php varbinary,php – 无法从MSSQL中获取varbinary数据
背景
開發(fā)環(huán)境:
在Windows 10 x64上使用Apache 2.4.16的PHP 7.0.3
SQL Server 2014標(biāo)準(zhǔn)版
服務(wù)器在相應(yīng)的文件列上啟用了FileStream.
試圖安裝sqlsvr驅(qū)動(dòng)程序但由于缺乏對PHP7的支持而失敗
使用驅(qū)動(dòng)程序SQL Server從ODBC訪問SQL Server
PHP代碼將圖像數(shù)據(jù)插入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保存圖像數(shù)據(jù)
$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服務(wù)器.打開SQL Server的DATA目錄,所有上傳的文件都可以通過Paint打開.
但是從上面的圖像保存代碼中獲取的文件已損壞.該文件缺少原始文件中的一些字節(jié).
嘗試了方法
fwrite( fopen("file","w+") , strtolower("0x".str_replace("\0","",$img)) );
以及此鏈接中說明的方法.
但兩者都沒有運(yùn)氣,文件似乎也被破壞了.
任何幫助表示贊賞.
編輯2016-02-25
修改SQL語句如下,但輸出文件仍然已損壞.
$link->prepare("SELECT DATALENGTH([File]) AS [Size] , [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");
我現(xiàn)在正在嘗試更改不同的SQL Server ODBC驅(qū)動(dòng)程序,以查看該文件是否可以成功輸出.
編輯2016-08-09
使用更新的PHP 7 MSSQL PDO驅(qū)動(dòng)程序.一切都有魅力.
現(xiàn)在,我們不需要使用這個(gè)新驅(qū)動(dòng)程序轉(zhuǎn)換varbinary數(shù)據(jù)了.
解決方法:
當(dāng)插入包含varbinary的表時(shí),選擇數(shù)據(jù)類型對PHP PDO非常重要.
對于文件列,應(yīng)使用PDO :: PARAM_LTR代替PDO :: PARAM_LTR
要確保DB通過驅(qū)動(dòng)程序輸出正確的文件,請將VARBINARY(MAX)字段轉(zhuǎn)換為十六進(jìn)制字符串,并通常使用此方法將其交給PHP CONVERT(VARCHAR(MAX),[FileColumn],2)
將列轉(zhuǎn)換為VARCHAR(MAX)而不是NVARCHAR(MAX),因?yàn)镠EX字符串不需要任何Unicode支持并保留一個(gè)普通的HEX字符串.
然后十六進(jìn)制字符串可以通過PHP函數(shù)hex2bin()有效地從十六進(jìn)制數(shù)據(jù)轉(zhuǎn)換回二進(jìn)制.
解決方案
$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驅(qū)動(dòng)程序11 for SQL Server中選擇varbinary列時(shí),既不將列轉(zhuǎn)換為varchar,也不會(huì)輸出損壞的二進(jìn)制結(jié)果,這是不需要的.但是當(dāng)我將列轉(zhuǎn)換為VARCHAR(MAX)時(shí),驅(qū)動(dòng)程序SQL Server成功向我返回一個(gè)HEX字符串.我懷疑這個(gè)動(dòng)作是一個(gè)錯(cuò)誤或驅(qū)動(dòng)程序問題.
標(biāo)簽:php,sql-server,pdo,php-7,sql-server-2014
來源: https://codeday.me/bug/20190516/1115975.html
總結(jié)
以上是生活随笔為你收集整理的php varbinary,php – 无法从MSSQL中获取varbinary数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java线程之基础学习
- 下一篇: php 遍历数组