使用PHP将BLOB插入MySQL的更好方法

7

我正在处理一个需要将文件插入到数据库的系统。

有两种方式可以将 blob 插入到数据库中,我想知道哪一种更好。

第一种方法是获取内容,然后在插入时将内容作为字符串绑定参数:

 $fp      = fopen($tmpName, 'r');
 $content = fread($fp, filesize($tmpName));
 $content = addslashes($content);
 fclose($fp);
 ...
 $prep_stmt = "INSERT INTO dokumenty (name, size, type, content, autor, poznamka) VALUES (?, ?, ?, ?, ?, ?)";
        $stmt = $mysqli->prepare($prep_stmt);
              $stmt->bind_param('sissis',$fileName,$fileSize,$fileType,$content,$user_id,$poznamka );

另一种方法是像这样使用send_long_data:
 $content = NULL;
 ...
 $prep_stmt = "INSERT INTO dokumenty (name, size, type, content, autor, poznamka) VALUES (?, ?, ?, ?, ?, ?)";
        $stmt = $mysqli->prepare($prep_stmt);
             $stmt->bind_param('sisbis',$fileName,$fileSize,$fileType,$content,$user_id,$poznamka );
        $stmt->send_long_data(3, file_get_contents($tmpName));

我的问题是:两种方式都可以使用,哪种更好?

1
两者都可以吗?在将内容绑定到查询之前应用addslashes意味着在许多情况下数据将被损坏。 - symcbean
我尝试下载纯文本文件,这个方法行得通,但你可能是对的,二进制文件会被破坏...下面的解决方案非常好用。 - Mi Ro
1个回答

2
使用send_long_data方法可以解决一个文件比您特定的MySQL服务器设置中的max_allowed_packet值大的情况。但是,您的两个代码可以正常工作表明您在测试中没有达到此限制。send_long_data方法被设计为在循环中多次调用,以部分“块”方式发送数据,因为这些数据太大而无法一次性发送。此外,我不喜欢您编写的第二种方式,因为您无法处理文件读取期间的错误。我建议采用第三种编码方式:
define ('YOUR_MYSQL_MAX_ALLOWED_PACKET', 8192);
$fp = fopen($tmpName, "r");
// TODO check here if fopen succeed
$prep_stmt = "INSERT INTO dokumenty (name, size, type, content, autor, poznamka) VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $mysqli->prepare($prep_stmt);

while (!feof($fp)) {
    $stmt->send_long_data(3, fread($fp, YOUR_MYSQL_MAX_ALLOWED_PACKET));
}
fclose($fp);

在MySQL中,YOUR_MYSQL_MAX_ALLOWED_PACKET常量值必须根据您的MySQL特定设置进行调整。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接