Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

PHP, ORM, MSSQL e Unicode, è possibile farli funzionare insieme?

Aggiornamento: Il driver non è più in anteprima. MS ha fornito istruzioni ufficiali per la versione ora rilasciata:https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu

Le istruzioni seguenti non sono aggiornate poiché MS ha ritirato il download del driver di anteprima.

Bene, c'è il driver ODBC fornito da Microsoft. Ciò dovrebbe fornire un comportamento corretto al riguardo. Vedi la fine del post per vedere come ho testato il suo comportamento (in via preliminare). È stato testato su un database SQL di Azure V12.

Come installare il driver ODBC di Microsoft SQL su Ubuntu 16.04

Questo è stato testato sulla nuova istanza Azure di Ubuntu 16.04 basata sull'immagine Azure di Ubuntu 16.04 fornita da Canonical. Dopo aver effettuato l'accesso, sono passato all'utente root usando sudo -i , quindi:

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

Prova

Sostituisci il server e le credenziali nel comando seguente con il tuo.

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

Dovresti essere in grado di emettere comandi SQL a questo punto. Ok, facciamo in modo che funzioni con php.

Usalo con php

Dobbiamo assicurarci che il pacchetto libodbc1 non sia installato e che non venga installato, poiché verrebbe utilizzato da php invece di quello personalizzato conforme, e ciò porterebbe a problemi di codifica.

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

A questo punto dovresti averlo disponibile come driver ODBC.

Testarne il comportamento

Crea un file php, test.php con codifica UTF-8 e con il seguente contenuto. Sostituisci il server, il database e le credenziali nella stringa di connessione con le tue.

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

Eseguendo questo con php -f test.php mostra che recuperiamo la stringa senza alcun danneggiamento. Inoltre, la stringa sembra buona anche da SQL Server Management Studio. Ho osservato la seguente query nella pagina Performance Insight del portale di Azure:(@P1 nvarchar(max))INSERT INTO test VALUES(@P1) , quindi sono state ovviamente utilizzate istruzioni preparate, quindi presumo che potrebbe gestire il tuo (e il mio) scenario.

(Questo post è stato di grande aiuto mentre cercavo di farlo funzionare:http://www.codesynthesize.com/~boris/blog/2011/12/02/microsoft-sql-server-odbc-driver-linux/ Grazie boris !)