Prêt à l’emploi, WordPress fournit des tonnes de fonctions qui peuvent être utilisées pour interagir avec la base de données. Dans la plupart des cas, le WP_Query
classe et fonctions connexes telles que wp_insert_post
, update_post_meta
, get_posts
sera suffisant pour faire le travail. Cependant, il y aura des moments où nous devrons faire quelque chose qui n’est pas fourni par WordPress de manière native, en particulier lorsque nous devons gérer des tableaux personnalisés.
Dans ce didacticiel, nous allons parcourir la classe la plus importante pour gérer les bases de données dans WordPress – wpdb
, y compris quelques trucs et astuces qui peuvent être implémentés ultérieurement dans notre workflow de développement. Nous aborderons également dbDelta
qui peut être utilisé pour créer des tableaux personnalisés dans notre plugin. Nous ne couvrirons pas les bases de la création de votre base de données WordPress originale dans ce didacticiel, mais n’hésitez pas à consulter ce didacticiel sur créer des bases de données à partir de cPanel
Travailler avec le wpdb
Classer
wpdb
est peut-être la classe la plus importante que nous utilisons lorsque nous devons traiter directement la base de données. Il est basé sur la ezSQL
classe écrite par Justin Vincent, adaptée pour fonctionner avec WordPress.
Les méthodes et propriétés de base de la wpdb
la classe est déjà bien expliquée sur le Page du codex WordPress il est donc inutile de les répéter ici. Au lieu de cela, nous allons passer en revue quelques erreurs courantes que les développeurs WordPress peuvent commettre, comment les rectifier, ainsi que les meilleures pratiques qui peuvent être appliquées lors de l’utilisation du wpdb
classer.
Ne pas coder en dur les noms de table dans la requête SQL
Certains développeurs partent du principe que le préfixe de table sera inchangé et utiliseront la valeur par défaut de wp_
. Un exemple de base de la mauvaise façon de procéder est illustré dans l’extrait ci-dessous :
global $wpdb;
$result = $wpdb->get_results('SELECT * FROM wp_posts LIMIT 10');
Il s’agit bien sûr d’une simplification excessive de ce qu’un plugin va réellement faire, mais cet exemple montre à quelle vitesse les choses peuvent mal tourner. Que se passe-t-il si nos utilisateurs remplacent le préfixe de la table par autre chose ? Cela peut être facilement résolu en remplaçant le wp_
chaîne avec les propriétés réelles fournies en utilisant prefix
.
Le code ci-dessus peut être rendu portable en appliquant les modifications ci-dessous :
global $wpdb;
$result = $wpdb->get_results('SELECT * FROM ' $wpdb->prefix 'posts LIMIT 10');
Mieux encore, si vous avez affaire aux tables par défaut de WordPress, vous pouvez ignorer la partie préfixe et à la place, les adresser directement en tant que propriétés dans wpdb
. Chaque tableau WordPress par défaut est représenté par une propriété personnalisée dans le wpdb
classe avec le même nom de table sans le préfixe.
Par exemple, en supposant que le préfixe de table est wp_
:
$wpdb->posts
correspondra àwp_posts
table$wpdb->postmeta
correspondra àwp_postmeta
table$wpdb->users
correspondra àwp_users
table
Etc. Le code ci-dessus peut encore être amélioré, puisque nous interrogeons la table des messages en procédant de la sorte :
global $wpdb;
$result = $wpdb->get_results('SELECT * FROM ' $wpdb->posts ' LIMIT 10');
Utiliser des méthodes d’assistance spécifiques pour les opérations de base de données
Bien que le query
est conçue pour gérer toutes les requêtes SQL, il est préférable d’utiliser des méthodes d’assistance plus appropriées. Ceci est généralement fourni par des méthodes telles que insert
, update
, get_row
et d’autres. En plus de cela, il est plus spécifique à nos cas d’utilisation, il est également plus sûr car les fuites et autres travaux fastidieux sont pris en charge.
Jetons un œil à cet exemple :
$global wpdb;
$post_id = $_POST['post_id'];
$meta_key = $_POST['meta_key'];
$meta_value = $_POST['meta_value'];
$wpdb->query("INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value )
VALUES ( $post_id, $meta_key, $meta_value )"
);
Outre la nature dangereuse de cet extrait, il devrait fonctionner correctement avec les valeurs appropriées. Cependant, cet extrait peut être encore amélioré en utilisant le insert
méthode à la place. Le code ci-dessus peut être modifié pour ressembler à ce qui suit :
$global wpdb;
$post_id = $_POST['post_id'];
$meta_key = $_POST['meta_key'];
$meta_value = $_POST['meta_value'];
$wpdb->insert(
$wpdb->postmeta,
array(
'post_id' => $_POST['post_id'],
'meta_key' => $_POST['meta_key'],
'meta_value' => $_POST['meta_value']
)
);
Si nous ne fournissons pas le format comme troisième paramètre pour insert
, toutes les données fournies dans le deuxième paramètre seront échappées sous forme de chaîne. De plus, nous pouvons facilement savoir ce que fait ce code en un coup d’œil, car le nom de la méthode est plus clair.
Déboguer correctement les requêtes de base de données
Par défaut, le rapport d’erreur est désactivé. Cependant, wpdb
fournit deux méthodes qui peuvent être utilisées pour basculer l’état du rapport d’erreur.
Pour activer la fonction de rapport d’erreurs, exécutez simplement ce code.
$wpdb->show_errors();
Et pour l’éteindre :
$wpdb->hide_errors();
Une autre chose à noter est que si nous définissons les deux WP_DEBUG
et WP_DEBUG_DISPLAY
à true
la show_errors
méthode sera automatiquement appelée. Il existe une autre méthode utile qui peut être utilisée pour traiter les erreurs, à savoir print_error
:
$wpdb->print_error();
Comme son nom l’indique, il n’affichera que l’erreur de la requête la plus récente, quel que soit l’état du rapport d’erreur.
Une autre astuce consiste à activer SAVEQUERIES
dans wp-config.php
. Cela stockera toutes les requêtes de base de données qui s’exécutent, les temps pris et l’origine de l’appel dans une propriété appelée queries
dans le wpdb
classer.
Pour récupérer ces données, nous pouvons procéder comme suit :
print_r( $wpdb->queries );
Notez que cela aura un impact sur les performances de notre site, alors utilisez-le uniquement lorsque cela est nécessaire.
La plupart du temps, ces fonctions suffiront à déboguer ce qui ne va pas avec notre code. Cependant, pour un débogage et des rapports plus approfondis, il y a toujours le Moniteur de requête plugin qui peut aider à déboguer plus que les requêtes de base de données.
Sécurisation des requêtes contre les attaques potentielles
Pour sécuriser complètement notre code de l’injection SQL, wpdb
fournit également une autre méthode utile appelée prepare
qui prendra une chaîne d’une instruction SQL et des données qui doivent être échappées. Ceci est pertinent chaque fois que nous avons affaire à des méthodes telles que query
ou get_results
.
$wpdb->prepare( $sql, $format... );
La prepare
prend en charge à la fois la syntaxe de sprintf
et vsprintf
. Le premier paramètre, $sql
est une instruction SQL remplie d’espaces réservés. Ces espaces réservés peuvent exister dans trois formats différents :
%s
pour chaîne%d
pour entier%f
pour flotteur
$format
peut être une série de paramètres pour sprintf
comme la syntaxe, ou un tableau de paramètres qui seront utilisés pour remplacer l’espace réservé dans $sql
. La méthode renverra le SQL avec des données correctement échappées.
Voyons comment nous pouvons réaliser le processus de suppression meta_key
dans wp_postmeta
pour un identifiant de publication spécifique :
$global wpdb;
$post_id = $_POST['post_id'];
$key = $_POST['meta_key'];
$wpdb->query(
"DELETE FROM $wpdb->postmeta
WHERE post_id = $post_id
AND meta_key = $key"
);
Notez que ce n’est pas la méthode recommandée pour supprimer un enregistrement dans la base de données à l’aide de wpdb
. C’est parce que nous laissons le code ouvert à l’injection SQL, puisque l’entrée utilisateur n’est pas correctement échappée et utilisée directement dans le DELETE
déclaration.
Cependant, cela peut être facilement corrigé! Nous introduisons simplement le prepare
méthode avant de faire la requête proprement dite, afin que le SQL généré puisse être utilisé en toute sécurité. Cela peut être illustré dans l’extrait ci-dessous:
$global wpdb;
$post_id = $_POST['post_id'];
$key = $_POST['meta_key'];
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key = %s",
$post_id,
$key
)
);
Connexion à des bases de données distinctes
Par défaut, le $wpdb
variable est une instance de wpdb
classe qui se connecte à la base de données WordPress définie dans wp-config.php
. Si nous voulons interagir avec d’autres bases de données, nous pouvons instancier une autre instance de wpdb
classer. Cela nous profite grandement, car des méthodes comme insert
, update
et get_results
sont disponibles.
La wpdb
La classe accepte quatre paramètres dans la construction, qui sont le nom d’utilisateur, le mot de passe, le nom de la base de données et l’hôte de la base de données, dans cet ordre. Voici un exemple :
$mydb = new wpdb( 'username', 'password', 'my_database', 'localhost' );
$mydb->query('DELETE FROM external_table WHERE id = 1');
Si nous utilisons le même nom d’utilisateur, mot de passe et hôte de base de données, mais que nous devons uniquement modifier la base de données sélectionnée, il existe une méthode pratique appelée select
sur le mondial $wpdb
variable. Ceci est réalisé en interne en utilisant le mysql_select_db
/mysqli_select_db
fonction.
$wpdb->select('my_database');
Ceci est également particulièrement utile lorsque nous voulons passer à une autre base de données WordPress, mais que nous souhaitons tout de même conserver la fonctionnalité de fonctions telles que get_post_custom
et d’autres.
Utilisation de tables de base de données personnalisées
Les tables par défaut de WordPress suffisent généralement pour gérer les opérations les plus complexes. En utilisant des types de publication personnalisés avec des métadonnées de publication, des taxonomies personnalisées et des métadonnées de terme, nous pouvons faire presque n’importe quoi sans avoir besoin d’utiliser des tableaux personnalisés.
Cependant, les tables personnalisées peuvent être utiles chaque fois que nous voulons avoir un contrôle plus précis sur les données que notre plugin peut gérer. Les avantages de l’utilisation de tableaux personnalisés incluent :
- Contrôle total de la structure des données – Tous les types de données ne rentrent pas dans la structure d’un
post
donc lorsque nous voulons stocker des données qui n’ont aucun sens en tant que type de publication personnalisé, une table personnalisée peut être une meilleure option. - Séparation des préoccupations – Étant donné que nos données sont stockées dans un tableau personnalisé, elles n’interféreront pas avec le
wp_posts
ouwp_postmeta
tables par opposition à si nous utilisions des types de publication personnalisés. La migration de nos données vers une autre plate-forme est plus facile car elle n’est pas limitée à la façon dont WordPress structure ses données. - Efficacité – Interroger les données de notre table spécifique sera certainement beaucoup plus rapide que de parcourir le
wp_posts
table qui contient également des données sans rapport avec notre plugin. Il s’agit d’un problème apparent lors de l’utilisation de types de publication personnalisés pour stocker de nombreuses métadonnées susceptibles de gonfler lewp_postmeta
table.
dbDelta à la rescousse
À la place d’utiliser wpdb
pour créer une table de base de données personnalisée, il est recommandé d’utiliser dbDelta pour gérer toute la création de votre table initiale, ainsi que les mises à jour du schéma de la table. C’est fiable, puisque le noyau de WordPress utilise également cette fonction pour gérer toutes les mises à jour du schéma de base de données d’une version à l’autre, le cas échéant.
Pour créer une table personnalisée initialement lors de l’installation du plugin, nous devons accrocher notre fonction au register_activation_hook
fonction. En supposant que notre fichier de plugin principal est plugin-name.php
à l’intérieur d’un plugin-name
répertoire, nous pouvons mettre cette ligne directement dedans:
register_activation_hook( __FILE__, 'prefix_create_table' );
Ensuite, nous devons créer la fonction prefix_create_table
qui fait la création réelle de la table lors de l’activation du plugin. Par exemple, nous pouvons créer une table personnalisée appelée my_custom_table
qui seront utilisées pour stocker des données clients simples telles que le prénom, le nom et leur adresse e-mail.
function prefix_create_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE my_custom_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
first_name varchar(55) NOT NULL,
last_name varchar(55) NOT NULL,
email varchar(55) NOT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
if ( ! function_exists('dbDelta') ) {
require_once( ABSPATH 'wp-admin/includes/upgrade.php' );
}
dbDelta( $sql );
}
Pour optimiser la compatibilité, nous récupérons le jeu de caractères de la base de données à partir de wpdb
. De plus, l’instruction SQL doit respecter certaines règles pour s’assurer qu’elle fonctionne comme prévu. Ceci est tiré directement de la page du Codex sur Création de tableaux avec plugin:
- Vous devez placer chaque champ sur sa propre ligne dans votre instruction SQL.
- Vous devez avoir deux espaces entre les mots PRIMARY KEY et la définition de votre clé primaire.
- Vous devez utiliser le mot clé KEY plutôt que son synonyme INDEX et vous devez inclure au moins une KEY.
- Vous ne devez pas utiliser d’apostrophes ou de backticks autour des noms de champs.
- Les types de champs doivent être tous en minuscules.
- Les mots clés SQL, tels que CREATE TABLE et UPDATE, doivent être en majuscules.
- Vous devez spécifier la longueur de tous les champs qui acceptent un paramètre de longueur. int(11), par exemple.
C’est aussi généralement une bonne idée de stocker la version de la base de données dans la table des options, afin que nous puissions les comparer lors d’une mise à jour du plugin au cas où notre table personnalisée aurait besoin d’être mise à jour. Pour ce faire, nous ajoutons simplement cette ligne juste après avoir créé notre table en utilisant le dbDelta
fonction:
add_option( 'prefix_my_plugin_db_version', '1.0' );
Mise à jour du schéma de table
En utilisant le même exemple que ci-dessus, disons pendant le développement, nous changeons d’avis et nous voulons également stocker notre numéro de téléphone client dans notre table. Ce que nous pouvons faire, c’est déclencher une mise à jour du schéma de table lors de la mise à jour de notre plugin. Depuis register_activation_hook
ne sera pas déclenché lors d’une mise à jour du plugin, nous pouvons nous connecter au plugin_loaded
à la place, pour vérifier la version de notre base de données et mettre à jour le schéma de la table si nécessaire.
Tout d’abord, nous ajoutons notre fonction de mise à niveau personnalisée au plugin_loaded
accrocher:
add_action( 'plugin_loaded', 'prefix_update_table' );
Les fonctions réelles doivent faire quelques choses :
- Nous devons obtenir la version de la base de données stockée.
- Comparez-les avec notre version actuelle de la base de données.
- S’il est plus récent, nous exécutons le
dbDelta
fonctionner à nouveau. - Enfin, nous stockons la version mise à jour de la base de données dans la table d’options.
Dans la plupart des cas, nous pouvons réellement réutiliser les prefix_create_table
fonctionnent comme nous l’avons fait ci-dessus, avec quelques modifications mineures :
function prefix_update_table() {
global $prefix_my_db_version;
if ( $prefix_my_db_version != get_option('prefix_my_plugin_db_version' ) {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE my_custom_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
first_name varchar(55) NOT NULL,
last_name varchar(55) NOT NULL,
phone varchar(32) DEFAULT '' NOT NULL, //new column
email varchar(55) NOT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
if ( ! function_exists('dbDelta') ) {
require_once( ABSPATH 'wp-admin/includes/upgrade.php' );
}
dbDelta( $sql );
update_option( 'prefix_my_plugin_db_version', $prefix_my_db_version );
}
}
Notez que nous n’avons pas besoin d’utiliser le ALTER
déclaration, puisque dbDelta
prendra notre instruction SQL, la comparera aux tables existantes et apportera la modification en conséquence. Plutôt pratique !
Conclusion
WordPress ne se limite pas à la création de sites Web simples, car il évolue rapidement vers un cadre d’application à part entière. L’extension de WordPress via des types de publication personnalisés et des taxonomies personnalisées devrait être notre principale priorité. Cependant, lorsque nous avons besoin d’un contrôle plus fin de nos données, il est rassurant de savoir que WordPress lui-même fournit diverses fonctions et classes comme wpdb
pour les développeurs à utiliser. C’est ce qui fait de WordPress une solution mature.
— to www.sitepoint.com