Scène classique : vous avez fini la refonte d'un site WordPress en
staging (https://staging.exemple.fr), il faut le pousser en production
(https://www.exemple.fr). Vous exportez la base, vous remplacez l'ancienne URL
par la nouvelle avec un sed bien rude, vous ré-importez. Et là, les widgets
Elementor disparaissent, les options de thème ne sauvegardent plus, certains champs ACF
sont vides. Bienvenue dans l'enfer des données sérialisées PHP.
Le piège invisible : PHP serialize()
WordPress stocke beaucoup de choses sous forme d'arrays ou d'objets PHP sérialisés dans
wp_options (option_value), wp_postmeta (meta_value),
wp_usermeta, et les tables custom de la plupart des plugins. La sérialisation
encode la longueur exacte de chaque chaîne de caractères. Exemple
concret :
a:1:{s:8:"site_url";s:27:"https://staging.exemple.fr";}
Le s:27 signifie : "chaîne de 27 caractères". Si vous remplacez bêtement
https://staging.exemple.fr (27 car.) par https://www.exemple.fr
(23 car.) avec un UPDATE SQL ou un sed sur le dump, vous obtenez :
a:1:{s:8:"site_url";s:27:"https://www.exemple.fr";} ← compteur cassé
PHP n'arrive plus à dé-sérialiser ce blob. unserialize() renvoie
false, le widget affiche du vide, le plugin pense que l'option n'existe pas,
WordPress retombe sur la valeur par défaut. Le pire ? Aucune erreur visible.
Vos visiteurs voient un site qui marche à 80 %, et vous passez trois jours à chercher.
Pourquoi WP-CLI search-replace est la bonne réponse
La commande wp search-replace de WP-CLI fait ce qu'il faut : elle
dé-sérialise chaque valeur, applique le remplacement à l'intérieur des chaînes,
re-sérialise proprement avec le bon compteur de longueur. Idem pour les objets PHP, les
arrays imbriqués, et même les doubles sérialisations qu'on trouve parfois.
Sauf que. WP-CLI exige un accès SSH, exige PHP en ligne de commande, et tous les hébergements mutualisés français ne le proposent pas. Pour les utilisateurs qui n'ont qu'un cPanel et un phpMyAdmin, le module Search & Replace d'Alesta AI fait exactement le même travail, depuis l'interface admin WordPress.
Ce que fait le module Search & Replace d'Alesta AI
Architecture en trois étapes, qu'on a piochée chez les outils de référence du marché et adaptée pour rester compatible PHP 7.4 :
- Détection des tables et colonnes texte : on parcourt
information_schemapour repérer les colonnestext,longtext,varcharsusceptibles de contenir des URLs ou des données sérialisées. - Traitement par lots : on lit 500 lignes à la fois, on désérialise
chaque
meta_valueouoption_valueavec unmaybe_unserialize()récursif, on remplace, on re-sérialise, onUPDATEuniquement les lignes qui ont changé. - Mode dry-run obligatoire : avant tout remplacement réel, le module affiche combien d'occurrences trouvées dans combien de lignes dans combien de tables. Aucune écriture en BDD. Vous validez, et seulement après vous lancez l'apply.
La règle d'or des migrations WordPress : on ne fait jamais de search-replace direct en SQL. Jamais. Même si "c'est juste une petite chaîne".
Cas d'usage 1 — Migration staging → production
Le cas le plus courant. Vous avez bossé sur https://staging.exemple.fr, vous
voulez pousser sur https://www.exemple.fr. Procédure :
- Cloner la BDD staging vers la production (export SQL + import).
- Activer le module Search & Replace, mode dry-run, chercher
https://staging.exemple.fr, remplacer parhttps://www.exemple.fr. - Vérifier le rapport : en général 1 200 à 3 000 occurrences sur un site standard (options, postmeta Elementor, ACF, customizer).
- Lancer l'apply. Le module met à jour, garde un historique des 5 dernières opérations avec compteur de lignes touchées.
Cas d'usage 2 — Passage en HTTPS
Vous venez d'installer un certificat SSL gratuit (Let's Encrypt). Tout votre site est en
http:// en dur dans les widgets, dans les sliders, dans les images de
background CSS Elementor. Même opération : dry-run sur
http://exemple.fr → https://exemple.fr, validation,
apply. Compter ~5 000 occurrences sur un site e-commerce moyen.
Cas d'usage 3 — Ajout du préfixe www
Subtil : vous voulez passer de https://exemple.fr à
https://www.exemple.fr. C'est exactement le scénario où on a, dans Alesta AI
v1.3.4, chaîné automatiquement le module WWW (qui réécrit
.htaccess) avec Search & Replace (qui met à jour la BDD). Avant
v1.3.4 : les utilisateurs cochaient "ajouter le www" et leur site cassait à moitié parce
que les vieilles URLs restaient en BDD. Maintenant, les deux opérations se font dans la
même transaction : le .htaccess n'est mis à jour que si le
search-replace est passé.
Ce qu'il ne faut pas faire (la liste)
- Ne pas faire
UPDATE wp_options SET option_value = REPLACE(option_value, 'ancien', 'nouveau'). Vous corromprez tout ce qui est sérialisé. - Ne pas faire un
sed -isur un dump SQL. Même problème, même résultat. - Ne pas faire de search-replace sur des sites multilingues avant d'avoir lu la documentation de votre plugin de traduction (WPML/Polylang stockent des relations dans des tables custom avec leurs propres règles).
- Toujours sauvegarder la BDD avant. Toujours. Le module Alesta crée un
export
.sql.gzautomatique avant chaque apply, mais une sauvegarde externe ne fait jamais de mal.
Combien de temps ?
Sur une base de 1 000 articles + 50 pages Elementor + WooCommerce avec 500 produits, le dry-run prend ~12 secondes, l'apply ~40 secondes. Sur une base à 50 000 lignes d'options et postmeta cumulées, comptez 2 à 3 minutes. Le module montre une barre de progression et un compteur live des tables traitées.