为什么我的数据库导入丢失了文本小部件数据?


46

我已经在我们的开发机器上用WordPress创建了一个站点。在主题中,我们使用了许多小部件区域来显示文本(侧栏和首页)。我在所有这些区域中都使用了简单的Text小部件来放置我们的显示信息。

将站点迁移到生产环境时,我使用WP-DB-Backup插件对数据库进行快照。然后,我编辑了生成的.sql文件,以更新所有文件路径和URL引用以指向我们的生产站点。

创建数据库,网站并将所有文件复制到生产站点之后,我从mysql命令提示符下运行.sql文件,以将数据导入新数据库。

但是,当我转到生产站点时,会显示一些文本,而有些则没有。当我查看站点的窗口小部件部分时,某些窗口小部件区域中缺少文本窗口小部件。文本窗口小部件甚至在“非活动窗口小部件”区域中都不可见,它们根本不在那儿。

我什至尝试使用BackWPup插件重复该过程,并注意到在转储数据库时SQL语法是不同的。

为什么在导入期间丢失文本小部件数据?


我一直在进行一些挖掘,我唯一能想到的是,小部件信息存储在wp_options表中,该表看起来以一种奇怪的方式对其数据进行编码。我还无法尝试使用其他主题来查看它是否与主题相关。
Dillie-O 2011年

Answers:


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调整。


@Otto很好的答案。很快的问题,在MySql外部修改未序列化的blob /文本表(如wp_posts)会影响wp_post_meta或wp_options中的任何序列化数据吗?我在文本小部件上遇到了同样的问题,但是我没有碰过wp_options,而只是修改了wp_posts。
Chris_O 2011年

哇,我从来没有意识到这就是数据所发生的一切,但是完全有道理!非常感谢!
Dillie-O 2011年

4
某些人使用的另一种解决方法是使他们的开发系统的域名为“ example.dev”,而不是“ example.com”。这样,将字符串移至生产环境时,字符串的长度就不会改变。我更喜欢HOSTS文件方法。
奥托

3
2016年,wordrepss仍将序列化数据保存在数据库中。most famous worst code奖项不必再看了。
Ejaz

1
谢谢!!!好点和伟大的hack。总的来说,我得到了这个技巧,可以返回所有数据,之后,只需再次更新现有设置,然后删除此代码即可完美工作。
Ivijan StefanStipić17年

10

为了解决此问题,我始终使用此处提供的WordPress序列化搜索和替换工具。它工作正常,没有任何问题。我已经在所有网站迁移要求上使用了很长时间。这确实解决了将开发数据库迁移到生产中的问题。

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


1
是的,多年来一直使用此脚本,并强烈推荐它
davemac

大多数时候为我工作。但是本周,当我更换http://localhost/Me/site_namehttp://site.dev(从一个本地主机到另一个)用V 3.0.0我也失去了我的小部件和菜单位置奇怪的。因此,也许这个问题也与字符串长度有关。
rhand 2014年

我一直在使用..但到目前为止从未遇到过这种情况。您可以下载此脚本的旧版本,然后重试一次。尝试替换localhost/Me/site_namesite.dev
Subharanjan 2014年

网址已变更(现HTTPS,而不是HTTP):interconnectit.com/products/...
Koryonik

华丽的脚本。我将PHPMyAdmin的MySQL数据库从旧数据库复制到了新数据库-完全不更改URL,然后转到了新站点的文件夹,其中是新的WP文件(连同正确的wp-config.php一起,新的数据库凭据),添加了脚本,并完成了所有工作。序列化的数据沿正常的URL更新。简单快捷!强烈推荐。重要提示:使用脚本后,请不要忘记删除它,因为它可以访问您的数据库详细信息!
花生'18

7

奥托的答案很明确。我也很难发现这一点。

但是,我设法使用http://spectacu.la/search-and-replace-for-wordpress-databases/上的一个很酷的脚本来解决此问题。

要将wordpress迁移到新的URL /域名,请执行以下操作:

  1. 进行现有wordpress的数据库转储(例如,使用phpmyadmin)
  2. 将转储原样还原(无需修改)到您的新位置
  3. 将脚本从spectacu.la解压缩到您的wordpress主文件夹中(这不是插件...)
  4. 通过将浏览器指向新站点来运行该脚本,例如http://new-website.url/searchreplacedb.php
  5. 不要忘记从新的wordpress主页中删除脚本

1
我知道这有点旧,但是如果我按原样还原转储,应该在哪里指定新的数据库名称?我至少应该在第二步中输入新的数据库名称吗?感谢您提供此信息
andresmijares 2012年

我不确定我是否完全理解您的问题。可以使用phpmyadmin之类的工具来还原数据库,您可以给它起一个新名称,也可以使用旧名称。我刚才提到的脚本只是在数据库已还原后更改文本。
Yoav Aner 2012年

嗨,Yoav,谢谢您的回答,我的意思是,当我导出数据库时,通常将数据库名称更改为新名称,并更改域链接。这样说,在第二步,您说是按原样还原转储,而无修改,我只是想知道是不是从字面上看,否则我至少必须更改数据库名称。我知道这可能是一个虚假的问题,我有点迷茫,再次感谢您的回答
andresmijares 2012年

我不知道如何转储数据库,但是如果您使用phpmyadmin“导出”工具,那么它与哪个数据库名称无关。您可以使用导出并将其导入回任何其他数据库。通常,关于项目要点2,我认为可以更改数据库名称。
Yoav Aner

2

在数据库导出文件上进行搜索和替换时,OP过于热情,最终导致某些序列化数据中“ 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 */;

我还尝试使用@Yoav答复的“搜索并替换”工具(v2.1),但它仍会破坏我的序列化数据。


嗨,里卡多,欢迎来到WordPress答案!您在其中张贴的区域保留为原始问题的答案。即使您的问题与您相关,也应将其作为单独的问题发布。这样,您将有更多的机会得到答案。
Chris_O 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.