windows 7,php 5.3,当使用 sqlsrv 从 mssql 获取二进制数据时,数据加倍

发布于 2024-12-17 19:21:25 字数 3488 浏览 1 评论 0原文

好的,所以我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟花易冷人易散 2024-12-24 19:21:25

很高兴听到您找到了一些解决方案,即使不是一个好的解决方案:/

我在 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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文