Почему импорт из моей базы данных теряет данные текстового виджета?

46

Я создал сайт в WordPress на нашей машине для разработки. В используемой теме есть множество зон виджетов для отображения текста (боковая панель и лицевая страница). Я использовал простые текстовые виджеты во всех этих зонах, чтобы разместить информацию на дисплее.

Когда я перешел на рабочий сайт, я использовал плагин WP-DB-Backup, чтобы сделать снимок базы данных. Затем я отредактировал полученный файл .sql, чтобы обновить все пути к файлам и ссылки на URL-адреса, чтобы они указывали на наш производственный сайт.

После создания базы данных, веб-сайта и копирования всех файлов на рабочий сайт я запускаю файл .sql из командной строки mysql, чтобы импортировать данные в новую базу данных.

Однако, когда я иду на производственную площадку, появляется часть текста, а часть - нет. Когда я заглядываю в раздел виджетов сайта, текстовые виджеты отсутствуют в некоторых зонах виджетов. Текстовые виджеты даже не видны в зоне «Неактивный виджет», их просто нет.

Я даже пытался повторить процесс, используя плагин BackWPup, заметив, что синтаксис SQL отличается, когда он выгружает базу данных.

Почему я теряю данные текстового виджета во время импорта?

Dillie-О
источник
Я немного покопался, и единственное, о чем я могу подумать, - это то, что информация о виджете хранится в таблице wp_options, которая выглядит странным образом для кодирования некоторых ее данных. Я еще не смог попробовать это с другой темой, чтобы посмотреть, связано ли это с темой.
Дилли-О,

Ответы:

44

Вот где ваша проблема:

Затем я отредактировал полученный файл .sql, чтобы обновить все пути к файлам и ссылки на URL-адреса, чтобы они указывали на наш производственный сайт.

Вы не можете сделать это. WordPress хранит много опций как «сериализованные данные», которые содержат как строковое содержимое, так и их длину . Поэтому, когда вы изменяете URL-адрес и изменяется длина, сериализованные данные перестают быть правильными, и PHP отклоняет их.

Долгосрочная проблема заключается в том, что вы делаете это неправильно. Если вы настраиваете сайт разработки, на который будут перенесены данные, то для начала он должен иметь точно такой же URL-адрес, что и ваш рабочий сайт. Вы можете вручную отредактировать файл HOSTS, чтобы присвоить этому производственному домену (например, example.com) другой IP-адрес (например, 127.0.0.1), и, таким образом, «производственный» URL станет сайтом разработки только для вас. Затем вы можете создавать свои данные, ссылки и все остальное, используя этот рабочий URL-адрес, и когда вы переносите данные, ничего в этом не должно быть изменено.

В краткосрочной перспективе, однако, не используйте простой текстовый поиск / замену в файле SQL. Как вы обнаружили, это ломает вещи.

И хотя я не решаюсь это предложить, есть способ изменить код ядра WordPress для обработки этих неработающих сериализаций. Вы должны изменить файл wp-includes / functions.php и изменить функцию Maybe_unserialize () на следующую:

function maybe_unserialize( $original ) {
    if ( is_serialized( $original ) ) {
        $fixed = preg_replace_callback(
            '!(?<=^|;)s:(\d+)(?=:"(.*?)";(?:}|a:|s:|b:|i:|o:|N;))!s',
            'serialize_fix_callback',
            $original );
        return @unserialize( $fixed );
    }
    return $original;
}
function serialize_fix_callback($match) { return 's:' . strlen($match[2]); }  

Это НЕ жизнеспособное долгосрочное решение. Он должен использоваться только для того, чтобы вы могли начать работать прямо сейчас. В долгосрочной перспективе вам нужно исправить процесс разработки, чтобы вам не приходилось делать подобный манипулирование URL-адресами для начала.

эфирное масло
источник
@ Отличный ответ. Быстрый вопрос, повлияет ли изменение не сериализованной таблицы BLOB / текста, например wp_posts, на MySql, на сериализованные данные в wp_post_meta или wp_options? У меня была та же проблема с текстовым виджетом, но я не трогал wp_options, я только изменил wp_posts.
Chris_O
Вау, я никогда не осознавал, что именно так происходит с данными, но это имеет смысл! Большое спасибо!
Dillie-O
4
Еще один обходной путь, который используют некоторые люди, - сделать так, чтобы их система разработки имела доменное имя «example.dev» вместо «example.com». Таким образом, длины не изменяются для строк, когда они перемещают их в производство. Я предпочитаю метод файла HOSTS.
Отто
3
2016 и wordrepss все еще сохраняет сериализованные данные в базе данных. most famous worst codeприз должен смотреть не дальше.
Ejaz
1
БЛАГОДАРЮ ВАС!!! Хороший вопрос и отличный хак. В общем, я получаю этот взлом, чтобы вернуть все данные, а после этого просто обновить существующие настройки снова, и когда удалить этот код, работает отлично.
Ивиян Стефан Стипич
10

Для решения этой проблемы я всегда использую инструмент WordPress Serialized Search & Replace , предоставленный здесь. Он прекрасно работает без каких-либо проблем. Я использовал это в течение длительного времени на всех моих требований миграции сайта. Это действительно решает проблемы с переносом базы данных разработки в производство.

https://interconnectit.com/products/search-and-replace-for-wordpress-databases/

Subharanjan
источник
1
Да, использую этот сценарий в течение многих лет и очень рекомендую его
davemac
Работал для меня большую часть времени. Но на этой неделе , когда я заменил http://localhost/Me/site_nameна http://site.dev(от одного локального хоста на другой) , используя V 3.0.0 я теряю виджетов и меню позиции как ни странно. Так что, возможно, эта проблема также связана с длиной строки.
rhand
Я использовал .. но никогда не сталкивался с этой ситуацией на данный момент. Можете ли вы скачать старую версию этого скрипта и попробовать снова? Попробуйте заменить localhost/Me/site_nameна site.dev.
Субхаранджан
URL изменился (теперь https вместо http): interconnectit.com/products/…
Koryonik
Великолепный сценарий. Я продублировал базу данных MySQL из PHPMyAdmin со старой на новую - без изменения URL-адресов - и перешел в папку нового сайта, где находились свежие WP-файлы (вместе с правильным wp-config.php, с новые учетные данные БД), добавил скрипт и обо всем позаботился. Сериализованные данные обновляются по обычным URL-адресам. Легко и быстро! Настоятельно рекомендуется. Важно: не забудьте удалить скрипт после его использования, так как он имеет доступ к вашей информации БД!
Арахис
7

Ответ Отто точен. Я также обнаружил, что это трудный путь.

Однако мне удалось обойти это, используя классный скрипт на http://spectacu.la/search-and-replace-for-wordpress-databases/

Чтобы перенести свой WordPress и на новое URL / доменное имя, выполните следующие действия:

  1. Возьмите дамп базы данных (например, используя phpmyadmin) существующего WordPress.
  2. Восстановите дамп как есть, (не нужно вносить изменения) в новое местоположение
  3. Разархивируйте скрипт из spectu.la в вашу домашнюю папку WordPress (это не плагин ...)
  4. Запустите скрипт на своем новом сайте, указав в нем свой браузер, например, http: //new-website.url/searchreplacedb.php
  5. Не забудьте удалить скрипт из вашего нового дома WordPress
Йоав Анер
источник
1
Я знаю, что это старое, но где я должен указать новое имя базы данных, если я восстановлю дамп как есть? я не должен по крайней мере поместить новое имя базы данных во второй шаг? Спасибо за эту информацию
andresmijares
Я не уверен, что полностью понимаю ваш вопрос. Восстановление базы данных можно выполнить с помощью таких инструментов, как phpmyadmin, и вы можете дать ей новое имя или использовать старое имя. Сценарий, который я упомянул, просто изменяет текст в базе данных после того, как он уже восстановлен.
Йоав Анер
Привет Йоав, спасибо за ответ, я имею в виду, когда я экспортирую БД, я обычно меняю имя базы данных на новое и меняю ссылки на домен. Сказав это, на втором шаге вы говорите: «Восстановите дамп без изменений», я просто хотел узнать, буквально ли это, или мне нужно хотя бы изменить имя базы данных. Я знаю, что это может быть глупый вопрос, я просто потерян, еще раз спасибо за
ваш
Я не знаю, как вы выгружаете свою базу данных, но если вы используете phpmyadmin 'export', тогда не имеет значения, какое это имя базы данных. Вы можете использовать экспорт и импортировать его обратно в любую другую базу данных. Как правило, что касается пункта 2, я думаю, что можно сменить имя базы данных.
Йоав Анер
2

Оператор переусердствовал, когда выполнял поиск и замену в файле экспорта базы данных, и в итоге изменил вхождения «wp_» в некоторых сериализованных данных. Решение состоит в том, чтобы сделать поиск и замену более экономным, включив обратную черту в регулярное выражение, а затем вручную обновив оставшиеся ключи в базе данных после импорта.

Если вы мигрируете и меняете префикс, и, как более ручной подход, сделайте следующее (это только касается проблем OP и не касается обновления URL сайта)

  1. Сделайте резервную копию и перенесите файл SQL экспорта базы данных в новую среду (в моем примере предполагается имя файла backup_YYYY-MM-DD.sql)
  2. Выполните массовый поиск и замену в файле SQL, чтобы изменить имена таблиц для использования вашего нового префикса (ДО импортирования файла SQL!). Одним из способов сделать это может быть использование однострочного Perl, например: perl -p -i.bak -e "s /` wp_ / `myprefix_ / g" backup_YYYY-MM-DD.sql
  3. Импортируйте ваши данные SQL в базу данных
  4. Обновите все ключи в _options, которые содержат жестко заданный префикс: update myprefix_options set option_name = concat ('myprefix _', substr (option_name, 4)), где option_name наподобие 'wp_%'
  5. Обновите все ключи в _user_meta, которые содержат жестко заданный префикс: update myprefix_usermeta set meta_key = concat ('myprefix _', substr (meta_key, 4)), где meta_key похож на 'wp_%'
Том Оже
источник
0

Я использовал плагин WP Migrate , который заменяет http и патчи папок. Я получил одну проблему при импорте, но решил поставить следующие строки в верхней части сгенерированного SQL:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

Я также попытался с помощью инструмента поиска и замены (v2.1), на который ответил @Yoav, но он все еще ломает мои сериализованные данные.

Рикардо Мартинс
источник
Привет Рикардо, добро пожаловать в ответы на WordPress! Область, в которой вы разместили, зарезервирована для ответов на исходный вопрос. Даже если ваш вопрос связан, вы должны опубликовать его как отдельный вопрос. У вас будет гораздо больше шансов получить ответ таким образом.
Chris_O