douqiao3453 2016-10-18 21:14
浏览 52

结合PDO查询结果中的blob

I have a table which I'll call table_x holding file attachments as binary large objects in an Oracle database.

However, it does not have one row per file, it has one row per 28kb chunk of a file. Each blob is never more than 28kb.

Rows might look like:

attachsysfilename        file_seq      file_size      file_data
blah.xlsx                0             12000          <BLOB>
poo.xlsx                 0             28000          <BLOB>
poo.xlsx                 1             9000           <BLOB>

No row has a file size > 28000 bytes. Each attachsysfilename and file_seq combination is unique. When a file is above 28000 bytes, it is split across 2+ rows depending on how many 28kb chunks are needed to store the file.

If I directly export the blobs from the database, I need to concatenate blobs that are stored on 2+ rows before opening them. For example if I had a 2 part Excel file downloaded, I'd have to combine the parts, if using Windows, like type part1.xlsx part2.xlsx > combined.xlsx on the command line. The combined file would open properly, but opening either part individually would return an error.

I am writing some pages in PHP that access this data using PDO and would like to use PHP to similarly concatenate 2+ blobs when they represent the same file.

I have no problem writing a page to download files that are stored on only one row (28kb or less in size). I have that working as follows:

$att = $cono -> prepare (" SELECT attachsysfilename,
                                  file_size,
                                  file_data
                           from   table_x
                           where  attachsysfilename = :file_id
                          ");

$att -> bindParam(':file_id', $file_id, PDO::PARAM_STR);
$att -> execute();
$att -> bindColumn(1, $attachsysfilename, PDO::PARAM_STR, 256);
$att -> bindColumn(2, $file_size, PDO::PARAM_STR, 256);
$att -> bindColumn(3, $file_data, PDO::PARAM_LOB);
$att_row = $att -> fetch( PDO::FETCH_BOUND );

header("Content-type: application/vnd.openxmlfo");
header("Content-Disposition: inline; filename = $attachsysfilename");
fpassthru($file_data);

The above works fine whenever the file is limited to 1 row of the table.

This is my best attempt at handling those files on 2+ rows:

$att = $cono -> prepare (" SELECT attachsysfilename,
                                  file_size,
                                  file_data
                           from   table_x
                           where  attachsysfilename = :file_id
                          ");

$att -> bindParam(':file_id', $file_id, PDO::PARAM_STR);
$att -> execute();
$att -> bindColumn(1, $attachsysfilename, PDO::PARAM_STR, 256);
$att -> bindColumn(2, $file_size, PDO::PARAM_STR, 256);
$att -> bindColumn(3, $file_data, PDO::PARAM_LOB);

$combined_blob = '';

while (  $att_row = $att -> fetch( PDO::FETCH_BOUND ) )
{ 
  $combined_blob = $combined_blob . $file_data;

}

header("Content-type: application/vnd.openxmlfo");
header("Content-Disposition: inline; filename = $attachsysfilename");
fpassthru($combined_blob);
?>

Which returns this error (in the downloaded files):

<b>Warning</b>:  fpassthru() expects parameter 1 to be resource, string given in ....

The goal is to combine the 2+ blobs in php so that the combined blob can be downloaded as a file, not any one part.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 BC260Y用MQTT向阿里云发布主题消息一直错误
    • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
    • ¥15 划分vlan后,链路不通了?
    • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
    • ¥15 Vue3 大型图片数据拖动排序
    • ¥15 Centos / PETGEM
    • ¥15 划分vlan后不通了
    • ¥20 用雷电模拟器安装百达屋apk一直闪退
    • ¥15 算能科技20240506咨询(拒绝大模型回答)
    • ¥15 自适应 AR 模型 参数估计Matlab程序