【发布时间】:2013-07-30 17:15:48
【问题描述】:
我用 PHP (StreamWrapper) 编写了一个简单的 VFS(虚拟文件系统),将其数据放入 MySQL 数据库。存储数据的字段是一个中等大小的 blob。
你可以在 PHP 中做的事情:
copy( 'mytext.txt', 'dbfs://mytext.txt' );
copy( 'mytext.pdf', 'dbfs://mytext.pdf' ); or visa versa/etc.
问题在于通过 SQL 语句传递的二进制数据,例如 pdf。转义、取消引用、base64 等会破坏数据或占用过多内存(开销),例如 base64 占用 3 倍空间。
我认为最好的办法是把它变成一个十六进制字符串(只有两倍的空间),它将作为二进制存储在数据库中(没有开销)。我已经看到了 MySQL 的 HEX 命令,但无法让它像我想要的那样工作。
例如,下一条语句不会将其作为二进制数据存储到 blob 中:
UPDATE dbfs SET data=0xFF883838<very long string>FFA9999...... WHERE (fid=<number>)
我做的功能:
private function writeFile( $fid, &$uData = null, $iFileSize = null )
{
$sSql = 'UPDATE '.self::$dbTableNameFat.
' SET data="'.(($uData !== null)?('0x'.bin2hex($uData)):null).'"'.
',size="'.((int)$iFileSize).'" WHERE ( fid="'.$fid.'" );';
return $this->writeQuery( $sSql );
}
blob 包含数据,但以十六进制格式而不是二进制格式。我怎样才能实现我想要的行为?
【问题讨论】:
-
使用带有占位符的准备好的查询,二进制数据将通过而不需要任何编码l
-
我理解但由于 PHP 包装器的工作方式是不可能的,它是一个流处理程序。流包装器不知道外面发生了什么。
-
我不熟悉 PHP 流处理程序,但我不明白为什么这会阻止使用 mysqli 或 PDO 准备好的查询。
-
例如:我要复制的源文件名在包装器内部是未知的。包装器只处理要写入的流(目标)。
-
如果您有足够的信息将
$sSql创建为字符串,您应该能够使用占位符执行相同的查询。