Фон
Среда разработки:
PHP 7.0.3 с Apache 2.4.16 на Windows 10 x64
SQL Server 2014 Standard
На сервере включен FileStream для соответствующих файловых столбцов.
Пытался установить sqlsvr
драйвер, но не удалось из-за отсутствия поддержки PHP7
Доступ к SQL-серверу из 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. Открытие DATA
каталог SQL Server, все загруженные файлы и могут быть открыты с помощью Paint.
Но выборка файла из вышеуказанного кода сохранения изображения повреждена. В файле отсутствуют некоторые байты из оригинала.
Метод попробовал
fwrite( fopen("file","w+") , strtolower("0x".str_replace("\0","",$img)) );
а также метод, указанный в этой ссылке.
Php с MSSQL отображать необработанные данные из поля varbinary
Но обоим не повезло, файл тоже казался поврежденным.
Любая помощь приветствуется.
Редактировать 2016-02-25
Изменил оператор SQL следующим образом, но выходной файл все еще поврежден.
$link->prepare("SELECT DATALENGTH([File]) AS [Size] , [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");
Сейчас я пытаюсь изменить другой драйвер ODBC для SQL-сервера, чтобы посмотреть, может ли файл успешно выводиться.
Редактировать 2016-08-09
С обновленным MSSQL PDO Driver для PHP 7. Все снова заработало с очарованием.
Теперь нам не нужно convert
varbinary данные больше, используя этот новый драйвер.
При вставке в таблицы, содержащие varbinary, выбор типа данных очень важен для PHP PDO.
PDO::PARAM_LOB
должен использоваться вместо использования PDO::PARAM_STR
для файловых столбцов
Чтобы убедиться, что БД выдает правильный файл через драйвер, преобразуйте 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"]) );
Дополнительная информация
При выборе столбца varbinary из SQL Server Native Client 11.0
а также ODBC Driver 11 for SQL Server
не преобразовывая столбец в varchar
или нет, PHP выводит поврежденный двоичный результат, который является нежелательным. Но водитель SQL Server
успешно вернуть мне строку HEX при преобразовании столбца в VARCHAR(MAX)
, Я подозреваю, что это действие — ошибка или проблема с драйвером.
Если вы храните двоичные данные, не конвертируйте их в NVARCHAR () при выборе — попробуйте удалить CONVERT () из этого:
$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 = $link->prepare("SELECT DATALENGTH([File]) AS [Size], [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");
Вы также хотите убедиться, что ваш столбец VARBINARY(MAX)
,
При вставке данных я думаю, что вам нужно использовать SQLSRV_ENCODING_BINARY
(вместо PDO::PARAM_STR
)
Установите драйвер ODBC в соответствии с версией ОС и версией SQL Server.
например, 64-разрядная версия Win 10 и SQL Server 12 требуется драйвер odbc 11
Скачать по этой ссылке
pdo_sqlsrv_.dll
загрузка файлов в соответствии с версией php, вставка в каталог php / ext и открытие из раздела расширений php.ini. например,
в моем случае установите версию xampp 3.2.2, включающую php 7.08, для
это я скачать pdo_sqlsrv_7_ts.dll и установить в соответствии с вышеизложенным
упомянуть в пункте 3.
Скачать по этой ссылке:
Установите параметр подключения к базе данных в PHP-файле, как
$ conn = новый PDO («sqlsrv: server = 127.0.0.1,1433; база данных = test», «», «»);
$ Conn-> SetAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);