Как правильно менять домен сайта на WordPress

Один важный нюанс, благодаря которому сайт не сломается.

Недавно обнаружил, что в интернете нет нормальной инструкции по смене адреса домена сайтов на движке WordPress. Большинство советов сводятся к четырём запросам в базе данных через phpmyadmin или любой другой похожий инструмент:

UPDATE wp_options SET option_value = REPLACE(option_value, 'старый_адрес', 'новый_адрес') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts SET post_content = REPLACE (post_content, 'старый_адрес', 'новый_адрес');
UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'старый_адрес','новый_адрес');
UPDATE wp_posts SET guid = REPLACE (guid, 'старый_адрес', 'новый_адрес');

Это неправильно. Более того, подобные манипуляции с заменой сломают сайт, потому что эти советчики не знают, как устроена база WP и какого вида данные там хранятся.

Суть проблемы

Часть опций плагинов и самого движка сайта хранится в сериализированном виде. Вот, например, так выглядит содержимое строки wpseo-gsc, которую создаёт мега-популярный плагин SEO by Yoast:

a:1:{s:7:"profile";s:15:"https://tx8.ru/";}

У сериализации есть уязвимое место — для каждого значения требуется указать его длину (обратите внимание на «s:15:» перед доменным именем).

С помощью сериализации упаковывают массивы и прочие объекты в текстовые строки, из чего и состоит база данных сайта на Вордпрессе.

Замена одной буквы в домене может прокатить, но при переходе с http на https сайт начнёт сбоить. Настройки некоторых плагинов и тем не перенесутся, потому что станут ошибочными.

Странно, что некорректной заменой грешат плагины автозамены и переноса сайта на новый домен. Не могу указать проблемные, потому что ситуация постоянно меняется: авторы узнают о сериализации и переписывают свои детища, но появляются новые с некорректными функциями. Знаю, что WP Migrate DB и Duplicator работают нормально и корректно переносят сайт. Однако есть универсальное решение, работающее предельно корректно.

Решение: Search Replace DB

Скрипт Search Replace DB специально разработан для правильной замены значений в базе WP, не повреждающий сериализованные строки.

Установка скрипта

Если руки прямые, с установкой проблем не будет.

1. Качайте архив со скриптом с сайта выше (нужно ввести адрес почты, чтобы прислали ссылку на свежую версию).

2. В каталоге с установленным сайтом создайте подкаталог со случайным именем.

3. Распакуйте туда содержимое архива со скриптом. Достаточно файлов index.php и srdb.class.php. Для любителей запускать скрипты из консоли есть srdb.cli.php.

4. Зайдите по ссылке http(s)//домен.сайта/каталог_скрипта/index.php.

5. Откроется страница Search Replace DB. Если не мудрили с конфигурацией сайта, скрипт сам узнает логин и пароль для доступа к БД, в противном случае нужно заполнить поля в разделе «database».

Скрипт Database Search and Replace

Скрипт Database Search and Replace

Теперь можно приступить к замене.

После замены не забудьте удалить скрипт. Для этого есть кнопка «delete me».

Также помните о том, что в *.php, *.js и *.css файлах тоже может упоминаться домен сайта. Например, часто указывают в темах оформления, сделанных на заказ для одного сайта. Для выявления таких строк я пользуюсь текстовым поиском в редакторе VS Code — там найденное отображается удобным списком, легко делать ручные правки.

Смена домена

Это самое простое. В поле «replace» нужно ввести старое доменное имя, в «with» — новое, затем нажать «Live run». И ждать.

Если появляется ошибка AJAX, скорее всего в настройках интерпретатора PHP задано слишком короткое время выполнения скрипта (значение max_execution_time в php.ini). Менять параметр не обязательно, достаточно выбрать режим «select tables» вместо «all tables» и выполнять замену по одной таблице за раз.

Переход на HTTPS

Если вы не меняете домен, а переводите сайт на защищённый протокол HTTPS, просто сделайте поиск и замену по полному адресу сайта, включая протокол — «http://имя_домена» на «https://имя_домена».

Переход на HTTPS и смена домена

Одновременная смена доменного имени и переход на защищённый протокол — ситуация редкая, но случается. Рекомендую выполнять поэтапную замену.

  1. Сначала «имя_домена» на «новое_имя_домена», чтобы абсолютно все ссылки изменились.
  2. Затем «http://новое_имя_домена» на «https://новое_имя_домена», чтобы те ссылки, что были с указанием протокола, стали исправленными.

Также рекомендую поставить плагин SSL Insecure Content Fixer, который будет редиректить все http ссылки на защищённый протокол, а также ограничит админку сайта (/wp-admin/) одной HTTPS версией.

Переход на другой хостинг

В базе данных, помимо доменного имени и ссылок, хранится внутренний адрес сайта относительно файловой системы сервера. Например, сайт находился в каталоге «/var/www/tx8.ru», а очутился в «/home/www/sites/tx8-ru». Или, если вы перенесли сайт на локальную машину с Windows, «C:\WWW\tx8.ru».

Чем это чревато? Если плагинов нет, то ничем. Но редко какой сайт на WordPress обходится без установленных плагинов. И их авторы очень любят сохранять внутренние пути к файлам. Это неправильно, потому что ядро WP может подставлять правильные пути «на лету», но так уж получилось — качество кода многих «творений» в каталоге WP ниже всякой критики.

Проблема путей файлов в базе данных попортила мне жизнь в 2012 году, когда часто переносил свой блог glashkoff.com с одного shared-хостинга на другой в поисках лучшего. Ломались плагины резервного копирования, внутренние редакторы кода и другие, умеющие сохранять свой лог в отдельный файл. 

Если при переносе сайта на другую машину ломаются плагины, и отказаться от них невозможно — меняйте путь в базе данных. Чтобы узнать, где находится корневой каталог, создайте файл с произвольным именем и расширением «.php» в корне сайта с таким содержимым:

<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=Windows-1251">
<title>Путь к текущему каталогу от корня</title>
</head>
<body>
<?php
echo $_SERVER['DOCUMENT_ROOT'];
echo '/';
?>
</body>
</html>

При открытии файла в браузере вы увидите искомое.

Бонус: переезд на локальную машину

Это не про скрипт замены в базе данных WordPress, но может пригодиться. Про пути в файловой системе я рассказал выше, Есть ещё один способ быстро открыть сайт на новом домене и(или) машине. Это пригодится в том случае, если нужно запустить на локальной машине сайт, сидящий на протоколе HTTPS. Утягивать с сервера в интернете сертификаты и настраивать софт на компьютере — дело долгое, можно поступить иначе — указать движку WP новый домен.

Ссылки это не исправит, но сайт начнёт открываться, можно будет зайти в админку и быстро что-то протестировать или поправить.

Просто добавьте в wp-config.php сайта, скопированного на локальный сервер, над строкой «/* That’s all, stop editing! Happy blogging. */»:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('FORCE_SSL_ADMIN', false);
define('FORCE_SSL_LOGIN', false);
define('WP_SITEURL','http://адрес_сайта');
define('WP_HOME','http://адрес_сайта');

Первые три опции включат невидимый режим отладки. Ошибки движка WP будут сохраняться в файл «/wp-content/debug.log», что облегчит выявление проблем (вы ведь для этого копируете сайт себе на ПК?).

Опции «FORCE_SSL…» отключат принудительное перенаправление на HTTPS версию админок, ведь их на локальной машине не будет.

Последние две опции укажут, что нужно использовать протокол http.

Итог

Возможно, кому-то плагины вроде Duplicator покажутся проще. Каждому своё. Я привык делать замену в базе через скрипт, потому что он даёт больше контроля и гибкости.