使用Oracle和PHP下载BLOB文件
使用PHP,我试图下载一个已经上传到Oracle 10g数据库的blob文件。我看到并模仿了许多我发现的例子。当我访问页面时,会出现一个文件下载对话框,允许我打开或保存。如果我单击“打开”,media player会按应有的方式显示,但不会检索文件。如果选择“保存”,我总是会收到一条错误消息,说明“Internet Explorer无法打开此Internet站点。请求的站点不可用或找不到。请稍后再试。” 下面是我的代码,非常简单,非常像我找到的示例使用Oracle和PHP下载BLOB文件,php,oracle,oracle10g,blobs,Php,Oracle,Oracle10g,Blobs,使用PHP,我试图下载一个已经上传到Oracle 10g数据库的blob文件。我看到并模仿了许多我发现的例子。当我访问页面时,会出现一个文件下载对话框,允许我打开或保存。如果我单击“打开”,media player会按应有的方式显示,但不会检索文件。如果选择“保存”,我总是会收到一条错误消息,说明“Internet Explorer无法打开此Internet站点。请求的站点不可用或找不到。请稍后再试。” 下面是我的代码,非常简单,非常像我找到的示例 <?php header('Conte
<?php
header('Content-Disposition: attachment; filename='.$_GET['fileName']);
header('Content-length: '.$_GET['fileSize']);
header('Content-type: '.$_GET['mimeType']);
require_once("Include/Application.php");
$connection = oci_connect ($userID, $password, $TNS);
$phpCur = oci_new_cursor($connection);
$stmt = oci_parse($connection, "BEGIN MOR.DOWNLOAD_ATTACHMENT (:morID, :attachmentType, :phpCur); END;");
oci_bind_by_name($stmt, ":morID", $_GET['morID'], -1);
oci_bind_by_name($stmt, ":attachmentType", $_GET['attachmentType'], -1);
oci_bind_by_name($stmt, "phpCur", $phpCur, -1, OCI_B_CURSOR);
oci_execute($stmt);
oci_free_statement($stmt);
$output = '';
oci_execute($phpCur);
while( $row = oci_fetch_array($phpCur) )
$output .= $row['ATTACHMENT_BL'];
oci_free_statement($phpCur);
oci_close($connection);
echo $output;
exit;
?>
在脚本中添加更多错误处理。任何oci*功能都可能失败,随后的步骤也将失败。告诉您如果函数失败会发生什么,以及返回值将是什么。例如 返回值
错误时返回连接标识符或FALSE。 如果将内容类型标题设置得尽可能晚,即在第一次输出之前,则可以发送包含某种错误消息的纯文本或html
<?php
// error_reporting/ini_set: for testing purposes only.
error_reporting(E_ALL); ini_set('display_errors', 1);
require_once("Include/Application.php");
$connection = oci_connect ($userID, $password, $TNS);
if ( !$connection) {
die('database connection failed');
}
$phpCur = oci_new_cursor($connection);
if ( !$phpCur) {
die('creating cursor failed');
}
$stmt = oci_parse($connection, "BEGIN MOR.DOWNLOAD_ATTACHMENT (:morID, :attachmentType, :phpCur); END;");
if ( !$stmt) {
die('creating statement failed');
}
// and so on and on. Test the return values of each oci* function.
oci_close($connection);
header('Content-Disposition: attachment; filename='.$_GET['fileName']); // at least at basename() here
header('Content-length: '.$_GET['fileSize']); // strange...
header('Content-type: '.$_GET['mimeType']); // possible but still strange...
echo $output;
exit;
首先使用数据库查询并执行以下操作:数据字段为blob数据:
$sql="SELECT FILE_NAME,data,length(data) as filesize FROM branch_data where id='$id'";
$r = $db->execute($sql);
$filename=$r->data[0]['FILE_NAME'];
$d=$r->data[0]['DATA'];
$filesize = $r->data[0]['FILESIZE'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' .$filesize);
echo $d->load();
header('Content-length:'.$\u GET['fileSize'])代码>-内容长度由GET参数决定,而不是blob数据的实际(字节)大小?听起来不对。上传文件时,附件的大小存储在单独的字段中。在调用此页面之前,我使用AJAX调用获取这些信息。我不知道这是否是标准做法,但据我所知,我需要提前知道文件大小,以便为header语句提供它。虽然,现在我看到在我的过程调用之后,我有了三个头语句,我可以在下载blob的同时获得这些信息。这当然让我更接近了一步。根据您的建议,我现在得到一个“OCI Lob类的对象无法转换为字符串…”错误。搜索该错误时,我应该使用$row=oci\u fetch\u数组($phpCur,oci\u ASSOC+oci\u RETURN\u LOBS);而不是$row=oci\u fetch\u数组($phpCur);有了这个参数,我现在实际上下载了文件的字符表示,而不是打开或保存文件的提示。现在我如何越过这一点呢?只要尚未向客户端发送任何输出,就可以在“任何地方”执行header()。您确定在标题('Content-type…')之前没有输出吗?使用脚本示例中的error_reporting()/ini_set()行,如果在header()之前有输出,您将得到“警告:headers已经发送”