После миграции WordPress чаще всего «ломается» не PHP и не Nginx, а данные: в базе остаются старые URL, абсолютные ссылки в контенте, пути к медиа и настройки плагинов. Ещё один типичный симптом — двойные слеши в адресах (/catalog//item/, /uploads//), которые всплывают из-за неправильной «склейки» путей или кривых значений home/siteurl.
WP-CLI помогает разрулить это быстро и повторяемо: вы делаете бэкап, прогоняете search-replace с --dry-run, точечно исправляете «лишние /», проверяете wp cron и в финале запускаете wp cli diagnose, чтобы поймать проблемы окружения.
Подготовка: где запускать WP-CLI и как не навредить
WP-CLI удобнее запускать по SSH из корня установки WordPress (там, где лежит wp-config.php). Если WordPress стоит в подпапке (например, public_html/site), переходите именно туда.
Два правила, которые реально экономят часы:
- Всегда делайте бэкап базы перед массовым
search-replace. - Сначала делайте прогон с
--dry-runи только потом реальную замену.
Проверьте, что WP-CLI видит ваш сайт и читает настройки:
cd /path/to/wordpress
wp core version
wp option get siteurl
wp option get home
Если команды ругаются на права, окружение или подключение к базе — сначала чините доступ (путь, владелец файлов, права, DB_*), и только потом меняйте URL.
Бэкап базы перед работами
Самый простой дамп через WP-CLI:
wp db export wp-before-migration.sql
Если база большая, проверьте место на диске и квоты. Дальше можно работать спокойнее: любые массовые правки всегда можно откатить.
Смена URL WordPress: быстро и правильно
В WordPress есть два базовых значения: home и siteurl. Обычно при миграции меняются оба. Начните с них:
wp option update home 'https://new.example'
wp option update siteurl 'https://new.example'
На практике этого мало: внутри постов, виджетов, мета-полей, опций темы и плагинов могут быть абсолютные ссылки. Следующий шаг — wp search-replace, который умеет корректно работать с сериализованными данными (важно для WordPress).
WP-CLI search-replace: базовый сценарий после migration
Сначала оцените объём изменений без записи в базу:
wp search-replace 'https://old.example' 'https://new.example' --dry-run
Если на старом сайте одновременно встречались http и https, делайте две отдельные операции (так предсказуемее):
wp search-replace 'http://old.example' 'https://new.example' --dry-run
wp search-replace 'https://old.example' 'https://new.example' --dry-run
Когда цифры в dry-run выглядят адекватно — применяйте реальные замены:
wp search-replace 'http://old.example' 'https://new.example'
wp search-replace 'https://old.example' 'https://new.example'
Если сайт после переноса живёт на другом домене, не забудьте проверить DNS и срок делегирования, чтобы не ловить «плавающие» редиректы и петли. При необходимости поможет регистрация доменов для быстрого управления зоной и переносов.
Ручной поиск/замена в SQL-дампе почти всегда худшая идея: легко сломать сериализацию и получить «странные» падения админки. В этом смысле WP-CLI безопаснее.
Сценарий: сайт переехал в подпапку или из подпапки
Иногда меняется не только домен, но и базовый путь: было https://example.com, стало https://example.com/blog. Тогда обновите home/siteurl и делайте замены точечно:
wp option update home 'https://example.com/blog'
wp option update siteurl 'https://example.com/blog'
wp search-replace 'https://example.com/wp-content/uploads' 'https://example.com/blog/wp-content/uploads' --dry-run
Глобальный replace по https://example.com на https://example.com/blog может неожиданно переписать внешние ссылки и данные плагинов, которые не должны содержать базовый URL. Лучше идти итеративно: проверили — применили — перепроверили.
Если миграцию делаете регулярно и хочется воспроизводимости (снапшоты, отдельные окружения, откаты), удобнее жить на VDS, где вы контролируете версию PHP, окружение CLI и планировщик задач.

Лишний “/” в URL и путях: откуда берётся и как лечить через WP-CLI
Фраза «убрать лишние / после миграции» обычно означает одну из двух проблем:
- Двойные слеши в адресах:
/catalog//item/,/wp-content//uploads/и подобное. - Кривой базовый адрес в настройках: завершающий слеш в
home/siteurlплюс принудительное добавление слеша в теме/плагине даёт «//» при конкатенации.
Проверяем, не кривые ли home/siteurl
Начните с простого: проверьте текущие значения:
wp option get home
wp option get siteurl
Если у вас принято хранить адрес без завершающего слеша — приведите к единому виду:
wp option update home 'https://new.example'
wp option update siteurl 'https://new.example'
Точечный search-replace для двойных слешей без поломки https://
Самая опасная идея — заменить // на / глобально. Это сломает схемы URL и превратит https:// в https:/. Действуйте точечно: исправляйте только те подстроки, которые гарантированно не являются частью схемы.
Сначала оцените наличие проблемы:
wp search-replace '/wp-content//' '/wp-content/' --dry-run
wp search-replace '/uploads//' '/uploads/' --dry-run
wp search-replace '/wp-json//' '/wp-json/' --dry-run
Если dry-run показывает реальные попадания — применяйте:
wp search-replace '/wp-content//' '/wp-content/'
wp search-replace '/uploads//' '/uploads/'
wp search-replace '/wp-json//' '/wp-json/'
Если двойные слеши появляются в ответах сервера, но в базе их почти нет, причина часто не в данных, а в генерации URL: константы WP_HOME/WP_SITEURL, конкатенация путей в теме/плагине, редиректы на уровне веб-сервера или прокси. Но начать всё равно удобно с базы: WP-CLI быстро подтвердит, «зашито» ли это в данных.
GUID: когда «лишний /» там встречается и нужно ли трогать
В таблице постов есть поле GUID. Его часто путают с URL и начинают массово переписывать. В большинстве сценариев GUID — это идентификатор, историческая строка, и менять его без необходимости не стоит.
Если вы не понимаете, зачем трогать GUID — лучше не трогайте. Для «починки ссылок» обычно достаточно заменить URL в контенте и метаданных, а GUID оставить как есть.
Если сомневаетесь, ограничьте замену конкретными таблицами и проверяйте результат по шагам. Список таблиц для ориентира:
wp db tables
Проверяем и чиним wp-cron после переноса
После миграции WordPress нередко перестаёт выполнять фоновые задачи: публикации по расписанию, очистку кеша, рассылки, импорт, обработку очередей. Причины обычно такие: мало трафика (псевдо-cron запускается от посещений), не проходят loopback-запросы, сайт за прокси, или внутренние вызовы упираются в редиректы из-за кривого URL.
Проверка очереди событий
Посмотрите ближайшие задачи:
wp cron event list --fields=hook,next_run,recurrence --format=table
Если список огромный и события копятся, часто видно сотни однотипных задач, которые не исполняются.
Запуск cron вручную
wp cron event run --due-now
Если вы видите ошибки, обычно в тексте явно указан хук или плагин, который падает. Это сильно ускоряет разбор.
Типовой фикс: отключить WP-Cron и повесить системный cron
На продакшене часто отключают встроенный триггер и запускают WP-Cron по расписанию средствами ОС. В wp-config.php добавьте строку PHP:
define('DISABLE_WP_CRON', true);
Дальше добавьте системное задание, например раз в 5 минут. Важно: команда должна выполняться в каталоге WordPress, либо используйте --path.
crontab -e
*/5 * * * * cd /path/to/wordpress && wp cron event run --due-now >/dev/null 2>&1
Если нужно больше практики по планировщику, пригодится материал про cron, crontab и systemd timers.

wp cli diagnose: быстрая диагностика окружения
Команда wp cli diagnose полезна, когда WP-CLI ведёт себя странно: падает на простых операциях, ругается на PHP-модули, не видит сеть, или вы подозреваете, что после переезда веб и CLI работают на разных версиях PHP.
Запуск:
wp cli diagnose
Что обычно смотреть в выводе:
- версию PHP CLI и отличие от PHP-FPM (частая причина «в браузере работает, в CLI нет»);
- наличие расширений (mbstring, curl, openssl и т.д.);
- права на запись в директории проекта,
tmp, домашний каталог пользователя; - лимиты памяти/таймауты при больших заменах.
Если search-replace на большой базе обрывается по памяти, чаще всего проще выполнять замену частями: ограничивать таблицы и проверять результат итеративно.
Контрольный чек-лист после search-replace
После обновления URL и точечной чистки слешей пройдитесь по проверкам — они ловят большинство «плавающих» багов миграции:
- Проверить реальные значения URL:
wp option get home,wp option get siteurl. - Убедиться, что старый домен не остался: повторный
--dry-runдолжен показывать 0 (или почти 0) совпадений. - Пересоздать rewrite-правила (если меняли структуру ссылок):
wp rewrite flush --hard
- Проверить cron:
wp cron event listиwp cron event run --due-now. - Проверить медиа: откройте несколько случайных картинок из старых постов.
- Проверить админку: вход, сохранение записей, редактор, виджеты.
Практический сценарий «в один заход»
Если нужен простой воспроизводимый план для типовой миграции (подставьте свои домены):
cd /path/to/wordpress
wp db export wp-before-migration.sql
wp option update home 'https://new.example'
wp option update siteurl 'https://new.example'
wp search-replace 'http://old.example' 'https://new.example' --dry-run
wp search-replace 'https://old.example' 'https://new.example' --dry-run
wp search-replace 'http://old.example' 'https://new.example'
wp search-replace 'https://old.example' 'https://new.example'
wp search-replace '/uploads//' '/uploads/' --dry-run
wp search-replace '/uploads//' '/uploads/'
wp rewrite flush --hard
wp cron event list --fields=hook,next_run,recurrence --format=table
wp cron event run --due-now
wp cli diagnose
Итоги
WP-CLI — один из самых надёжных инструментов для пост-миграционных работ в WordPress: он помогает безопасно выполнить search-replace (в том числе в сериализованных данных), быстро подтвердить источник «лишних /» и проверить, не умер ли wp-cron. А wp cli diagnose закрывает частую боль, когда «кажется, всё настроено», но CLI и веб живут в разных мирах.
Если кейс нестандартный (мультисайт, переезд в подпапку, много интеграций с абсолютными URL), делайте замену итеративно: сначала dry-run, затем ограниченные правки по таблицам/подстрокам, и только потом финальная проверка.


