php varbinary,php – 无法从MSSQL中获取varbinary数据

背景

开发环境:

在Windows 10 x64上使用Apache 2.4.16的PHP 7.0.3

SQL Server 2014标准版

服务器在相应的文件列上启用了FileStream.

试图安装sqlsvr驱动程序但由于缺乏对PHP7的支持而失败

使用驱动程序SQL Server从ODBC访问SQL Server

PHP代码将图像数据插入MSSQL

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);

$stmt = $link->prepare("INSERT INTO [Attachment] (AttID, Seq , ModuleCde, AppID, StaffID , FileName , [File]) VALUES ( NEWID() , ? , ? , ? , ? , ? , ? )");

$stmt->bindValue(1,$_POST["Seq"],PDO::PARAM_INT);

$stmt->bindValue(2,$_POST["ModuleCde"],PDO::PARAM_STR);

$stmt->bindValue(3,$_POST["AppID"],PDO::PARAM_STR);

$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);

$stmt->bindValue(5,$_FILES["file"]["name"][$_POST["Seq"]],PDO::PARAM_STR);

$stmt->bindValue(6,file_get_contents($_FILES["file"]["tmp_name"][$_POST["Seq"]]),PDO::PARAM_STR);

$stmt->execute();

PHP代码从MSSQL保存图像数据

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);

$stmt = $link->prepare("SELECT DATALENGTH([File]) AS [Size] , CONVERT(NVARCHAR(MAX),[File],2) AS [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");

$stmt->bindValue(1,$_GET["ModuleCde"],PDO::PARAM_STR);

$stmt->bindValue(2,$_GET["AppID"],PDO::PARAM_STR);

$stmt->bindValue(3,$_GET["Seq"],PDO::PARAM_STR);

$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);

$stmt->execute();

$stmt->bindColumn(2,$img,PDO::PARAM_LOB, 0);

$stmt->fetch(PDO::FETCH_ASSOC);

file_put_contents( "file" , $img );

该文件已成功上载到SQL服务器.打开SQL Server的DATA目录,所有上传的文件都可以通过Paint打开.

但是从上面的图像保存代码中获取的文件已损坏.该文件缺少原始文件中的一些字节.

尝试了方法

fwrite( fopen("file","w+") , strtolower("0x".str_replace("\0","",$img)) );

以及此链接中说明的方法.

但两者都没有运气,文件似乎也被破坏了.

任何帮助表示赞赏.

编辑2016-02-25

修改SQL语句如下,但输出文件仍然已损坏.

$link->prepare("SELECT DATALENGTH([File]) AS [Size] , [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");

我现在正在尝试更改不同的SQL Server ODBC驱动程序,以查看该文件是否可以成功输出.

编辑2016-08-09

使用更新的PHP 7 MSSQL PDO驱动程序.一切都有魅力.

现在,我们不需要使用这个新驱动程序转换varbinary数据了.

解决方法:

当插入包含varbinary的表时,选择数据类型对PHP PDO非常重要.

对于文件列,应使用PDO :: PARAM_LTR代替PDO :: PARAM_LTR

要确保DB通过驱动程序输出正确的文件,请将VARBINARY(MAX)字段转换为十六进制字符串,并通常使用此方法将其交给PHP CONVERT(VARCHAR(MAX),[FileColumn],2)

将列转换为VARCHAR(MAX)而不是NVARCHAR(MAX),因为HEX字符串不需要任何Unicode支持并保留一个普通的HEX字符串.

然后十六进制字符串可以通过PHP函数hex2bin()有效地从十六进制数据转换回二进制.

解决方案

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);

$stmt = $link->prepare("SELECT DATALENGTH([File]) AS [Size] , CONVERT(VARCHAR(MAX),[File],2) AS [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");

$stmt->bindValue(1,$_GET["ModuleCde"],PDO::PARAM_STR);

$stmt->bindValue(2,$_GET["AppID"],PDO::PARAM_STR);

$stmt->bindValue(3,$_GET["Seq"],PDO::PARAM_STR);

$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);

$stmt->execute();

$result = $stmt->fetch(PDO::FETCH_ASSOC);

file_put_contents( "file" , hex2bin($result["File"]) );

附加信息

从SQL Server Native Client 11.0和ODBC驱动程序11 for SQL Server中选择varbinary列时,既不将列转换为varchar,也不会输出损坏的二进制结果,这是不需要的.但是当我将列转换为VARCHAR(MAX)时,驱动程序SQL Server成功向我返回一个HEX字符串.我怀疑这个动作是一个错误或驱动程序问题.

标签:php,sql-server,pdo,php-7,sql-server-2014

来源: https://codeday.me/bug/20190516/1115975.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值