[RESOLU] PHP7 : interroger un SQL server depuis un serveur Linux Debian

Eléphanteau du PHP | 12 Messages

22 nov. 2016, 13:09

Bonjour à tous,

J'ai mon serveur Apache/PHP sur une Debian Linux.

Un certain nombre de mes programmes travaillent avec une BDD SQL Server, présent donc sur un serveur distant Windows Server.

Jusque là, je passais par les fonctions mssql_*. Mais en PHP7, ces fonctions disparaitront.
Je cherche donc une solution de remplacement.

Jusque là, j'ai trouvé deux options, et je cherche la plus fiable sur le long terme :
- PDO avec dblib
- Les fonctions odbc_*

Au feeling, je dirais que l'utilisation de PDO est plus "propre". Mais j'ai un doute concernant l'utilisation de dblib. Je ne connais pas du tout et trouve peu d'information sur le net.
D'autant que la doc indique "Cette extension (PDO_DBLIB) n'est plus disponible sous Windows avec PHP 5.3 et suivant". Qu'en sera-t-il sous Linux ?

Qu'en pensez vous ?
Y a-t-il d'autres alternatives encore meilleures ?

Merci de vos retours !

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8755 Messages

22 nov. 2016, 14:09

salut,

pour moi PDO y a pas de doute. (et si tu souhaites migrer vers un autres sgbd tu n'auras qu'a retoucher les requêtes propriétaire et pas refaire toutes les mécaniques d'utilisation de la base de données parce que tu changes. Oui je sais c'est pas tous les jours mais pour le cas ou ;) )

sinon y a la solution fournit par µsoft : http://fr.php.net/manual/fr/intro.sqlsrv.php, ha ba non dommage c'est windows only :-)

du coup la doc t'indiques qu'il faut utiliser le driver ODBC pour linux : http://fr.php.net/manual/fr/ref.pdo-sqlsrv.php avec le lien vers https://www.microsoft.com/en-us/downloa ... x?id=28160

D'après la doc c'est soit le driver ODBC soit un Windows serveur au choix ;)

après c'est que sous Windows le PB et il n'y a pas d'info pour linux donc cela semple une bonne idée de l'utiliser.

Quoi qu'il en soit utilise PDO ensuite c'est qu'une histoire de driver à changer dans la chaîne de connexion (et la conf serveur) c'est surement le plus serein.

@+
Il en faut peu pour être heureux ......

Avatar de l’utilisateur
Administrateur PHPfrance
Administrateur PHPfrance | 7268 Messages

22 nov. 2016, 16:25

+1 pour PDO, c'est à mon sens le plus "future-proof" :)
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 12 Messages

22 nov. 2016, 16:28

Salut moogli,

Merci de te pencher sur mon problème.

Je crois bien qu'il y a une troisième solution : faire une connexion ODBC avec PDO.
http://php.net/manual/fr/ref.pdo-odbc.php

Mais alors là, je suis un peu noyé, car je ne comprends pas cette histoire de configuration de fichiers odbc/odbcinst.ini.

Dans /etc/odbcinst.ini, j'ai

Code : Tout sélectionner

[FreeTDS] Description = TDS driver (Sybase/MS SQL) Driver = libtdsodbc.so Setup = libtdsS.so CPTimeout = CPReuse =
Et dans /etc/odbc.ini

Code : Tout sélectionner

[MABASE] Driver = FreeTDS Description = ODBC connection via FreeTDS Trace = Yes TraceFile = /tmp/odbc.ini.log Server = IP.DE.MON.SERVEUR Port = 1433 Database = myDatabase
En ligne de commande, ça marche : isql -v MABASE user password me retourne bien :

Code : Tout sélectionner

+---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
Quand je fais :
$dbh = new PDO("odbc:Driver={MABASE};Server=IP.DE.MON.SERVEUR;Database=myDatabase;Uid=user;Pwd=password;");
--> J'ai une erreur "can't open lib 'MABASE' : file not found".

$dbh = new PDO("odbc:MABASE", "user, "password");
--> Erreur de segmentation

$dbh = new PDO("odbc:MABASE");
--> Data source name not found, and no default driver specified

$dbh = new PDO("odbc:Driver=FreeTDS;Server=IP.DE.MON.SERVEUR;Port=1433;Database=myDatabase;Uid=user;Pwd=password;");
--> Can't open cursor lib "/etc/libodbccr.so"
--> Pourtant, j'utilise aussi ce DSN pour faire un odbc_connect, et il fonctionne.

Donc, je ne dois pas comprendre la syntaxe de la connexion ODBC dans PDO... Si quelqu'un pouvait m'éclaircir (!)

Eléphanteau du PHP | 12 Messages

22 nov. 2016, 17:18

+1 pour PDO, c'est à mon sens le plus "future-proof" :)
Ha oui, effectivement, PDO ce sera :)

Finalement, ma question devient : par quel moyen se connecter au SQL server ?

Là, j'y arrive avec DBLIB, mais que pensez vous de cette bibliothèque ?

Avec un ODBC, je n'y arrive pas par PDO, bien que ma configuration fonctionne avec des lignes de commandes.

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8755 Messages

23 nov. 2016, 10:28

si tu regarde complètement ma première réponse tu y trouveras
D'après la doc c'est soit le driver ODBC soit un Windows serveur au choix
après c'est suivant tes besoins et possibilité d'installation sur le serveur.
J'aurais tendance à dire qu'il faut utiliser le driver par défaut tant que tu peux afin de faciliter la maintenance de celui (correction de bug et autre fait par les mainteneur du paquet, installation simplifiée, par compilation dont tu te souvient jamais des options et autre choses du genre).
Après si tu préfère partir sur une installation custom du driver ODBC pas de problème, pense quand même que c'est à toi de le maintenir, de le faire évoluer et de t'assurer de la compatibilité de celui ci avec la version de php courante.

si tu n'as aucun des deux fournit avec ton gestionnaire de paquet utilise celui qui a le plus de ressources pour t'aider en cas de problème tu gagneras surement du temps.

Sachant que le cœur du problème c'est d'utiliser PDO dans le code php, changer le driver c'est simple et peux être fait pas un sysadmin ensuite.

pour le problème avec le driver odbc, est ce que l'extension est bien présente dans un phpinfo ?

d'après la doc odbc:MABASE devrait suffire ce qui me fait poser la question précédente ;)

il y a bien le premier commentaire de la doc que tu semble avoir testé (as testé dans odbc: ? )
$dsn = 'DRIVER=FreeTDS;SERVERNAME=server1;DATABASE=testdb;APP=My PHP Application;UID=user;';

il y a des exemples de chaînes de connexion la https://www.connectionstrings.com/sql-server/
ce post indique la solution suivante :
$cn = new PDO("odbc:Driver={SQL Native Client};Server=127.0.0.1\SQLEXPRESS;Database=bd_2009; Uid=ut;Pwd=mdp;");


et celui ci une solution qui pourrais coller à ton cas : http://stackoverflow.com/questions/2016 ... a-pdo-odbc


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 12 Messages

23 nov. 2016, 16:38

pour le problème avec le driver odbc, est ce que l'extension est bien présente dans un phpinfo ?
Il me semble que oui, puisque les fonctions odbc_* fonctionnent, ou cela n'a rien à voir ?
$dsn = 'DRIVER=FreeTDS;SERVERNAME=server1;DATABASE=testdb;APP=My PHP Application;UID=user;';
Je n'ai pas testé stricto cette syntaxe, mais mon dernier exemple était basé là dessus. Echec...
$cn = new PDO("odbc:Driver={SQL Native Client};Server=127.0.0.1\SQLEXPRESS;Database=bd_2009; Uid=ut;Pwd=mdp;");
Alors là, je vais me montrer enquiquinant, mais je ne veux pas installer les pilotes Microsoft sur mon Linux, sauf si je n'ai vraiment pas le choix :P
Pour l'instant, je n'en suis pas là. Je suis convaincu de ne pas faire ce qu'il faut pour utiliser ODBC dans PDO.
et celui ci une solution qui pourrais coller à ton cas : http://stackoverflow.com/questions/2016 ... a-pdo-odbc
Je vais regarder ce post en détail. Pour l'heure, je réinstalle une machine propre pour tous ces tests. je vous tiens au courant :)

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8755 Messages

24 nov. 2016, 12:56

Alors là, je vais me montrer enquiquinant, mais je ne veux pas installer les pilotes Microsoft sur mon Linux, sauf si je n'ai vraiment pas le choix :P
Pour l'instant, je n'en suis pas là. Je suis convaincu de ne pas faire ce qu'il faut pour utiliser ODBC dans PDO.
en même temps si tu attaques une base MS c'est mieux avec les drivers qui vont bien ;)

pour odbc_* c'est pas la même chose que PDO, dans la distrib windows de php tu as extension=php_pdo_odbc.dll, sur debian il y a un paquet php_odbc...

j'essairai de regarder ce soir ave une debian sous la main

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 12 Messages

24 nov. 2016, 13:38

Hello,

Bon, j'ai finalement réussi à faire fonctionner pdo_odbc. J'ai insisté car une des forces de PDO et de pouvoir changer sans grosse incidence de drivers. Avec dblib, ça marchait presque tout seul. Mais je me devais de trouver une alternative, au cas où dblib ne serait plus maintenu.
Avec odbc, c'était plus compliqué. Je vais tenter de résumer aussi clairement que possible les manip' que j'ai faites, si ça peut être utile à d'autres :

1) Sur le serveur Linux Debian, en plus des paquets usuels pour un serveur Apache/PHP installer php-odbc (qui activera pdo_odbc), unixodbc, tdsodbc (qui fournira freetds)

2) Je me suis ensuite basé sur les instructions dans la doc php http://php.net/manual/fr/ref.pdo-odbc.php. Voir le #0, mais attention, ne pas le suivre à 100%
a) Créer un fichier tds.driver dans votre dossier perso et y mettre les infos suivantes :

Code : Tout sélectionner

[FreeTDS] Description = v0.63 with protocol v8.0 Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Attention à vérifier le dossier où se trouve libtdsodbc.so. Cela varie selon votre distri et/ou architecture.

Enregistrer :

Code : Tout sélectionner

odbcinst -i -d -f tds.driver
Vous pouvez contrôler que la manip' a fonctionné en visualisant le contenu de /etc/odbcinst.ini est similaire à votre tds.driver

b) Ce que l'auteur du post#0 dans la doc citée fait ici me semble optionnel. Je vous le mets quand même.
Créer un fichier tds.datasource dans votre dossier perso :

Code : Tout sélectionner

[SOURCENAME] Driver=FreeTDS Description=Test MS SQL Database with FreeTDS Trace=No Server=IP.DE.MON.SERVEUR Port=1433 TDS Version=8.0 Database=myDatabase
Enregistrer :

Code : Tout sélectionner

odbcinst -i -s -f tds.datasource
A cette étape, vous aurez normalement un fichier .odbc.ini dans votre dossier perso. L'auteur explique qu'il faut copier ce fichier à la racine de votre site web. Pour ma part, avec ou sans ce fichier, cela n'a rien changé.

3) Tester que votre lien ODBC fonctionne :

Code : Tout sélectionner

isql -v SOURCENAME 'user' 'password' +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
4) A cette étape, si vous faites
$dbh = new PDO("odbc:Driver=FreeTDS;Server=IP.DE.MON.SERVEUR;Port=1433;Database=myDatabase;Uid=user;Pwd=password;");
vous aurez l'erreur Can't open cursor lib "/etc/libodbccr.so" comme je l'ai indiqué précédemment.

Le détournement se fait par un lien symbolique :

Code : Tout sélectionner

cd /usr/lib/x86_64-linux-gnu ln -s libodbccr.so.2 libodbccr.so
Mais là, je ne sais pas pourquoi pdo vas chercher son pilote au mauvais endroit. Je ne sais pas si c'est un bug, ou une erreur de configuration de ma part.

Mais voilà, grâce à tout ça, j'ai atteint mon but, qui était d'avoir deux solutions pour se connecter depuis une Linux Debian à un SQL server distant par PDO.

Champagne :P

Avatar de l’utilisateur
Administrateur PHPfrance
Administrateur PHPfrance | 7268 Messages

24 nov. 2016, 20:04

Un grand merci à toi pour se retour et partage de la solution :-D
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 12 Messages

25 nov. 2016, 11:35

Un grand merci à toi pour se retour et partage de la solution :-D
De rien, un forum, c'est fait pour ça :)

Précision : j'ai fait tout ça sur une Debian/Testing (Stretch) avec du PHP7.