# 在 WordPress 数据库中执行搜索替换

Source: https://support.kapsulehost.com/zh-cn/wordpress-search-replace

WordPress 会在数十个数据库表中存储绝对网址，因此更换域名或迁移到 SSL 后，旧地址会散落在文章、选项和插件设置中：搜索替换就是安全清理它们的方法。本指南介绍在 KPanel 中执行此操作的两种受支持方式、为什么一种常见的第三种方法会损坏数据，以及如何验证结果。

## 何时需要执行搜索替换

- 启用 SSL 后从 `http://` 迁移到 `https://`。
- 更换域名，例如从 `old-brand.co.nz` 更换为 `new-brand.co.nz`。
- 将预发布环境推送到生产环境后，预发布主机名仍然固化在数据库中。
- 停用旧的资源主机，并一次性将所有图片网址重新指向新地址。
- 批量修正多篇文章中的同一处错误，例如旧电话号码或已停产的产品名称。

> **Warning:** 搜索替换会一次性改写所有表中的行，并且无法按行撤销。每次开始之前都请先创建备份，即使是看起来微不足道的更改也不例外。当您使用下文所述的内置工具时，KPanel 会自动创建一份备份，但如果您自己运行命令，备份就需要由您负责。请参阅[创建备份](https://support.kapsulehost.com/zh-cn/taking-a-backup)。

## 为什么不能直接运行 SQL REPLACE

这是 WordPress 数据库操作中破坏性最大的错误，因此在选择方法之前值得先了解清楚。

WordPress 将插件设置、主题选项和小工具数据存储为 PHP 序列化字符串。序列化字符串会记录其中每个值的长度，例如：

```
a:1:{s:3:"url";s:26:"http://old-domain.co.nz/x";}
```

其中的 `s:26` 表示该网址长度为 26 个字符。如果使用普通的 SQL `REPLACE()` 将 `http://` 替换为 `https://`，文本就会变成 27 个字符，而存储的长度仍然声称是 26。PHP 随后会拒绝反序列化整个选项，该设置会悄无声息地恢复为空。主题自定义设置会消失，幻灯片会丢失其中的幻灯片，插件许可证会自行注销。

KPanel 运行的 WP-CLI search-replace 会对每个值进行反序列化，在其中执行替换，然后以修正后的长度重新序列化。这就是本文只介绍这种方法的原因。

> **Important:** 切勿对 WordPress 数据库运行 `UPDATE wp_options SET option_value = REPLACE(...)` 或在 phpMyAdmin 中执行等效操作。它看起来像是成功了，也会报告受影响的行数，但会悄悄破坏它触及的每一个序列化设置。除了还原备份之外，没有任何修复方法。

## 方法 1：搜索替换卡片

这几乎适合所有人。所有 WordPress 套餐均可使用。

1. 登录 [KPanel](https://kpanel.kapsulehost.com)，然后点击左侧边栏中的**网站**。
2. 点击该网站。
3. 打开 **WordPress** 标签页，然后进入**快捷操作**部分。
4. 找到**搜索和替换**卡片，然后点击**配置**。
5. 在**查找（旧值）**中输入现有文本。
6. 在**替换为**中输入新文本。
7. 保持勾选**试运行（仅预览，不做更改）**，然后点击**预览**。

![KPanel 快捷操作中的搜索和替换卡片](https://support.kapsulehost.com/help/screenshots/wordpress-search-replace.d3d0a573.webp)

试运行会报告将进行多少次替换，并按表和列细分计数，因此您可以在正式执行之前准确看到更改将落在哪里。

当预览结果无误时：

1. 取消勾选**试运行**。
2. 点击**运行**。
3. 在对话框中确认。

替换开始之前会自动创建一份完整备份，并且本次运行涵盖所有表，包括由插件创建的表。

> **Tip:** 请搜索尽可能具体的字符串。替换 `old-domain.co.nz` 时，也会同时改写 `mail.old-domain.co.nz` 和 `staging.old-domain.co.nz`，而这通常不是您想要的。包含协议部分（如 `https://old-domain.co.nz`）可以让匹配更精确。

## 方法 2：从控制台使用 WP-CLI

控制台为您提供相同的引擎，并可对参数进行更多控制。它是托管套餐中出现的部分之一；在其他套餐中，标签栏会显示一个**托管套餐 +8 项**链接。

打开该网站，然后依次进入 **WordPress**、**控制台**。提示符已经以 `wp` 开头，因此只需输入命令的其余部分。

先预览：

```
search-replace 'http://old-domain.co.nz' 'https://old-domain.co.nz' --all-tables --dry-run
```

然后正式运行：

```
search-replace 'http://old-domain.co.nz' 'https://old-domain.co.nz' --all-tables
```

> **Warning:** 控制台不会为您创建备份。只有在使用方法 1 中的搜索和替换卡片时，才会在运行前自动创建备份。如果您在这里运行命令，请先在网站的**备份**页面中自行创建一份备份。

常用参数：

| 参数 | 作用 |
|---|---|
| `--all-tables` | 包括由插件创建的自定义表，而不仅仅是 WordPress 核心表 |
| `--dry-run` | 报告将会更改的内容，但不写入任何数据 |
| `--precise` | 使用 PHP 而不是 SQL 执行替换。速度较慢，但能处理棘手的序列化结构 |
| `--skip-columns=guid` | 不改动文章的 GUID（见下文） |
| `--report-changed-only` | 将输出精简为实际发生更改的表 |

### 关于 GUID 的说明

每篇 WordPress 文章都有一个 `guid` 列。尽管它看起来像一个网址，但它是一个标识符，而不是链接，订阅源阅读器用它来判断是否已经见过某个条目。改写它可能会让订阅源中的每篇文章都重新显示为新文章。

当您永久更换域名并重新开始时，请改写 GUID。当您只是在同一域名上从 HTTP 迁移到 HTTPS 时，请使用 `--skip-columns=guid` 跳过它们。

## 更换域名：请改用网站网址卡片

如果您的目的就是将网站迁移到新域名，请不要从搜索替换开始。同一**快捷操作**部分中的**更改网站网址**卡片会更新 `siteurl` 和 `home` 选项，并在一次操作中按正确的顺序在所有表中执行替换。如果顺序反过来，可能会导致 WordPress 无法加载自己的管理后台。

## 替换完成后

在宣告完成之前，请逐项完成以下清单。

1. **清除缓存。** 在**快捷操作**部分中运行**清除缓存**。如果网站使用全页缓存，请在 **WordPress** 下的**缓存**中清除它。
2. **刷新重写规则。** 在同一部分中运行**刷新重写规则**，或在 wp-admin 中依次打开**设置**、**固定链接**，不做任何更改直接点击**保存更改**。
3. 如果网站使用了 CDN，请在**性能**下的 **Kapsule CDN** 中**清除 CDN 缓存**。请参阅[清除 Kapsule CDN 缓存](https://support.kapsulehost.com/zh-cn/cdn-cache-purge)。
4. **在隐私窗口中加载网站**，以免浏览器缓存误导您。
5. **检查挂锁图标。** 迁移到 SSL 后如果挂锁缺失或显示警告，说明仍有网址未被替换：请参阅[修复混合内容警告](https://support.kapsulehost.com/zh-cn/ssl-mixed-content)。
6. **逐一点击检查容易出问题的页面。** 首页幻灯片、页眉标志、任何使用页面构建器搭建的页面，以及商店的结账页面。这些地方保存着位于序列化选项中的网址。
7. 在任何缓存插件自己的设置页面中**清除其缓存**。

## 故障排除

**试运行报告零次替换。** 数据库中不存在完全相同形式的该字符串。请检查末尾的斜杠、`www.` 前缀或协议部分。可以先只搜索不带其他部分的主机名，确认它确实存在。

**更换域名后图片无法显示。** 媒体网址位于 `wp_posts` 和 `wp_postmeta` 中，会被 `--all-tables` 覆盖，但 CDN 或图片优化插件可能缓存了自己改写过的副本。请清除 CDN 和该插件的缓存，然后重新加载。

**替换后设置消失了。** 这就是序列化问题，说明更改是用原始 SQL 而不是通过此处介绍的工具完成的。请还原运行前创建的备份：[从备份还原](https://support.kapsulehost.com/zh-cn/restoring-from-backup)。

**预发布网址不断重新出现。** 有某些东西在重新填充它们，通常是计划推送或缓存的选项。请查看[使用预发布环境：推送与拉取](https://support.kapsulehost.com/zh-cn/wordpress-staging-workflow)中的工作流程，并确保推送时勾选了**改写网址**。
