WP-CLI pour ceux qui vivent dans le terminal
Commandes WP-CLI pour migrations WordPress, sauvegardes, accès verrouillés, mises à jour des plugins et du core, SSH distant et search-replace sûr.
WP-CLI est l’interface en ligne de commande d’une installation WordPress. Elle épargne des clics, mais la véritable raison de l’apprendre tient à l’ensemble des tâches pour lesquelles le tableau de bord n’offre aucun écran : réécrire des données d’options sérialisées lors d’un changement de domaine, exécuter du PHP arbitraire sur un site en production, ou mettre à jour dix installations depuis une seule invite.
La plupart des gens la découvrent en situation d’urgence. Une mise à jour d’extension met l’administration hors service, le tableau de bord ne se charge plus, et FTP couplé à phpMyAdmin devient soudain la seule porte d’entrée. Cette voie fonctionne, mais elle est lente et demande un certain sang-froid.
Cet article est organisé par tâche, non par espace de noms. Chaque section présente une opération pénible ou impossible depuis le tableau de bord, suivie de la commande qui l’accomplit et des options qui la rendent sûre.
Points clés à retenir
wp search-replacedésérialise les données PHP, applique le remplacement, puis resérialise — c’est pourquoi la commande peut réécrire des réglages de widgets et des options d’extensions qu’unREPLACE()SQL brut corromprait.- Exécutez toujours un remplacement avec
--dry-rund’abord, puis relancez la commande identique sans l’option. - Excluez la colonne
guidavec--skip-columns=guid, car les lecteurs de flux s’appuient sur le guid d’un article pour déterminer s’ils l’ont déjà affiché. --ssh=[<scheme>:][<user>@]<host>[:<port>][<path>]relaie une commande vers une installation distante, et la machine distante doit disposer de sa propre copie de WP-CLI accessible viawp.- Aucune de ces commandes ne demande de confirmation et aucune ne peut être annulée :
wp db exportpasse donc en premier.
Ces commandes s’exécutent immédiatement
Il n’y a ni boîte de dialogue de confirmation, ni écran de prévisualisation, ni annulation. wp search-replace écrit dans chaque ligne correspondante dès que vous appuyez sur Entrée. wp plugin deactivate --all désactive tout sur un site de production aussi volontiers que sur un portable. Votre seul recours est l’export de base de données réalisé au préalable : faites-en un.
Comment changer de domaine sans casser les données sérialisées ?
wp search-replace est l’outil approprié pour un changement de domaine : il lit correctement le PHP sérialisé et laisse les clés primaires intactes, deux choses dont un simple rechercher-remplacer SQL est incapable. La raison tient au format de stockage : la fonction serialize() de PHP enregistre une chaîne sous la forme de sa longueur en octets suivie de la chaîne elle-même.
a:1:{s:3:"url";s:27:"https://staging.example.com";}
Un UPDATE ... REPLACE() SQL aveugle réécrit l’URL en https://example.com et laisse le 27 inchangé. La longueur déclarée ne correspond plus à la charge utile, PHP ne peut plus désérialiser la valeur, et le widget ou l’option d’extension qui y résidait est silencieusement réduit à néant. WP-CLI désérialise la structure, effectue le remplacement à l’intérieur, puis resérialise avec les bonnes longueurs.
Procédez par paliers, en trois étapes :
# 1. report what would change; writes nothing
wp search-replace 'https://staging.example.com' 'https://example.com' \
--skip-columns=guid --dry-run
# 2. optional: write the result to a SQL file instead of the database
wp search-replace 'https://staging.example.com' 'https://example.com' \
--skip-columns=guid --export=migration.sql
# 3. apply it
wp search-replace 'https://staging.example.com' 'https://example.com' \
--skip-columns=guid
--dry-run exécute l’intégralité du traitement et affiche le rapport, puis jette les modifications. --export envoie le résultat dans un fichier SQL et laisse la base de données de production intacte, ce qui vous permet de lire le diff ou de l’appliquer ailleurs. Ignorez la colonne guid, car WordPress considère le guid d’un article comme immuable pour toute la durée de vie de celui-ci : le modifier peut amener les lecteurs de flux à présenter tout votre historique comme du contenu neuf.
Pour des données imbriquées récalcitrantes, ajoutez --precise. Par défaut, la commande utilise des requêtes SQL rapides et bascule automatiquement vers PHP pour les colonnes contenant des données sérialisées ; --precise force le recours à PHP pour chaque colonne, ce qui est plus lent mais plus fiable face à des structures sérialisées complexes. Le mode expression régulière est lui aussi nettement plus lent : n’y recourez que lorsqu’une chaîne littérale ne suffit pas.
Comment mettre à jour les extensions et le cœur sur plusieurs sites ?
Une seule commande met à jour tout ce pour quoi une mise à jour est disponible, sans pagination du tableau de bord ni cases à cocher extension par extension :
wp plugin update --all
wp core update
wp core update-db
wp core update-db exécute la routine de mise à jour de la base de données de WordPress, c’est-à-dire l’étape que le tableau de bord effectue pour vous sur l’écran de mise à niveau après une mise à jour du cœur. Lancez-la après wp core update afin que la mise à niveau aille à son terme au lieu de rester à mi-chemin.
Combinée aux alias abordés plus bas, la même ligne devient wp @all plugin update --all et s’applique successivement à chaque installation que vous maintenez.
Exporter avant, importer après
wp db export délègue à mysqldump et récupère l’hôte, le nom, l’utilisateur et le mot de passe de la base depuis wp-config.php : vous n’avez donc jamais à saisir d’identifiants de connexion. Donnez-lui un nom de fichier explicite ; à défaut, il écrira {dbname}-{Y-m-d}-{random-hash}.sql.
wp db export backup-$(date +%Y%m%d-%H%M%S).sql
La restauration en est l’image inversée :
wp db import backup-20250413-141055.sql
wp db import accepte soit un nom de fichier, soit une entrée acheminée par tube (pipe), ce qui vous permet d’envoyer un export directement d’un hôte à un autre via ssh. Pour une stratégie plus pérenne qu’un simple dump avant une opération risquée, les articles d’OpenReplay consacrés aux sauvegardes WordPress traitent de la planification et du stockage hors site.
Comment reprendre la main sur un site dont vous êtes exclu ?
Trois commandes couvrent la quasi-totalité des cas de verrouillage, dans l’ordre où vous les exécuteriez sous pression. Créer un nouvel administrateur, réinitialiser le mot de passe d’un utilisateur existant, ou écarter complètement les extensions :
wp user create ops ops@example.com --role=administrator
wp user reset-password admin --show-password --skip-email
wp plugin deactivate --all
wp user reset-password génère un nouveau mot de passe ; --show-password l’affiche dans le terminal et --skip-email empêche l’envoi de la notification vers une boîte de réception que vous ne contrôlez peut-être pas. wp plugin deactivate accepte --all pour tout désactiver, ainsi que --exclude=<name> pour maintenir active une liste séparée par des virgules.
Lorsque c’est une erreur fatale dans une extension qui a cassé l’administration, WP-CLI peut échouer à s’amorcer pour la même raison que le site. Le paramètre global --skip-plugins empêche le chargement de toutes les extensions, ou d’une liste nommée, pour la durée de la commande :
wp plugin deactivate broken-plugin --skip-plugins
Ignorer une extension ne modifie pas l’état enregistré : une extension ainsi ignorée est toujours signalée comme active. Cela vous offre seulement un amorçage fonctionnel pour que la désactivation puisse s’exécuter. Cela n’aide pas non plus lorsque le code fautif se trouve dans une mu-plugin, car WP-CLI charge les mu-plugins dans tous les cas. C’est à ce moment-là que la plupart des mainteneurs ont besoin de WP-CLI pour la première fois, et c’est plus rapide que d’ouvrir un client FTP et de renommer des répertoires d’extensions. Une fois l’administration rétablie, le volet diagnostic de l’opération est traité dans l’article d’OpenReplay sur l’écran blanc de la mort de WordPress.
Exécuter du PHP ponctuel avec wp eval
wp eval exécute du PHP arbitraire sur une installation WordPress entièrement chargée. Il n’existe aucun équivalent dans le tableau de bord, et c’est précisément l’intérêt : toute fonction déclarée par une extension, toute option, toute requête devient une commande d’une seule ligne.
wp eval 'echo get_option( "siteurl" );'
wp eval 'echo count( get_users( [ "role" => "administrator" ] ) );'
Tout ce qui est plus long a sa place dans un fichier. wp eval-file prend le chemin d’un fichier PHP, transmet au script tous les arguments positionnels supplémentaires sous la forme de $args, et ignore totalement l’amorçage de WordPress si vous passez --skip-wordpress. Votre code s’exécute à l’intérieur d’une méthode : chaque variable globale que vous manipulez nécessite donc sa propre déclaration global.
Il n’existe pas de simulation à blanc pour wp eval. Tout ce que le script écrit, il l’écrit pour de bon. C’est l’argument le plus clair en faveur de l’export.
Comment exécuter WP-CLI sur un hôte distant ?
C’est ici que l’outil cesse d’être un simple confort. Le paramètre global --ssh de WP-CLI prend la forme --ssh=[<scheme>:][<user>@]<host>[:<port>][<path>] et fonctionne en transmettant votre commande au binaire ssh, qui la remet au WP-CLI présent à l’autre bout.
wp --ssh=dev_user@example.com:2222~/webapps/production plugin list
| Composant | Valeur ici | Valeur par défaut si omis |
|---|---|---|
| scheme | (omis) | ssh |
| user | dev_user | votre utilisateur système courant |
| host | example.com | obligatoire |
| port | 2222 | 22 |
| path | ~/webapps/production | le répertoire personnel de l’utilisateur ssh |
Le chemin ne prend aucun séparateur. Écrivez-le directement après le port, ou directement après l’hôte si vous avez omis le port, et faites-le commencer par / ou ~. Outre ssh, la référence de configuration du handbook documente vagrant, docker, docker-compose et docker-compose-run. Ce dernier démarre un conteneur neuf avec docker-compose run plutôt que d’utiliser un conteneur déjà actif.
Un prérequis est absolu : le serveur distant doit disposer de son propre WP-CLI, accessible sous le nom wp. Un wp qui fonctionne lorsque vous vous connectez manuellement peut tout de même renvoyer une erreur « command not found » via --ssh, parce que le shell qui exécute une commande distante ne construit pas le même $PATH. La plupart des distributions placent, en haut de ~/.bashrc, une garde qui interrompt l’exécution lorsque le shell n’est pas interactif : toute ligne PATH située en dessous n’est donc jamais exécutée ; dans ce cas de figure, zsh lit ~/.zshenv plutôt que ~/.zshrc. La solution consiste à définir explicitement $PATH côté distant.
Saisir cette chaîne deux fois suffit à convaincre. Enregistrez des alias dans le wp-cli.yml de votre projet ou dans votre ~/.wp-cli/config.yml global :
@prod:
ssh: deploy@example.com~/webapps/production
@stage:
ssh: deploy@staging.example.com~/webapps/staging
@all:
- @prod
- @stage
wp @prod plugin update --all
wp @all core check-update
Un groupe d’alias exécute une seule invocation sur plusieurs installations : c’est toute la différence entre maintenir dix sites clients et se connecter à dix tableaux de bord. Pour une installation locale qui ne se trouve pas dans votre répertoire courant, le paramètre global --path indique à WP-CLI où résident les fichiers WordPress :
wp --path=/var/www/example.com/htdocs plugin update --all
Pour aller plus loin
L’idée à retenir avant tout : WP-CLI comprend les structures de données de WordPress, ce qui n’est le cas ni de mysql ni de phpMyAdmin — raison pour laquelle un changement de domaine relève de wp search-replace et de rien d’autre. Prenez la prochaine migration que vous avez planifiée, rédigez la ligne avec --dry-run, lisez le rapport, et exécutez wp db export avant de retirer l’option. Tout ce qui précède est irréversible dès l’instant où vous appuyez sur Entrée.
FAQ
wp search-replace met-il à jour tous les sites d'un réseau multisite ?
Non. La commande agit sur les tables que WordPress enregistre lui-même : en multisite, vous n'obtenez donc que les tables du site courant, sauf si vous ajoutez --network. Pour atteindre toutes les tables de la base, quel que soit leur préfixe et que WordPress les connaisse ou non, utilisez --all-tables, qui prime sur --network et sur --all-tables-with-prefix. Sur un réseau, ajoutez également --url afin que WP-CLI s'amorce sur le bon site.
Pourquoi WP-CLI refuse-t-il de s'exécuter en tant que root ?
WP-CLI s'interrompt avec une erreur YIKES lorsqu'il détecte l'utilisateur root. Tout ce qui se trouve dans l'installation, y compris les extensions et thèmes que vous n'avez pas écrits, hériterait de la portée de root sur le serveur : un seul fragment de code malveillant pourrait ainsi s'emparer de toute la machine. L'option --allow-root contourne cette vérification, et les conteneurs s'exécutant en tant que root en ont souvent besoin, mais le projet la déconseille. Exécutez plutôt les commandes avec l'utilisateur système propriétaire des fichiers WordPress.
Que signifie l'erreur « This does not seem to be a WordPress installation » ?
WP-CLI n'a trouvé aucun fichier du cœur de WordPress à l'endroit où il a cherché, et ne s'est donc jamais amorcé. Exécutez la commande depuis le répertoire contenant wp-admin, wp-content et wp-includes, ou pointez-la vers l'installation à l'aide du paramètre global --path. Passez la valeur avec le signe égal, --path=/var/www/html, car un argument séparé par une espace laisse l'option sans valeur et la même erreur se reproduit.
WP-CLI fonctionne-t-il sous Windows ?
WP-CLI est conçu pour un environnement de type UNIX tel que Linux, macOS, FreeBSD ou Cygwin, et n'est que partiellement pris en charge sous Windows lui-même : WSL ou Cygwin constitue donc la voie fiable sur une machine Windows. Il requiert par ailleurs WordPress 4.9 ou une version ultérieure, et toute version antérieure à la version courante de WordPress risque de ne pas fonctionner pleinement.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k