windows 7,php 5.3,当使用 sqlsrv 从 mssql 获取二进制数据时,数据加倍
好的,所以我在 MSSQL 2005 (express) 服务器上有图像,我想将其写入文件。 使用同一段代码,在 Linux 上它工作正常,在 Windows 上它在文件中写入数据两次
file_put_contents($file, $val);
$val = basename($file);
我知道这不是 file_put_contents() 问题,因为我也尝试过 fwrite Windows 中的输出文件大小是 linux 中的两倍
-rw-rw-r-- 1 dimitris dimitris 891768 2011-11-22 16:13 eshop_products__2201.jpg
-rw-rw-r-- 1 dimitris dimitris 445884 2011-11-21 19:15 eshop_products__2201_linux.jpg
我正在使用 Linux 的 freetds 驱动程序和 Windows 中的 php_pdo_sqlsrv_53_nts_vc9
对于我可以做些什么来在 Windows 中获取正确的数据有什么想法吗?也许我错过了一些配置?
每个文件的最高字节:
windows 文件:
ASCII (php substr):
FFD8FFE000104A46494600010100000100010000FFDB0043000302020302020303030304030304050805050404050A070706080C0...etc...
hex:
00000000: 46 46 44 38 46 46 45 30 30 30 31 30 34 41 34 36 FFD8FFE000104A46
00000010: 34 39 34 36 30 30 30 31 30 31 30 30 30 30 30 31 4946000101000001
00000020: 30 30 30 31 30 30 30 30 46 46 44 42 30 30 34 33 00010000FFDB0043
00000030: 30 30 30 33 30 32 30 32 30 33 30 32 30 32 30 33 0003020203020203
00000040: 30 33 30 33 30 33 30 34 30 33 30 33 30 34 30 35 0303030403030405
00000050: 30 38 30 35 30 35 30 34 30 34 30 35 30 41 30 37 0805050404050A07
00000060: 30 37 30 36 30 38 30 43 30 41 30 43 30 43 30 42 0706080C0A0C0C0B
linux 文件:
ASCII (php substr):
����JFIF��C
hex:
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03 .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07 ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d ................
00000040: 0e 11 0e 0b 0b 10 16 10 11 13 14 15 15 15 0c 0f ................
00000050: 17 18 16 14 18 12 14 15 14 ff db 00 43 01 03 04 ............C...
00000060: 04 05 04 05 09 05 05 09 14 0d 0b 0d 14 14 14 14 ................
00000070: 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 ................
从数据库中提取文件的代码基于 yii 框架,使用 yii 的命令功能(php cli)
连接字符串:
linux
'connectionString' => 'dblib:host=192.168.56.101;port=1433;dbname=mssqldb',
windows
'connectionString' => 'sqlsrv:Server=192.168.56.101;Database=mssqldb',
代码:
$rows = $this->db->createCommand("SELECT * FROM $viewName WHERE 1=1")->queryAll();
/*
* Convert charset and extract photos from view
*/
foreach ($rows as $row) {
// convert charset / export photos
foreach ($row as $key => &$val) {
// charset conversion, on fields that do not contain photos
// $viewCfg is an array I maintain to know which field does what
if (empty($viewCfg['photos']) || !in_array($key, $viewCfg['photos'])) {
$val = @iconv("Windows-1253", "UTF-8", $val);
// grab image in file
} else {
$id = '';
foreach ($viewCfg['keys'] as $fieldName) {
$id .= '_' . $row[$fieldName];
}
$file = Yii::app()->params['pathPhotos'] . '/' . $viewName . '_' . $id . '.jpg';
if ($val) {
if (file_exists($file) && (file_get_contents($file)!=$val))
unlink($file);
file_put_contents($file, $val);
$val = basename($file);
}
}
}
// ... do the rest
ok, so I have images on a MSSQL 2005 (express) server which I want to write to files.
with the same piece of code, on linux it works fine, on windows it writes the data twice in the file
file_put_contents($file, $val);
$val = basename($file);
I know it is not a file_put_contents() problem because I also tried with fwrite
the output file in windows has double the size it has in linux
-rw-rw-r-- 1 dimitris dimitris 891768 2011-11-22 16:13 eshop_products__2201.jpg
-rw-rw-r-- 1 dimitris dimitris 445884 2011-11-21 19:15 eshop_products__2201_linux.jpg
I am using the freetds driver for linux and php_pdo_sqlsrv_53_nts_vc9 in windows
any ideas on something I could do to get the correct data in windows? maybe some configuration I missed?
topmost bytes of each file:
windows file:
ASCII (php substr):
FFD8FFE000104A46494600010100000100010000FFDB0043000302020302020303030304030304050805050404050A070706080C0...etc...
hex:
00000000: 46 46 44 38 46 46 45 30 30 30 31 30 34 41 34 36 FFD8FFE000104A46
00000010: 34 39 34 36 30 30 30 31 30 31 30 30 30 30 30 31 4946000101000001
00000020: 30 30 30 31 30 30 30 30 46 46 44 42 30 30 34 33 00010000FFDB0043
00000030: 30 30 30 33 30 32 30 32 30 33 30 32 30 32 30 33 0003020203020203
00000040: 30 33 30 33 30 33 30 34 30 33 30 33 30 34 30 35 0303030403030405
00000050: 30 38 30 35 30 35 30 34 30 34 30 35 30 41 30 37 0805050404050A07
00000060: 30 37 30 36 30 38 30 43 30 41 30 43 30 43 30 42 0706080C0A0C0C0B
linux file:
ASCII (php substr):
����JFIF��C
hex:
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03 .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07 ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d ................
00000040: 0e 11 0e 0b 0b 10 16 10 11 13 14 15 15 15 0c 0f ................
00000050: 17 18 16 14 18 12 14 15 14 ff db 00 43 01 03 04 ............C...
00000060: 04 05 04 05 09 05 05 09 14 0d 0b 0d 14 14 14 14 ................
00000070: 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 ................
The code extracting the file from the database is base on the yii framework, using yii's commands feature (php cli)
Connection strings:
linux
'connectionString' => 'dblib:host=192.168.56.101;port=1433;dbname=mssqldb',
windows
'connectionString' => 'sqlsrv:Server=192.168.56.101;Database=mssqldb',
Code:
$rows = $this->db->createCommand("SELECT * FROM $viewName WHERE 1=1")->queryAll();
/*
* Convert charset and extract photos from view
*/
foreach ($rows as $row) {
// convert charset / export photos
foreach ($row as $key => &$val) {
// charset conversion, on fields that do not contain photos
// $viewCfg is an array I maintain to know which field does what
if (empty($viewCfg['photos']) || !in_array($key, $viewCfg['photos'])) {
$val = @iconv("Windows-1253", "UTF-8", $val);
// grab image in file
} else {
$id = '';
foreach ($viewCfg['keys'] as $fieldName) {
$id .= '_' . $row[$fieldName];
}
$file = Yii::app()->params['pathPhotos'] . '/' . $viewName . '_' . $id . '.jpg';
if ($val) {
if (file_exists($file) && (file_get_contents($file)!=$val))
unlink($file);
file_put_contents($file, $val);
$val = basename($file);
}
}
}
// ... do the rest
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很高兴听到您找到了一些解决方案,即使不是一个好的解决方案:/
我在 PHP 应用程序上测试 Mssql 时遇到了这种情况,但从未得到任何进一步的解决方案。您可以查看的另一个提示是有关 PDO 大对象(如 varbinary 和 image SQL 数据类型)的 PHP 文档: https://www.php.net/manual/en/pdo.lobs.php
也许当您将图像作为流读取时结果是一致的?
Good to hear you found some solution, if not a nice one : /
I had that situation while testing Mssql on a PHP app but never got any further. Another hint you may check is the PHP doc on PDO Large Objects (like varbinary and image SQL Datatypes): https://www.php.net/manual/en/pdo.lobs.php
Maybe the result is consistent when you read the image as a stream?