Как правильно сменить домен WordPress, ошибка 90% вебмастеров
В Сети куча статей о смене домена WP-сайта, в т.ч. и о переносе WP с локалхоста на сервер, когда девелоперский домен меняется на реальный. И лишь в единицах источников упоминается о том, что бывают сериализованные данные, в которых замена текста first-domain.ru
на second-domain.ru
равнозначна удалению этих данных. Но даже в тех статьях, где упомянута сия оказия (в частности, на Хабре), не указан способ автоматизировать задачу, кроме как выполнить «аккуратную» (читай — ручную) замену. Хочу поделиться своими успехами в автоматизации правильной смены домена у сайта на WordPress.
Коротко суть проблемы. Многие вебмастеры заблуждаются, говоря, что в смене домена WP нет ничего сложного — достаточно найти и заменить в дампе БД (файл sql) старый домен на новый. И они уверены, что правы, потому что делали так, и всё было норм.
А бывает иначе. В БД удобно хранить данные в сериализованном виде, потому что можно записать массив или объект строкой. Вот конкретный пример части сериализованных данных:
s:8:"base_url";s:17:"http://domain.ru/";
Расшифрую выделенное жирным: s
— строковый тип, 17
— число символов, http://domain.ru/
— сами данные. И можно догадаться, что если тут заменить domain
на new-domain
, то получится что-то не то (ведь в строке http://new-domain.ru/
уже не 17, а 21 символ). А точнее, весь массив будет для программы повреждёнными нечитаемыми данными.
Согласен, обычно проблем не возникает, потому что многие разработчики плагинов и тем оформления предпочитают узнавать URL сайта вызовом get_option('siteurl')
и абсолютный путь — из константы ABSPATH
. Но мир ведь не без гениев! Вот конкретный пример. У меня сейчас сайт на переносе, и длина его нового доменного имени отличается от старого. Использую такое регулярное выражение в notepad++ для поиска по дампу БД интересующих меня данных:
s:[\d]+:"[^"]*domain\.ru
Где вместо domain.ru
подразумевается конкретный домен.
И я вижу 90 вхождений! Т.е. все эти данные могли бы потеряться, воспользуйся я простой заменой текста. Для грамотной автоматической замены я написал такой скрипт:
$delta = 1; $s = file_get_contents( '1.sql' ); $s = preg_replace_callback( '~s:([\d]+):"([^"]*)first\.ru~', function ($m) { global $delta; return 's:'.( $m[1]+$delta ).':"'.$m[2].'second.ru'; }, $s ); file_put_contents( '2.sql', $s );
В коде гипотетический домен first.ru
заменяется на second.ru
. И т.к. разница в их длинах составляет 1 символ, то $delta = 1
(если новый домен у вас будет короче, то разница будет отрицательной). Скрипт читает файл 1.sql
и записывает результат в 2.sql
. В результате будет заменён не только домен, но и скорректировано значение длины строки, в которой этот домен упомянут.
Кстати, перед заменой обратите внимание, участвует ли домен в абсолютном пути на старом и новом сервере. Иногда бывает, что на старом сервере домен был в абсолютном пути, например:
/home/httpd/vhosts/domen.ru/httpdocs
А на новом сервере домена в пути нет (реальный пример на популярном хостинге СпайсВеб):
/home/m/mebelmakm/maks/public_html
Из примера ясно, что процедуру замены домена в дампе БД надо проводить в 4 этапа:
- найти и заменить старый абсолютный путь на новый с учётом возможного присутствия его в сериализованных данных (т.е. моим скриптом, например);
- моим скриптом заменить старое доменное имя на новое;
- заменить в notepad++ оставшиеся вхождения абсолютного пути (которые в обычных данных — их скрипт не затронул);
- заменить в notepad++ оставшиеся вхождения старого домена.
По идее, можно допилить мой скрипт, сделать из него плагин WP, который будет принимать на входе строки: старый путь на сервере, новый путь, старый домен, новый домен — и на выходе выгружать дамп БД, готовый для загрузки на новый сервер. Только мне приятней, если юзер обращается за переносом WP сразу ко мне, а не после того, как он своими силами и самопальными плагинами уже поломал свой сайт.
Да, когда закончили с дампом БД, надо пройтись регуляркой и обычным поиском по файлам движка (темы оформления, плагины и всё остальное до кучи) — там тоже иногда можно найти вхождения абсолютного пути и домена, иногда даже в сериализованном виде. Пусть и ламер тот кодер, который пишет таким образом темы и плагины, но при переносе WP именно вы отвечаете за дальнейшую работоспособность сайта и должны быть готовы к любому маразму.
Ну, а остальные сведения о смене домена и переносе WP очевидны и описаны в сотнях статей даже на кулинарных сайтах домохозяек в специальной рубрике по обмену постами.
3 ответа к “Как правильно сменить домен WordPress, ошибка 90% вебмастеров”
Перенос осуществить не столько сложно, сколько нужно делать это внимательно.
Над плагином думал, и примерно те же выводы сделал. Нельзя заранее предсказать, кто и как решит сохранять домен/пути. Стандартная сериализация хорошо, но есть ещё json_encode (не встречал, но почему бы и нет?), зипование + base64, да и ещё фиг знает, что.
В простейшем случае в 2 этапа колдую над данными:
1. замена старых серверный путей новыми;
2. замена старого домена новым.
По аналогии с имеющимся кодом, можно дополнить скрипт, чтобы сперва пути заменял, а после — домены.
И ещё, можно ввести пару переменных + дельту на автовычисление подвесить:
$old_domain = 'first.ru'; $new_domain = 'second.ru'; $delta = strlen($new_domain) - strlen($old_domain);
Остаётся открытым лишь вопрос работы с puny-доменами, .рф иже с ними. Но тут проще сразу к знающему обратиться, чем запороть дамп и обратиться после.
Да, внимательность важна. Потому переносы планирую на утро — голова свежая и трафик минимальный. Про json_encode не думал. По идее, с ним проще, чем serialize — та же возможность передать разнотипные данные строкой, но нет заморочки с фиксированными длинами.
А про puny думал, но забыл. Они, действительно, в серверных путях обязательно XN, а в текстах можно и РФ. Короче, либерализацией национальных символов только больше всё запутали. Latinitsa norm!
Для жителей этой страны было вообще шикарно: смесь букв/цифр(точка)буквы = домен. Сейчас же учитывать нужно и puny в доменах, и QP в путях. Весело, в общем. Маркетологи заскучать не дают)