Access
 sql >> Base de données >  >> RDS >> Access

Pourquoi devriez-vous utiliser PHPs PDO pour l'accès à la base de données

De nombreux programmeurs PHP ont appris à accéder aux bases de données en utilisant les extensions MySQL ou MySQLi. Depuis PHP 5.1, il existe un meilleur moyen. Les objets de données PHP (PDO) fournissent des méthodes pour les instructions préparées et l'utilisation d'objets qui vous rendront beaucoup plus productif !

Générateurs et frameworks CRUD

Le code de la base de données est répétitif, mais il est très important d'être correct. C'est là qu'interviennent les générateurs et frameworks PHP CRUD :ils vous font gagner du temps en générant automatiquement tout ce code répétitif afin que vous puissiez vous concentrer sur d'autres parties de l'application.

Sur CodeCanyon, vous trouverez des générateurs et des frameworks CRUD qui vous aideront à livrer des produits de qualité exceptionnelle dans les délais. (CRUD est un acronyme pour créer, lire, mettre à jour et supprimer—les manipulations de base pour une base de données.)

  • Générateurs et frameworks PHP CRUD utiles PHP9 disponibles sur CodeCanyonFranc Lucas

Introduction à l'AOP

PDO—PHP Data Objects—sont une couche d'accès à la base de données fournissant une méthode uniforme d'accès à plusieurs bases de données.

Il ne tient pas compte de la syntaxe spécifique à la base de données, mais peut permettre que le processus de changement de bases de données et de plates-formes soit assez indolore, simplement en changeant la chaîne de connexion dans de nombreux cas.

Ce didacticiel n'est pas censé être un tutoriel complet sur SQL. Il est écrit principalement pour les personnes qui utilisent actuellement mysql ou mysqli extension pour les aider à faire le saut vers le PDO plus portable et plus puissant.

En ce qui concerne les opérations de base de données en PHP, PDO offre de nombreux avantages par rapport à la syntaxe brute. Énumérons-en rapidement quelques-unes :

  • couche d'abstraction
  • syntaxe orientée objet
  • prise en charge des déclarations préparées
  • meilleure gestion des exceptions
  • API sécurisées et réutilisables
  • prise en charge de toutes les bases de données courantes

Support de base de données

L'extension peut prendre en charge n'importe quelle base de données pour laquelle un pilote PDO a été écrit. Au moment d'écrire ces lignes, les pilotes de base de données suivants sont disponibles :

  • PDO_DBLIB (FreeTDS/Microsoft SQL Server/Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (serveur dynamique IBM Informix)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Interface d'appel d'Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC et win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 et SQLite 2)
  • PDO_4D (D)

Tous ces pilotes ne sont pas nécessairement disponibles sur votre système; voici un moyen rapide de savoir quels pilotes vous avez :

print_r(PDO::getAvailableDrivers());

Connexion

Différentes bases de données peuvent avoir des méthodes de connexion légèrement différentes. Ci-dessous, vous pouvez voir la méthode pour se connecter à certaines des bases de données les plus populaires. Vous remarquerez que les trois premiers sont identiques, à l'exception du type de base de données, et que SQLite a sa propre syntaxe.

essayez { # MS SQL Server et Sybase avec PDO_DBLIB $DBH =new PDO("mssql:host =$host;dbname=$dbname", $user, $pass); $DBH =new PDO("sybase:host=$host;dbname=$dbname", $user, $pass); # MySQL avec PDO_MYSQL $DBH =new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # Base de données SQLite $DBH =new PDO("sqlite:my/database/path/database.db");}catch(PDOException $e) { echo $e->getMessage();}

Veuillez prendre note du bloc try/catch. Vous devez toujours envelopper vos opérations PDO dans un try/catch et utiliser le mécanisme d'exception - plus d'informations à ce sujet sous peu. En règle générale, vous n'allez établir qu'une seule connexion - il y en a plusieurs répertoriées pour vous montrer la syntaxe. $DBH signifie 'database handle' et sera utilisé tout au long de ce didacticiel.

Vous pouvez fermer n'importe quelle connexion en définissant le handle sur null.

# ferme la connexion$DBH =null;

Vous pouvez obtenir plus d'informations sur les options spécifiques à la base de données et/ou les chaînes de connexion pour d'autres bases de données sur PHP.net.

Exceptions et AOP

PDO peut utiliser des exceptions pour gérer les erreurs, ce qui signifie que tout ce que vous faites avec PDO doit être enveloppé dans un bloc try/catch. Vous pouvez forcer PDO dans l'un des trois modes d'erreur en définissant l'attribut de mode d'erreur sur votre descripteur de base de données nouvellement créé. Voici la syntaxe :

$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

Quel que soit le mode d'erreur que vous définissez, une erreur de connexion produira toujours une exception et la création d'une connexion doit toujours être contenue dans un bloc try/catch.

PDO::ERRMODE_SILENT

C'est le mode d'erreur par défaut. Si vous le laissez dans ce mode, vous devrez vérifier les erreurs de la manière dont vous êtes probablement habitué si vous avez utilisé le mysql ou mysqli extensions. Les deux autres méthodes sont plus adaptées à la programmation DRY.

PDO::ERRMODE_WARNING

Ce mode émettra un avertissement PHP standard et permettra au programme de continuer son exécution. C'est utile pour le débogage.

PDO::ERRMODE_EXCEPTION

C'est le mode que vous voulez dans la plupart des situations. Il déclenche une exception, vous permettant de gérer les erreurs avec élégance et de masquer les données qui pourraient aider quelqu'un à exploiter votre système. Voici un exemple d'utilisation des exceptions :

# se connecter à la base de donnéestry { $DBH =new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); # UH-OH ! Tapé DELECT au lieu de SELECT ! $DBH->prepare('DELECT name FROM people');}catch(PDOException $e) { echo "Je suis désolé, Dave. J'ai peur de ne pas pouvoir faire ça."; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);}

Il y a une erreur intentionnelle dans l'instruction select; cela provoquera une exception. L'exception envoie les détails de l'erreur dans un fichier journal et affiche un message convivial (ou moins convivial) à l'utilisateur.

Insérer et mettre à jour

L'insertion de nouvelles données (ou la mise à jour de données existantes) est l'une des opérations de base de données les plus courantes. En utilisant PHP PDO, il s'agit normalement d'un processus en deux étapes. Tout ce qui est couvert dans cette section s'applique également à la fois à la UPDATE et INSERT opérations.

Voici un exemple du type d'insertion le plus basique :

# STH signifie "Statement Handle"$STH =$DBH->prepare("INSERT INTO folks ( first_name ) values ​​( 'Cathy' )");$STH->execute();

Vous pouvez également accomplir la même opération en utilisant le exec() méthode, avec un appel en moins. Dans la plupart des situations, vous allez utiliser la méthode la plus longue afin de pouvoir tirer parti des instructions préparées. Même si vous ne l'utilisez qu'une seule fois, l'utilisation d'instructions préparées vous aidera à vous protéger des attaques par injection SQL.

Relevés préparés

L'utilisation d'instructions préparées vous aidera à vous protéger des injections SQL.

Une instruction préparée est une instruction SQL précompilée qui peut être exécutée plusieurs fois en envoyant uniquement les données au serveur. Il présente l'avantage supplémentaire de protéger automatiquement les données utilisées dans les espaces réservés contre les attaques par injection SQL.

Vous utilisez une instruction préparée en incluant des espaces réservés dans votre SQL. Voici trois exemples :un sans espace réservé, un avec des espaces réservés sans nom et un avec des espaces réservés nommés.

# pas d'espace réservé - prêt pour l'injection SQL !$STH =$DBH->prepare("INSERT INTO peoples (name, addr, city) values ​​($name, $addr, $city)"); # espaces réservés sans nom$STH =$DBH->prepare("INSERT INTO folks (name, addr, city) values ​​(?, ?, ?)"); # espaces réservés nommés$STH =$DBH->prepare("INSERT INTO folks (name, addr, city) values ​​(:name, :addr, :city)");

Vous voulez éviter la première méthode; c'est ici pour comparaison. Le choix d'utiliser des espaces réservés nommés ou non affectera la façon dont vous définissez les données pour ces déclarations.

Espaces réservés sans nom

# attribue des variables à chaque espace réservé, indexé 1-3$STH->bindParam(1, $name);$STH->bindParam(2, $addr);$STH->bindParam(3, $city); # insérez une ligne$name ="Daniel"$addr ="1 Wicked Way";$city ="Arlington Heights";$STH->execute(); # insère une autre ligne avec des valeurs différentes$name ="Steve"$addr ="5 Circle Drive";$city ="Schaumburg";$STH->execute();

Il y a deux étapes ici. Tout d'abord, nous attribuons des variables aux différents espaces réservés (lignes 2 à 4). Ensuite, nous attribuons des valeurs à ces espaces réservés et exécutons l'instruction. Pour envoyer un autre ensemble de données, modifiez simplement les valeurs de ces variables et exécutez à nouveau l'instruction.

Cela semble-t-il un peu lourd pour les instructions avec beaucoup de paramètres ? Il est. Cependant, si vos données sont stockées dans un tableau, il existe un raccourci simple :

# les données que nous voulons insérer$data =array('Cathy', '9 Dark and Twisty Road', 'Cardiff'); $STH =$DBH->prepare("INSERT INTO folks (name, addr, city) values ​​(?, ?, ?)");$STH->execute($data);

C'est facile !

Les données du tableau s'appliquent aux espaces réservés dans l'ordre. $data[0] va dans le premier espace réservé, $data[1] le second, etc. Cependant, si les index de votre tableau ne sont pas dans l'ordre, cela ne fonctionnera pas correctement et vous devrez réindexer le tableau.

Espaces réservés nommés

Vous pourriez probablement deviner la syntaxe, mais voici un exemple :

# le premier argument est le nom de l'espace réservé nommé - notez que les espaces réservés nommés # commencent toujours par deux-points.$STH->bindParam(':name', $name);

Vous pouvez également utiliser un raccourci ici, mais cela fonctionne avec des tableaux associatifs. Voici un exemple :

# les données que nous voulons insérer$data =array( 'name' => 'Cathy', 'addr' => '9 Dark and Twisty', 'city' => 'Cardiff' ); # le raccourci !$STH =$DBH->prepare("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");$STH->execute($data); 

Les clés de votre tableau n'ont pas besoin de commencer par deux-points, mais doivent sinon correspondre aux espaces réservés nommés. Si vous avez un tableau de tableaux, vous pouvez les parcourir et appeler simplement le execute avec chaque tableau de données.

Une autre fonctionnalité intéressante des espaces réservés nommés est la possibilité d'insérer des objets directement dans votre base de données, en supposant que les propriétés correspondent aux champs nommés. Voici un exemple d'objet et comment vous effectueriez votre insertion :

# une simple objectclass person { public $name; public $adresse ; $ville publique ; function __construct($n,$a,$c) { $this->name =$n; $this->adresse =$a ; $cette->ville =$c; } # etc ...} $cathy =new person('Cathy','9 Dark and Twisty','Cardiff'); # voici la partie amusante :$STH =$DBH->prepare("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");$STH->execute((array)$ cathy);

Caster l'objet dans un tableau dans le execute signifie que les propriétés sont traitées comme des clés de tableau.

Sélectionner des données

Les données sont obtenues via ->fetch() , une méthode de votre handle d'instruction. Avant d'appeler fetch, il est préférable d'indiquer à PDO comment vous souhaitez que les données soient récupérées. Vous disposez des options suivantes :

  • PDO::FETCH_ASSOC : renvoie un tableau indexé par nom de colonne.
  • PDO::FETCH_BOTH (par défaut) : renvoie un tableau indexé à la fois par le nom et le numéro de la colonne.
  • PDO::FETCH_BOUND : attribue les valeurs de vos colonnes aux variables définies avec le ->bindColumn() méthode.
  • PDO::FETCH_CLASS : attribue les valeurs de vos colonnes aux propriétés de la classe nommée. Il créera les propriétés si les propriétés correspondantes n'existent pas.
  • PDO::FETCH_INTO : met à jour une instance existante de la classe nommée.
  • PDO::FETCH_LAZY  :combine PDO::FETCH_BOTH /PDO::FETCH_OBJ , en créant les noms des variables d'objet au fur et à mesure qu'ils sont utilisés.
  • PDO::FETCH_NUM : renvoie un tableau indexé par numéro de colonne.
  • PDO::FETCH_OBJ : renvoie un objet anonyme avec des noms de propriété qui correspondent aux noms de colonne.

En réalité, il y en a trois qui couvriront la plupart des situations : FETCH_ASSOCFETCH_CLASS , et FETCH_OBJ . Afin de définir la méthode de récupération, la syntaxe suivante est utilisée :

$STH->setFetchMode(PDO::FETCH_ASSOC);

Vous pouvez également définir le type de récupération directement dans ->fetch() appel de méthode.

FETCH_ASSOC

Ce type d'extraction crée un tableau associatif, indexé par nom de colonne. Cela devrait être assez familier à quiconque a utilisé les extensions mysql/mysqli. Voici un exemple de sélection de données avec cette méthode :

# en utilisant la méthode raccourci ->query() ici puisqu'il n'y a pas de valeurs de variable# dans l'instruction select.$STH =$DBH->query('SELECT name, addr, city from folks'); # définir le mode de récupération$STH->setFetchMode(PDO::FETCH_ASSOC); while($row =$STH->fetch()) { echo $row['name'] . "\n" ; echo $ligne['adresse'] . "\n" ; echo $ligne['ville'] . "\n";}

La boucle while continuera à parcourir le jeu de résultats une ligne à la fois jusqu'à ce qu'elle soit terminée.

FETCH_OBJ

Ce type d'extraction crée un objet de classe std pour chaque ligne de données extraites. Voici un exemple :

# création de l'instruction $STH =$DBH->query('SELECT name, addr, city from folks'); # définition du mode de récupération$STH->setFetchMode(PDO::FETCH_OBJ); # montrant les résultatswhile($row =$STH->fetch()) { echo $row->name . "\n" ; echo $ligne->adresse . "\n" ; echo $ligne->ville . "\n";}

FETCH_CLASS

Les propriétés de votre objet sont définies AVANT que le constructeur ne soit appelé. C'est important.

Cette méthode de récupération vous permet de récupérer des données directement dans une classe de votre choix. Lorsque vous utilisez FETCH_CLASS , les propriétés de votre objet sont définies BEFORE le constructeur est appelé. Relisez-le, c'est important. Si les propriétés correspondant aux noms de colonne n'existent pas, ces propriétés seront créées (publiques) pour vous.

Cela signifie que si vos données ont besoin d'une transformation après leur sortie de la base de données, cela peut être fait automatiquement par votre objet lors de la création de chaque objet.

Par exemple, imaginez une situation où l'adresse doit être partiellement masquée pour chaque enregistrement. Nous pourrions le faire en opérant sur cette propriété dans le constructeur. Voici un exemple :

classe secret_person { public $name; public $adresse ; $ville publique ; public $other_data ; function __construct($other ='') { $this->adresse =preg_replace('/[a-z]/', 'x', $this->adresse); $this->other_data =$other ; }}

Au fur et à mesure que les données sont récupérées dans cette classe, l'adresse a tous ses minuscules a-z lettres remplacées par la lettre x . Désormais, l'utilisation de la classe et la transformation des données sont totalement transparentes :

$STH =$DBH->query('SELECT name, addr, city from people');$STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person'); while($obj =$STH->fetch()) { echo $obj->addr;}

Si l'adresse était '5 Rosebud', vous verriez '5 Rxxxxxx' comme sortie. Bien sûr, il peut y avoir des situations où vous souhaitez que le constructeur soit appelé avant que les données ne soient affectées. PDO vous couvre également pour cela.

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'secret_person');

Maintenant, lorsque vous répétez l'exemple précédent avec ce mode de récupération (PDO::FETCH_PROPS_LATE ), l'adresse ne sera pas être obscurci, car le constructeur a été appelé et les propriétés ont été assignées.

Enfin, si vous en avez vraiment besoin, vous pouvez passer des arguments au constructeur lors de la récupération de données dans des objets avec PDO :

$STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person', array('stuff'));

Si vous devez transmettre différentes données au constructeur pour chaque objet, vous pouvez définir le mode de récupération dans le fetch méthode :

$i =0;while($rowObj =$STH->fetch(PDO::FETCH_CLASS, 'secret_person', array($i))) { // faire des trucs $i++}

Quelques autres méthodes utiles

Bien que cela ne soit pas censé couvrir tout dans PDO (c'est une énorme extension !), il existe quelques méthodes supplémentaires que vous voudrez connaître pour faire des choses de base avec PDO.

$DBH->lastInsertId();

Le ->lastInsertId() est toujours appelée sur le handle de la base de données, pas sur le handle de l'instruction, et renverra l'identifiant auto-incrémenté de la dernière ligne insérée par cette connexion.

$DBH->exec('DELETE FROM folks WHERE 1');$DBH->exec("SET time_zone ='-8:00'");

Le ->exec() La méthode est utilisée pour les opérations qui ne peuvent pas renvoyer de données autres que les lignes affectées. Ce qui précède sont deux exemples d'utilisation de la méthode exec.

$safe =$DBH->quote($unsafe);

Le ->quote() La méthode cite les chaînes afin qu'elles puissent être utilisées en toute sécurité dans les requêtes. C'est votre solution de rechange si vous n'utilisez pas d'instructions préparées.

$rows_affected =$STH->rowCount();

Le ->rowCount() La méthode renvoie un entier indiquant le nombre de lignes affectées par une opération. Dans au moins une version connue de PDO, la méthode ne fonctionnait pas avec les instructions select. Cependant, cela fonctionne correctement dans la version PHP 5.1.6 et supérieure.

Si vous rencontrez ce problème et que vous ne pouvez pas mettre à jour PHP, vous pouvez obtenir le nombre de lignes avec ce qui suit :

$sql ="SELECT COUNT(*) FROM folks";if ($STH =$DBH->query($sql)) { # vérifie le nombre de lignes if ($STH->fetchColumn()> 0) { # lancez une vraie sélection ici, car il y a des données ! } else { echo "Aucune ligne ne correspond à la requête."; }}

Générateurs PHP CRUD de CodeCanyon

Vous pouvez gagner des heures de temps en trouvant un générateur PHP CRUD de CodeCanyon et en l'utilisant dans vos projets. Voici cinq des téléchargements les plus populaires que vous pouvez commencer à utiliser dès maintenant.

1. Application polyvalente Laravel :Sximo 6

Le constructeur Sximo 6 est basé sur les frameworks les plus populaires. Il a également reçu une nouvelle mise à jour pour 2021, le rendant aussi facile à utiliser et riche en fonctionnalités que possible. Certaines de ces fonctionnalités incluent :

  • gestion des tables de base de données
  • Modèles front-end et back-end
  • module éditeur MySQL
  • prise en charge de plusieurs images et téléchargement de fichiers

Essayez-le si vous cherchez à gagner du temps avec un modèle PHP CRUD.

2. PDO Crud :Générateur de formulaires et gestion de base de données

Voici un autre puissant générateur PHP CRUD. Ce modèle de code PHP PDO gère bien la base de données. Mais ce n'est pas tout. Vous pouvez également utiliser PDO CRUD pour créer des formulaires utiles directement à partir de vos tables de base de données. C'est une fonctionnalité utile que peu d'autres options ont.

3. Cicool :page, formulaire, API REST et générateur CRUD

Cicool est un autre constructeur polyvalent qui mérite d'être examiné. Non seulement il offre un constructeur CRUD, mais il a aussi :

  • créateur de pages
  • créateur de formulaires
  • Constructeur d'API REST

En plus de ces fonctionnalités, vous pouvez également ajouter des extensions à Cicool et personnaliser facilement son thème.

4. Générateur PHP CRUD

Générateur de panneau d'administration facile ? Vérifier. Interface facile à naviguer ? Vérifier. Analyse approfondie de la base de données ? Un autre chèque. Ce générateur PHP CRUD a tout ce dont vous avez besoin pour créer de superbes tableaux de bord et stocker vos données. Avec différentes fonctionnalités d'authentification des utilisateurs et de gestion des droits, ce modèle PHP PDO vaut le détour.