Download do arquivo BLOB com o Oracle e Php
Pergunta
Usando o PHP, estou tentando baixar um arquivo BLOB que já foi enviado para um banco de dados Oracle 10G. Eu já vi e imitei vários exemplos que encontrei. Quando eu acessar a página, uma caixa de diálogo de download de arquivo é permitindo que eu abra ou salve. Se eu clicar em abrir, o media player aparecerá como deveria, mas nunca recuperar o arquivo. Se eu escolher Salvar, sempre recebo uma mensagem de erro informando: "O Internet Explorer não conseguiu abrir este site da Internet. O site solicitado não está disponível ou não pode ser encontrado. Tente novamente mais tarde."
Abaixo está o meu código, que é bastante direto e praticamente como os exemplos que encontrei.
<?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;
?>
Solução
Adicione mais tratamento de erros ao seu script. Qualquer função OCI* pode falhar e, em seguida, as etapas subsequentes também falharão. o documentação diz o que acontece se uma função falhar e qual será o valor de retorno. Por exemplo
Valores de retorno
Retorna um identificador de conexão ou falso em erro.
Se você definir o cabeçalho do tipo conteúdo o mais tarde possível, ou seja, diretamente antes da primeira saída, poderá enviar texto simples ou HTML que contém algum tipo de mensagem de erro.
<?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;
Outras dicas
Use sua consulta de banco de dados e Excecute primeiro aqui é que o campo de dados são dados do 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();