WordPress 换域名全流程:数据库替换、301 与图标不显示
换域名失败最常见的样子是:前台首页能打开,点进内页 404,或者后台能登录但主题设置页一片空白。原因几乎都出在同一处——数据库改了,但 wp-config.php、.htaccess、SSL 证书这三样没跟着换。下面按真实操作的先后顺序写,顺序错了会多做一倍功。
先确认你属于哪一种换法
「换域名」在 WordPress 里有三种,处理范围差别很大,先对号入座再动手。
| 情况 | 典型场景 | 要做的事 |
|---|---|---|
| 彻底替换 | old.com 不再使用,全部流量走 new.com | 数据库全量替换 + 301 + 证书重签 + 收录处理 |
| 新增并列 | old.com 保留,new.com 是新品牌站 | 不要共用一份数据库,建议新装一套再导内容 |
| 仅绑定别名 | 主域名不变,加一个 www 或二级域名 | 只改 siteurl/home + 301 归一化,不动内容表 |
第三种最容易被当成第一种做,结果把正文里的旧链接也一起替了,历史文章引用的外部地址全断。判断标准很简单:旧域名以后还要不要能访问。要,就只改配置;不要,才做全量替换。
第一步:在还能进后台的时候备份
换域名是不可逆操作,尤其是 SQL 批量替换,跑错一次就得回滚。备份要分两件事做。
- 数据库:phpMyAdmin 进库,全选表导出,格式选 SQL,字符集选 utf8mb4,勾选「添加 DROP TABLE」。
- 文件:把整个站点目录打包,重点是 wp-config.php、wp-content/uploads、wp-content/themes、wp-content/plugins。
只备份数据库不备份文件是常见错误:回滚时数据库是旧的、文件是新的,两边对不上,排查成本更高。完整的备份策略可以参照 WordPress 备份与恢复,这里不重复。
第二步:改 siteurl 和 home
WordPress 判断「自己在哪个地址」只看 wp_options 表里的两行:siteurl 和 home。这两个值不改,后台所有跳转都会把你送回旧域名,连登录都进不去。
动手之前,先在主机面板把新域名绑定到同一个站点目录(cPanel 叫附加域,宝塔叫站点绑定),并确认解析已经指向这台服务器。绑定没做就去改 WordPress 配置,前台会直接打不开。
三种改法,按能不能进后台选:
- 能进后台:设置 → 常规,把「WordPress 地址」和「站点地址」都改成新域名,保存。改完会立刻被踢出登录,用新域名重新登录即可。
- 进不去后台:在 wp-config.php 里加两行常量,优先级高于数据库,改完能进后台再回头改数据库里的值。
- 命令行:用 WP-CLI 一条命令改完,适合有 SSH 的环境。
// wp-config.php,加在「好了,别再编辑了」注释之前
define('WP_HOME', 'https://new.com');
define('WP_SITEURL', 'https://new.com');
wp option update home 'https://new.com'
wp option update siteurl 'https://new.com'
协议要和实际一致。站点已经上了 HTTPS 就写 https,写成 http 会导致后台混合内容告警,编辑器加载不出来。证书和协议的处理细节见 WordPress SSL 与 HTTPS 配置。
第三步:SQL 批量替换,为什么不能裸跑 UPDATE
改完 siteurl/home 只解决了 WordPress 的自我认知,正文、摘要、自定义字段、小工具配置里还散落着大量 old.com。这些必须一起换掉,否则图片全部裂开、内链全部跳回旧站。
很多人第一反应是这么写:
UPDATE wp_posts SET post_content = REPLACE(post_content, 'old.com', 'new.com');
这条语句本身没错,错在只跑了 wp_posts。WordPress 存域名的地方至少有这五处:
| 表 | 关键字段 | 存了什么 |
|---|---|---|
| wp_options | option_value | siteurl、home、主题选项、小工具、插件配置 |
| wp_posts | post_content、post_excerpt、guid | 正文图片、内链、摘要、菜单项 |
| wp_postmeta | meta_value | 页面构建器数据、SEO 插件字段、缩略图路径 |
| wp_termmeta | meta_value | 分类与标签的封面图、SEO 描述 |
| wp_usermeta | meta_value | 用户后台偏好、部分插件的用户字段 |
更麻烦的是,wp_options 和 wp_postmeta 里有大量 序列化数据,形如 a:2:{s:3:"url";s:15:"http://old.com/";}。字符串长度是写死在数据里的:你把 old.com 换成更短的 new.com,s:15 这个长度声明却没变,PHP 反序列化时直接失败返回 false。表现就是主题设置页空白、小工具全部消失、页面构建器内容读不出来,而前台首页看起来还正常——这是最迷惑人的一处。
第四步:用 Better Search Replace 处理序列化
这就是「换域名必须用工具而不是裸 SQL」的全部理由。Better Search Replace 会先反序列化、改值、再按新长度重新序列化,长度声明跟着变,数据不会坏。
- 插件 → 安装插件,搜 Better Search Replace,装好启用。
- 打开 工具 → Better Search Replace。
- Search for 填
old.com,Replace with 填new.com,不要带 http:// 和结尾斜杠,这样 http、https、协议相对地址三种写法能一次全覆盖。 - Tables 全选,先勾上「Run as dry run」跑一遍,看报告里每张表命中多少行。
- 确认命中数合理,取消 dry run,再跑一次真替换。
几个判断点:
- wp_options 命中几百到上千行是正常的,主题选项和小工具都在里面。
- wp_posts 的
guid列也会被替换。guid 本意是文章永久标识,理论上不该改,但实践中改了没有副作用,不改反而会让部分 RSS 阅读器持续抓到旧地址,建议一起换。 - 表前缀不是 wp_ 的,记得在下拉里选对前缀,选错等于没跑。
- 数据量在十万行以上时插件容易超时,把 PHP 的 max_execution_time 临时调到 300,或者按表分批替换。
第五步:301 把旧域名永久跳到新域名
不跳 301 的后果比想象中严重:搜索引擎同时抓到两个域名的同一份内容判定重复,外部链接和收藏夹全部落到旧站,旧域名的权重传不过去。
Apache 环境,改 .htaccess,规则要放在 WordPress 自带规则之前:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?old.com$ [NC]
RewriteRule ^(.*)$ https://new.com/$1 [R=301,L]
Nginx 环境:
server {
listen 80;
listen 443 ssl;
server_name old.com www.old.com;
return 301 https://new.com$request_uri;
}
两个细节经常漏:一是 $request_uri 必须带上,否则所有旧链接都跳到新站首页,深层页面积累的权重全丢;二是 www 和非 www 要写在一起,只跳裸域名的话 www.old.com 依旧能访问。跳转写错导致的循环重定向,排查思路和 404 与跳转异常处理 一致。
第六步:SSL 证书必须重签
证书是绑定域名的,新域名不在旧证书的 SAN 列表里,浏览器直接报「证书名称不匹配」。这不是配置问题,只能重新签发。
- 免费证书(Let’s Encrypt):删掉旧证书,按新域名重新申请。certbot 环境直接跑
certbot --nginx -d new.com -d www.new.com,会自动改写 nginx 配置。 - 付费证书:找签发方重签或补 SAN,需要重新验证域名所有权,走 DNS TXT 记录最快。
- 证书装好后,把 wp-config.php 里的 WP_HOME、WP_SITEURL 和数据库里的 siteurl 再确认一遍都是 https。
证书没换就开强制 HTTPS,整站会打不开。换完出现「无法访问此网站」,先看是不是这个原因,再看 WordPress 打不开排查。
第七步:图标不显示,问题只在三个地方
换域名之后「网站图标不显示」是反馈最多的问题,原因只有三类,按顺序查。
1. 浏览器和 CDN 缓存没清
favicon 是强缓存资源,缓存周期常常按天算。你自己的浏览器还留着旧域名的图标,看着就像没生效。
- 用无痕窗口访问新域名,图标正常就是缓存问题,不用处理。
- 站点装了缓存插件,清一遍页面缓存,再清 CDN 缓存。
- CDN 里的 favicon.ico 要单独刷新,刷新页面缓存不会带上它。
2. 主题选项里的图标路径还是旧域名
多数主题在「外观 → 自定义 → 站点标识 → 站点图标」里存的是一个完整 URL。这个值存在 wp_options 的序列化数组里,如果替换时漏了 wp_options,或者用裸 SQL 把序列化搞坏了,路径就还指向 old.com,而旧域名已经 301 走了,图标自然 404。
处理办法很直接:进自定义器把站点图标移除后重新上传一次,会写入新域名下的新路径,比改数据库可靠。
3. 根目录 favicon.ico 与 link 标签冲突
WordPress 4.3 之后,「站点图标」会自动输出一行 <link rel="icon">。如果主题的 header.php 里还硬编码着指向旧地址的 link,两个标签打架,浏览器可能取到旧的那个。
<!-- header.php 里要删掉的旧写法 -->
<link rel="icon" href="http://old.com/favicon.ico">
同时把站点根目录下的 favicon.ico 换成新的。浏览器会默认请求 /favicon.ico,这个文件不存在时,部分浏览器不再回退到 link 标签。
第八步:清理搜索和缓存里的旧域名残留
站内搜索是最后一块,也是最容易被忘的一块。顺序错了会出现「搜索结果点进去还是旧域名」。
- 先确认替换完整:在数据库里跑
SELECT COUNT(*) FROM wp_posts WHERE post_content LIKE '%old.com%';,结果应当是 0。 - 清空对象缓存:装了 Redis 或 Memcached 的 flush 一次,否则旧的查询结果还在缓存里。
- 重建搜索索引:装了 Relevanssi 这类搜索插件,进插件设置页点「重建索引」,索引表里存的是带域名的链接。
- 刷固定链接:设置 → 固定链接,什么都不改,直接点「保存更改」,重写规则会重新生成。
- 清浏览器与 CDN 缓存,用无痕窗口验证。
还有一个隐蔽来源:导航菜单项、小工具里的自定义 HTML 都分散在 wp_posts 和 wp_options 里,替换工具要跑全表,只跑 wp_posts 会漏。
收尾:按这份清单核对一遍
任何一项没打勾都不要宣告完成。
| 顺序 | 检查项 | 怎么验 |
|---|---|---|
| 1 | wp_options 的 siteurl / home | 设置 → 常规,两个地址都是新域名 |
| 2 | 数据库全表替换完成 | SQL 查 old.com 命中数为 0 |
| 3 | 301 跳转生效 | curl -I 访问旧域名,返回 301 且 Location 带完整路径 |
| 4 | SSL 证书匹配新域名 | 浏览器地址栏无告警,证书详情里域名正确 |
| 5 | 图标与正文图片正常 | 无痕窗口访问,favicon 和首图都能加载 |
| 6 | 固定链接可访问 | 随机点三篇老文章,全部返回 200 |
最后提醒一句:不要在新旧域名同时可访问的状态下停留太久。两个域名都能打开、内容一致,搜索引擎会当镜像站处理,收录会被合并甚至丢弃。301 要在切换当天就配上,别抱着「观察几天再说」的想法。如果结构也要调整,先把域名做完再做改版,出问题好定位,改版的流程见 WordPress 网站改版。