Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

PHP, ORM, MSSQL e Unicode, é possível fazê-los funcionar juntos?


Atualização: O driver não está mais em visualização. A MS forneceu instruções oficiais para a versão agora lançada:https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu

As instruções abaixo estão desatualizadas como a MS puxou o download do driver de visualização.

Bem, existe o driver ODBC fornecido pela Microsoft. Isso deve fornecer um comportamento adequado a esse respeito. Veja no final da postagem como testei seu comportamento (de maneira preliminar). Ele foi testado em um Banco de Dados SQL do Azure V12.

Como instalar o driver ODBC do Microsoft SQL no Ubuntu 16.04

Isso foi testado na nova instância do Ubuntu 16.04 Azure que foi baseada na imagem do Ubuntu 16.04 Azure fornecida pela Canonical. Após o login, mudei para o usuário root usando sudo -i , então:
apt-get update
apt-get -y install atool make build-essential libc6 libkrb5-3 libgss3 e2fsprogs openssl equivs
wget https://download.microsoft.com/download/2/E/5/2E58F097-805C-4AB8-9FC6-71288AB4409D/msodbcsql-13.0.0.0.tar.gz
atool -x msodbcsql-13.0.0.0.tar.gz
rm msodbcsql-13.0.0.0.tar.gz

pushd msodbcsql-13.0.0.0/
./build_dm.sh --accept-warning | tee build_dm_result.txt
command=$(cat build_dm_result.txt | grep "Run the command" | cut -d"'" -f2)
rm build_dm_result.txt
sh -c "$command"
popd

echo "/usr/lib64" > /etc/ld.so.conf.d/microsoft-lib64.conf
ldconfig

pushd msodbcsql-13.0.0.0/
./install.sh  install --accept-license

Teste

Substitua o servidor e as credenciais no comando a seguir pelos seus próprios.
sqlcmd -S somedatabase.database.windows.net -U someuser -P somepassword

Você deve ser capaz de emitir comandos SQL neste momento. Ok, vamos trabalhar com php.

Use-o com php

Devemos ter certeza de que o pacote libodbc1 não está instalado e que não será instalado, pois isso seria usado pelo php em vez do nosso personalizado, e isso levaria a problemas de codificação.
cat > libodbc1<<EOL
Section: misc
Priority: optional
Standards-Version: 3.9.2

Package: libodbc1
Version: 9999
Description: fake pkg, so that we satisfy the dependency of php7-odbc, so that we can keep our custom built libodbc
EOL

equivs-build libodbc1
dpkg -i libodbc1_9999_all.deb
rm libodbc1
rm libodbc1_9999_all.deb

apt-get install php7.0-odbc php7.0-cli

Neste ponto, você deve tê-lo disponível como um driver ODBC.

Testar seu comportamento

Crie um arquivo php, test.php com codificação UTF-8 e com o seguinte conteúdo. Substitua o servidor, o banco de dados e as credenciais na string de conexão pelos seus próprios.
<?php

$pdo = new PDO('odbc:Driver={ODBC Driver 13 for SQL Server};Server=tcp:somedatabase.database.windows.net,1433;Database=somedatabase;[email protected];Pwd=somepassword;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;');

$str = 'Árvíztűrő tükörfúrógép, and... 你好,世界';

$pdo->prepare("DROP TABLE test")->execute();
$pdo->prepare("CREATE TABLE test(a NVARCHAR(MAX))")->execute();
$stmt = $pdo->prepare("INSERT INTO test VALUES(?)");
$stmt->bindParam(1, $str);
$stmt->execute();

$stmt = $pdo->prepare("SELECT * FROM test");
$stmt->execute();
$data = $stmt->fetchall();
var_dump($data[0][0]==$str); //Returns true

$stmt = $pdo->prepare("SELECT * FROM test WHERE a=?");
$stmt->bindParam(1, $str);
$stmt->execute();
$data = $stmt->fetchall();
var_dump($data[0][0]==$str); //Returns true

Executando isso com php -f test.php mostra que recuperamos a string sem nenhuma corrupção. Além disso, a string também parece boa no SQL Server Management Studio. Observei a seguinte consulta na página Performance Insight do Portal do Azure:(@P1 nvarchar(max))INSERT INTO test VALUES(@P1) , então as instruções preparadas foram obviamente usadas, então eu suponho que ele poderia lidar com seu (e meu) cenário.

(Esta postagem foi de grande ajuda ao tentar fazer isso funcionar:http://www.codesynthesis.com/~boris/blog/2011/12/02/microsoft-sql-server-odbc-driver-linux/ Obrigado boris !)