Introduction

modifier

PDO (PHP Data Objects) est une extension définissant l'interface pour accéder à plusieurs types de base de données, fournie automatiquement depuis PHP 5.1. Avec ce système, pour utiliser plusieurs SGBD il n'est pas nécessaire de changer les fonctions de communication dans tout le code, mais seulement les arguments envoyés au constructeur.

Les pilotes suivants sont disponibles[1] :

  1. 4D
  2. CUBRID
  3. Firebird
  4. IBM DB2
  5. Informix
  6. Microsoft SQL Server
  7. MySQL
  8. Oracle Database
  9. PostgreSQL
  10. SQLite

Et aussi via ODBC.

Installation

modifier

Machine hôte

modifier
 Pour PHP 5.0, l'extension est disponible en tant qu'extension PECL, et doit être activée[2] en ajoutant ou décommentant la ligne de "php_pdo.dll" dans php.ini.

Pour activer les différents SGBD qui doivent communiquer avec PDO, il faut ajouter ou décommenter les lignes extension=php_pdo_[SGBD utilisé].dll dans php.ini, que ce soit sur Apache ou IIS. Exemple :

extension=php_pdo_firebird.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
extension=php_pdo_sqlsrv_54_ts.dll

Les .dll de Microsoft SQL Server sont téléchargeables sur le site officiel[3].

MySQL :

RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli

PostgreSQL :

RUN apt-get update && apt-get install -y libpq-dev
RUN docker-php-ext-install pdo_pgsql && docker-php-ext-enable pdo_pgsql

Les classes de l'extension PDO

modifier

L'extension PDO comporte trois classes[4] :

  • La classe PDO correspond à une connexion à la base de données.
  • La classe PDOStatement représente d'une part une requête préparée et d'autre part le jeu de résultats de la requête une fois qu'elle est exécutée.

Cette classe offre des méthodes de parcours, de comptage, d'informations.

  • La classe PDOException représente une erreur émise par PDO.

Accès à la base de données avec PDO

modifier

L'accès à la base de données se fait en instanciant un objet PDO. Les paramètres à indiquer au constructeur sont :

  • la source de la base de données ;
  • optionnellement, le nom d'utilisateur et le mot de passe.

Par exemple, pour accéder à une base de données de nom ma_bdd accessible sur le port mon_port du serveur mon_serveur avec l'utilisateur mon_id associé au mot de passe mon_mot_de_passe, le code sera le suivant :

  • Pour MySQL[5] :
$connexion = new PDO('mysql:host=mon_serveur;dbname=ma_bdd;port=3306','mon_id','mon_mot_de_passe');
  • Pour MS-SQL[6] les noms des paramètres diffèrent :
$connexion = new PDO('sqlsrv:server=mon_serveur:mon_port;Database=ma_bdd','mon_id','mon_mot_de_passe');
  • MS-SQL via une source de données ODBC (à créer dans C:\Windows\SysWOW64\odbcad32.exe) :
$connexion = new PDO('odbc:nom_de_la_source','mon_id','mon_mot_de_passe');
  • Pour PostgreSQL[7] :
$connexion = new PDO('pgsql:host=mon_serveur;dbname=ma_bdd;port=5432;user=mon_id;password=mon_mot_de_passe');

 

Par rapport à mysqli, PDO indique le nom réseau de la machine qui l'utilise en suffixe du compte MySQL, ce qui change le nom du compte et donc les permissions sur les bases. Par exemple si 'mon_id@%' est autorisé, ce n'est pas forcément le cas de 'mon_id@192.168.1.10', ce qui provoque l'erreur Access denied for user.

Passer des requêtes en PDO

modifier

Des méthodes permettent de passer des requêtes à l'objet récupéré lors de la connexion.

  • PDO::exec(string $statement)

La méthode exec() permet de passer et exécuter une requête SQL de type INSERT, UPDATE, DELETE.
Elle retourne le nombre de lignes affectées par la requête.

$requete="DELETE * FROM matable WHERE champ1='mavaleur'";
$resultat=$connexion->exec($requete);
echo $resultat.' suppressions effectuées';
  • PDO::query(string $statement)

La méthode query() permet de passer et exécuter une requête SQL de type SELECT.
Elle retourne le jeu de résultats (s'il y en a) sous forme d'objet PDOStatement.

$requete="SELECT champ1, champ2 FROM matable";
$resultat=$connexion->query($requete);

Quelques méthodes de PDOStatement

modifier
  • PDOStatement::fetch() récupère la ligne suivante d'un jeu de résultats PDO.
  • PDOStatement::fetchAll() retourne un tableau contenant toutes les lignes du jeu d'enregistrements PDO.
  • PDOStatement::fetchObject() récupère la ligne suivante et la retourne en tant qu'objet.
  • PDOStatement::fetchColumn() retourne une colonne depuis la ligne suivante d'un jeu de résultats PDO.
  • PDOStatement::rowCount() retourne le nombre de lignes affectées par le dernier appel à la fonction.
  • PDOStatement::closeCursor() libère la connexion au serveur, permettant ainsi à d'autres requêtes SQL d'être exécutées. La requête reste dans un état lui permettant d'être de nouveau exécutée. Cette fonction retourne TRUE en cas de succès ou FALSE si une erreur survient.
  • PDOStatement::execute() exécute une requête préparée.

Les paramètres de la méthode fetch

modifier

La méthode fetch() peut avoir en paramètre le type de retour du résultat. Par défaut, sans paramètre, le paramètre implicite est PDO::FETCH_BOTH.

  • PDO::FETCH_ASSOC retourne le jeu de résultats sous forme d'un tableau associatif, dont la clé est le nom de colonnes.

Exemple d'utilisation :

while ($ligne = $resultat ->fetch(PDO::FETCH_ASSOC)) {    
 echo $ligne['champ3'].' '.$ligne['champ1'].'<br/>';   
}
  • PDO::FETCH_NUM retourne le jeu de résultats sous forme d'un tableau indexé par numéro commençant à 0.

Exemple d'utilisation :

while ($ligne = $resultat ->fetch(PDO::FETCH_NUM)) {    
 echo $ligne[2].' '.$ligne[0].'<br/>';   
}
  • PDO::FETCH_BOTH retourne un tableau indexé et un tableau associatif.
  • PDO::FETCH_OBJ retourne le jeu de résultats sous forme d'un objet dont les noms de propriétés correspondent aux noms des colonnes.

Faire une requête préparée avec PDO

modifier

PDO::prepare() permet de préparer une requête que l'on exécutera ensuite avec la méthode PDOStatement::execute().

Les variables (parties de la requête spécifiques au moment de l'exécution) seront passées à la requête préparée grâce à cette méthode execute(). Ce dispositif protège l'application d'attaque de type injection SQL.

Exemple :

        $pdoStatement = PDO::prepare('SELECT * FROM people WHERE name = :name');
        $pdoStatement->bindParam(':name', $name, PDO::PARAM_STR);
        $pdoStatement->execute();

        return $pdoStatement->fetchAll(PDO::FETCH_ASSOC);

Jongler avec plusieurs SGBD en même temps

modifier

Pour exécuter alternativement des requêtes sur plusieurs SGBD, par exemple pour comparer leurs bases :

Notes et références

modifier