Dev </>

Connexion entre Oracle 10g ou 11g et PHP avec les PDO

Sommaire

Il est possible en PHP de se connecter à une base Oracle avec les fonctions OCI8 ou avec l’objet PDO (souvent appelée « les PDO »).

Nous allons voir ici l’utilisation de l’objet PDO en PHP avec une base Oracle (10g ou 11g) sur Wampserver.

Oracle, PHP, OCI8 et PDO

PHP fournit 2 extensions afin de se connecter à une base Oracle :

  • Les fonctions OCI8 (Oracle Call Interface)
  • L’objet PDO (PHP Data Objects)

Les fonctions oci8 sont développées et supportées par Oracle qui offre un tutoriel d’utilisation complet.

La classe PDO est développée par la communauté PHP. Cette classe a été créée dans un but de normalisation, elle offre une interface objet de connexion à une ou plusieurs bases de données.

Compatible avec de nombreux SGBD et SGBDR (MySQL, PostgreSQl, SQLite et bien d’autres…) l’objet PDO fonctionne avec des pilotes. Pour se connecter à un SGBD / SGBDR, il est nécessaire d’installer le pilote PDO qui y correspond. Le pilote PDO_OCI sera utilisé dans notre cas.

Chaque objet PDO instancié correspond à une connexion de base de données :

 

PHP PDO Pilotes

Environnement

J’utilise pour cet article Wampserver avec la configuration suivante :

  • Apache 2.2.11
  • PHP 5.2.8
  • MySQL 5.1.3a
  • Oracle 10g (installé sur le serveur WAMP)

Warning_iconAttention : Dans le cas où la base Oracle est installée sur un autre poste, il faut installer l’Instant Client Oracle. Vous pouvez le télécharger sur le site d’Oracle, il est nécessaire de se créer un compte.

L’Instant Client permettra au pilote PDO_OCI d’accéder à une base Oracle distante via les pilotes Windows ODBC. Dans le cadre d’une base Oracle locale, le pilote PDO_OCI utilisera les pilotes ODBC installés localement avec la base.

Une fois l’Instant Client téléchargé, dézippez le (de préférence dans C:\Instant Client) et ajoutez le dossier à la variable PATH du système.

Installation de l’objet PDO OCI

Pour utiliser l’objet PDO et le pilote PDO_OCI, il est nécessaire d’activer les extensions php_pdo et php_pdo_oci.

Activez les depuis le menu contextuel de Wampserver ou en éditant le fichier php.ini (enlevez le point-virgule avant chaque ligne) :

extension=php_pdo.dll
extension=php_pdo_oci.dll

Warning_iconLe fichier php_pdo.dll n’est pas nécessaire à partir de PHP 5.3.0.

Il n’est pas nécessaire (voire déconseillé) d’activer les extensions php_oracle.dll et php_oci8.dll qui correspondent aux fonctions OCI8 abordées plus tôt dans cet article.

Il se peut que les extensions ne soient pas nativement présentes dans le dossier des extensions de PHP. Il n’est pas difficile de les trouver sur Internet, choisissez bien les extensions correspondant à votre version de PHP.

Voici les deux extensions php_pdo et php_pdo_oci pour PHP 5.2.8 : [ZIP] php5.2.8 php_pdo.dll php_pdo_oci.dll

PHP peut être capricieux et ne pas charger les extensions au démarrage.

Dans ce cas, placez les deux extensions dans les dossiers suivants (et ajoutez les aussi à la variable PATH du système) :

  • C:\wamp\bin\php\[VERSION PHP]
  • C:\wamp\bin\php\[VERSION PHP]\ext

De manière générale, pensez à regarder le log d’erreurs de PHP (C:\wamp\log\php_error.log) qui indique l’échec de chargement d’une extension.

Enfin, vérifiez si l’extension PDO et le pilote PDO_OCI sont installés avec la commande phpinfo().

phpinfo pdo oci

Connexion et requêtes

Afin de se connecter à la base Oracle, il faut renseigner à PHP les modalités de connexion à la base en respectant la syntaxe du fichier tnsnames.ora.

Il suffit ensuite d’instancier l’objet PDO avec les paramètres suivants : lien de base, utilisateur, mot de passe :

$hote = '127.0.0.1';
$port = '1521'; // port par défaut
$service = 'TEST';
$utilisateur = 'TEST';
$motdepasse = 'MotDePasse';

$lien_base =
"oci:dbname=(DESCRIPTION =
(ADDRESS_LIST =
	(ADDRESS =
		(PROTOCOL = TCP)
		(Host = ".$hote .")
		(Port = ".$port."))
)
(CONNECT_DATA =
	(SERVICE_NAME = ".$service.")
)
)";

try
{
	// connexion à la base Oracle et création de l'objet
	$connexion = new PDO($lien_base, $utilisateur, $motdepasse);
}
catch (PDOException $erreur)
{
	echo $erreur->getMessage();
}

Afin d’effectuer la plupart des requêtes, nous nous concentrerons sur 3 méthodes de l’objet :

  • query()
  • quote()
  • fetch() et fetchAll()

La méthode query() effectue une requête sur la base (peu importe le type de requête).

La méthode quote() permet d’échapper les variables utilisées dans la requête. Contrairement, à la fonction mysql_real_escape_string() de MySQL, la méthode quote() de la classe PDO échappe les caractères spéciaux (et dangereux) et entoure la chaîne de caractères avec des quotes. Les problèmes de sécurité (injection SQL) et de caractères spéciaux sont entièrement traités par cette méthode, peu importe le type de base de données.

Enfin, la méthode fetch() retourne dans un array indexé, un array associatif ou un objet (selon le paramètre fetch_style) une ligne d’un résultat de requête. La méthode fetchAll() permet ainsi de traiter l’intégralité des lignes du résultat sans avoir à boucler sur la méthode fetch().

Voici quelques exemples de requêtes utilisant ces méthodes :

// Sélection d'une seule ligne avec fetch()
$voiture_modele_recherche = "F430";
$voiture = $connexion->query("SELECT * FROM voitures WHERE modele = ".$connexion->quote($voiture_modele_recherche)."")->fetch();

// Sélection de plusieurs lignes avec fetchAll()
$voiture_marque_recherche = "Ferrari";
$voiture = $connexion->query("SELECT * FROM voitures WHERE marque = ".$connexion->quote($voiture_marque_recherche)."")->fetchAll();

// Mise à jour de la table, uniquement avec query()
$nouveau_proprio = 'moi';
$connexion->query("UPDATE voitures SET proprio = '".$nouveau_proprio ."' WHERE marque = modele = ".$connexion->quote($voiture_modele_recherche)."");

Vous constaterez qu’il n’est pas obligatoire d’utiliser la méthode quote(). Malgré son efficacité, il ne faut pas utiliser cette méthode à tort (pour des variables déjà échappées).

Les dates au format MySQL

Oracle affiche par défaut les champ date/time au format AAAA-MM-DD. Or, il est parfois nécessaire de manipuler plusieurs SGBDR dans un même applicatif.

Je me sert personnellement de cette requête pour qu’Oracle affiche les dates au format MySQL (AAAA-MM-DD HH:II:SS). Les dates deviennent bien plus facile à traiter.

$connexion->exec("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");

Pour finir…

La normalisation et la compatibilité des PDO sont des atouts majeurs par rapport aux fonctions OCI8 développées par Oracle.

Un développeur utilisant les PDO peut travailler sur plusieurs SGBDR sans avoir à réécrire de nouvelles lignes.

Article écrit avec l’aide de Julien TAUBENHAUS.

 

23 réflexions sur “Connexion entre Oracle 10g ou 11g et PHP avec les PDO

  • Salut,

    Félicitations pour ton tutoriel pour se connecter à une BDD Oracle via PDO. Très bien expliqué.

    Hélas, j’obtiens l’erreur suivante : « invalid data source name ».

    Sais-tu d’où ça peut venir ?

    En te remerciant de ton aide.

    Répondre
  • Salut.
    Puis-je voir le code ainsi que ton fichier TNSNAMES.ORA ?
    Oracle est installé sur la même machine ou tu passes par l’instantclient ?
    Cdt, Thibaud

    Répondre
    • Salut,

      Merci pour ton retour.

      Oracle est installé sur un serveur, je passe donc par l’Instant Client que j’ai dé-zippé à la racine de mon disque dur (C:\Instant Client) et que j’ai ajouté au PATH du système.

      Voici mon code PHP (nom d’utilisateur, mot de passe et adresse IP cachés) :
      //Informations BDD
      $user=’XXX’;
      $pwd=’YYY’;

      //Construction du lien
      $lien='(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 1.2.3.4)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = TEST)))’;

      //Initialisation de la connexion
      try{$cnx=new PDO($lien,$user,$pwd);}

      Bien entendu, j’ai testé les variables et je suis sûr que leur contenu est correct.

      Et le contenu du fichier TNSNAMES.ORA :
      EGO =
      (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 1.2.3.4)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = TEST)))

      Par contre, je n’ai pu activer que l’extension php_pdo_oci. L’autre n’était pas présente sur mon installation WAMP et étant en version PHP 5.4.3, je n’ai pas encore trouvé la DLL correspondante. Peut-être est-ce lié ?

      En te remerciant de ton aide.

      Répondre
      • Salut.

        Hélas oui c’est un problème. Je n’ai moi même jamais réussi à faire fonctionner la PDO OCI au delà de PHP 5.2.X ! Les autres PDO fonctionnent bien pourtant.
        L’extension php_pdo.dll n’existe plus au delà de PHP 5.2.X et php_pdo_oci.dll ne se charge pas (en version 32 comme 64bits, je n’ai jamais réussi).

        Si tu utilises WampServer, essaie d’installer une version de PHP (la 5.2.2 par exemple) ici :
        http://www.wampserver.com/#addons-php

        Les fichiers php_pdo.dll et php_pdo_oci.dll devront exister et se charger sans problème.

        Au niveau de l’activation des extensions PHP, c’est toujours plus sûr de passer par le php.ini que par l’activation depuis le menu de WampServer.

        Tiens moi au courant ! Thibaud

        Répondre
  • Salut,

    Bon bah le problème doit venir d’ailleurs. Même avec PHP 5.2.8, j’obtiens toujours ce satané message « invalid data source name ».

    Je te tiendrais au courant si je trouve une explication.
    Mais je suis également tout ouïe si tu as une quelconque idée.

    Répondre
  • Rectification, j’ai trouvé la source du problème.

    Au niveau du lien, il faut ajouter « oci:dbname= » en début de chaîne.

    Ce qui donnera :
    $lien=’oci:dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4])(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=TEST)));charset=AL32UTF8′;

    Du coup, connexion établie !

    Encore merci pour ton aide.

    À bientôt.

    Répondre
    • Re,

      Parfait alors !

      Effectivement, grosse erreur de ma part ! Je vais corriger ça rapidement !

      Du coup tu à réussis à charger les PDO avec PHP5.2 !? Et PHP 5.3 ou plus ?

      Cdt, Thibaud

      Répondre
      • Du coup, j’étais retourné sur PHP 5.4.3 mais si ça fonctionne sur ce dernier, ça doit fonctionner avec les versions antérieures.

        Qui plus est, après une petite recherche, l’absence de « php_pdo.dll » sur ma version s’explique par le fait que, depuis PHP 5.3, il n’y a plus besoin de ce fichier pour faire fonctionner PDO. 🙂

        Au plaisir, à bientôt.

        Répondre
  • Juste un petit mot pour vous dire que le tuto est TOP : simple, explicite et efficace. Ce qui n’est pas le cas de beaucoup de tuto.

    Merci encore !!!!!!!!!!!

    Répondre
  • Bonjour, tout d’abord je vous remercie pour ce tuto.
    J’ai tout de même un problème….
    Lorsque j’exécute le script dans wamp, il est noté : could not find driver.
    Auriez vous une solution svp.
    Je vous remercie d’avance pour votre réponse.

    Répondre
    • Bonjour,

      As tu installé l’instant client ? Celui fournit les dll nécessaires, notamment OCI.dll.

      Répondre
  • J’ai la derniere version de Wamp Server, mais j’arrive pas a me conncter.

    Répondre
    • WampServer 2.5
      Apache 2.4.9
      PHP 5.5.12
      Un coup de main je vous en prie.

      Répondre
  • bonjour comment faire pour enregistrer le premier table en html ou autre merci de votre reponse

    Répondre
  • bonjour, svp commepuis-je connecter php et oracle en windws avec easyphp
    apres avoir utilisé
    à l’aide urgentttttt svp

    Répondre
  • j’ai suivi les meme instructions que cele donnes dans l’article mais j’ai cette erreur :
    could not find driver !!!!!

    pourriez vous m’aidez ?????

    Répondre
    • Bonjour,

      J’ai rédigé cet article il y a quatre ans. PHP a beaucoup évolué depuis, surtout au niveau des PDO.

      Il semble que la PDO_OCI ne soit pas beaucoup utilisée. Si vous tombez encore sur cet article en cherchant de l’aide, c’est mauvais signe.

      Thibaud.

      Répondre
  • C’est effectivement mauvais signe mais il n’y a pas beaucoup de sujets sur oracle et PHP, pour ma part, j’ai constaté qu’en passant par le drivers PDO_OCI, à requête équivalente joué depuis Sql Developper, une même requête met quasi 35 fois plus de temps (et 3 fois plus depuis les méthodes « oci_* »).
    Avez vous déjà fais ce constat ? Avez vous des retour sur les performances ? Existe t-il une alternative intéressante (donc ayant une performance correcte) pour requêter dans du Oracle depuis PHP en 2018 ?

    Répondre
    • Bonjour,

      J’ai utilisé à l’époque les PDO pour ne pas utiliser oci_*, il fallait que je puisse changer mon SGBD sans avoir à ré-écrire le code. Je n’ai pas remarqué les problèmes de perfs dont vous parlez.

      Je suis encore étonné du nombre de visiteurs sur cet article 5 ans après sa publication. L’utilisation de PHP avec Oracle ne semble pas être une solution très populaire et le contenu de l’article est largement obsolète.

      Vous devriez essayer un lien ODBC. PHP possède des fonctions de connexion et de requêtes en ODBC. Cette solution a l’avantage d’être viable dans le temps, contrairement à la PDO_OCI.

      Thibaud.

      Répondre
  • Merci pour votre réponse, un article sur le sujet serai d’ailleurs le bienvenue (ou je l’aurai raté ?)

    Répondre
  • hello ! bon sang merci ! je n’arrivais pas à me connecter à la base oracle avec wamp – j’ai cherché cherché sur des sites et là youpi ! merci

    Répondre
  • Hamilton.Djey

    Salut,
    ton tuto date de 2018 mais sauve la « vie » en 2022.
    cela fait 2 semaine que j’essaie de déployer une application en production mais je bloque sue le pdo_oci.dll qui ne chargeait pas…. j’ai essayé ne dizaine de version de php et rien.
    Oracle étant installé sur un autre serveur, …j’ignorait qu’il fallait installer instant client…
    juste un mot. Merci

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Êtes-vous humain ? *