sql >> Base de Datos >  >> RDS >> Sqlserver

PHP, ORM, MSSQL y Unicode, ¿es posible hacer que funcionen juntos?

Actualización: El controlador ya no está en vista previa. MS ha proporcionado instrucciones oficiales para la versión ahora lanzada:https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu

Las instrucciones a continuación están desactualizadas ya que MS ha extraído la descarga del controlador de vista previa.

Bueno, existe el controlador ODBC proporcionado por Microsoft. Eso debería proporcionar un comportamiento adecuado en este sentido. Vea el final de la publicación para ver cómo probé su comportamiento (de manera preliminar). Se probó con Azure SQL Database V12.

Cómo instalar el controlador ODBC de Microsoft SQL en Ubuntu 16.04

Esto se probó en la nueva instancia de Ubuntu 16.04 Azure que se basó en la imagen de Ubuntu 16.04 Azure proporcionada por Canonical. Después de iniciar sesión, cambié al usuario raíz usando sudo -i , entonces:

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

Pruébalo

Reemplace el servidor y las credenciales en el siguiente comando con las suyas propias.

sqlcmd -S somedatabase.database.windows.net -U someuser -P somepassword

Debería poder emitir comandos SQL en este punto. Bien, hagamos que funcione con php.

Úselo con php

Debemos asegurarnos de que el paquete libodbc1 no esté instalado y que no se instale, ya que php lo usaría en lugar de nuestro compilado personalizado, y eso generaría problemas de codificación.

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

En este punto, debería tenerlo disponible como controlador ODBC.

Probando su comportamiento

Cree un archivo php, test.php con codificación UTF-8 y con el siguiente contenido. Reemplace el servidor, la base de datos y las credenciales en la cadena de conexión con las suyas propias.

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

Ejecutando esto con php -f test.php muestra que recuperamos la cadena sin corrupción. Además, la cadena también se ve bien desde SQL Server Management Studio. Observé la siguiente consulta en la página Performance Insight de Azure Portal:(@P1 nvarchar(max))INSERT INTO test VALUES(@P1) , por lo que obviamente se usaron declaraciones preparadas, por lo que asumo que podría manejar su escenario (y el mío).

(Esta publicación fue de gran ayuda al intentar que esto funcionara:http://www.codelysis.com/~boris/blog/2011/12/02/microsoft-sql-server-odbc-driver-linux/ Gracias boris !)