WordPress 网站搬家:换服务器与换空间的完整步骤
搬家之后出问题,绝大多数不是文件没传全,而是四件事里漏了一件:wp-config.php 里的数据库账号、wp_options 里的 siteurl、伪静态规则、目录属主。这四样任意一个不对,表现都差不多——500 或者白屏,看不出是哪一个。这篇按操作顺序走,每一步给出验证方法,最后专门讲 500 和白屏怎么定位。
先分清是换服务器还是换空间
口语里都叫「搬家」,实际差别不小,选错方法会白折腾。
| 场景 | 变的东西 | 要动的地方 |
|---|---|---|
| 换服务器,域名不变 | IP、PHP 版本、MySQL 版本 | 文件 + 数据库 + wp-config,不改 siteurl |
| 换空间,域名也不变 | 仅主机环境,可能从面板机换到 VPS | 同上,注意 PHP 扩展和上传限制 |
| 换服务器 + 换域名 | IP 和域名都变 | 搬家全部步骤 + 换域名的批量替换 |
| 同机换目录 | 路径变了,域名不变 | 只改文件位置和站点根目录指向 |
只有第三种需要做数据库里的域名替换,前两种不要动 siteurl。不少人搬完顺手在数据库里把域名替换了一遍,本来没变的东西被改坏,序列化数据一崩,主题设置全丢。换域名的完整流程单独写在 WordPress 迁移搬家 相关流程里,这里只讲域名不变的标准搬家。
第一步:老服务器上打包文件和导出数据库
先在老站关掉缓存插件,把缓存目录清掉。带着缓存文件搬家,新服务器上第一件事就是看到一堆过期页面。
打包用 tar,排除缓存和日志,体积能小一半:
cd /www/wwwroot
tar -czf site.tar.gz oldsite
--exclude='wp-content/cache'
--exclude='wp-content/upgrade'
--exclude='*.log'
导数据库,比 phpMyAdmin 导出稳,不会因为超时截断:
mysqldump -u root -p --default-character-set=utf8mb4
--single-transaction --no-tablespaces olddb > olddb.sql
三个参数的作用:--single-transaction 保证 InnoDB 表导出一致性快照,不用锁表;--no-tablespaces 避免 MySQL 8 上的 PROCESS 权限报错;--default-character-set=utf8mb4 防止中文变成问号。最后这条最容易被忽略,导完不检查,新站全文都是 ???,只能重来。
导出后看一眼文件尾部,确认最后一行是 -- Dump completed。没有这行说明导出中断了。备份的完整规范见 WordPress 备份与恢复。
第二步:新服务器建库、建用户、导入
CREATE DATABASE newdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'newuser'@'localhost' IDENTIFIED BY '强密码';
GRANT ALL PRIVILEGES ON newdb.* TO 'newuser'@'localhost';
FLUSH PRIVILEGES;
导入:
mysql -u newuser -p newdb < olddb.sql
两个细节:字符集必须和原来一致,原来用 utf8mb4 的不要建成 utf8(utf8 在 MySQL 里只有三字节,存不了 emoji 和部分生僻字);用户只授权到这一个库,不要图省事给 ALL ON *.*。
导入完成后核对行数,别信「没报错就是成功」:
SELECT COUNT(*) FROM wp_posts;
SELECT COUNT(*) FROM wp_options;
和老库的数字对得上再往下走。对不上就重新导,硬着头皮继续只会在后面某个页面莫名报错。
第三步:传文件、改 wp-config.php
上传解开后,先改 wp-config.php 这四项,改完再谈能不能打开:
define('DB_NAME', 'newdb');
define('DB_USER', 'newuser');
define('DB_PASSWORD', '强密码');
define('DB_HOST', 'localhost');
DB_HOST 是最常出错的一项。老主机常写 localhost,新主机如果是独立数据库服务,要写成内网 IP 或 127.0.0.1:3306;云数据库则是一串内网地址。写错的表现是「建立数据库连接时出错」,页面直接挂掉,连 WordPress 都没启动。
接着改权限。这一步是 500 的第一大来源:
chown -R www:www /www/wwwroot/newsite
find /www/wwwroot/newsite -type d -exec chmod 755 {} ;
find /www/wwwroot/newsite -type f -exec chmod 644 {} ;
chmod 600 /www/wwwroot/newsite/wp-config.php
属主写 www 还是 nginx 还是 apache,取决于新服务器的 Web 用户,用 ps aux | grep nginx 看一眼进程属主即可。目录 777 是错误做法,等于给上传目录开了写权限,安全上直接失守。
第四步:域名没变就不用改 siteurl
如果域名不变,wp_options 里的 siteurl 和 home 保持原样,不要碰。如果连域名一起换了,先按换域名那篇做批量替换,再继续往下。
有一种情况需要改:老站是 http,新服务器直接配了 https。这时要在 wp-config.php 里加一行,强制后台也走 https,否则会出现「后台改完设置跳回 http」的循环登录:
define('FORCE_SSL_ADMIN', true);
同时确认 siteurl 和 home 都写成了 https 开头,证书本身也要在新服务器上装好。
第五步:伪静态规则必须重配
这一项搬家后必然要重做,因为 .htaccess 或 nginx.conf 是服务器级的,不跟着文件走。没配的表现很统一:首页正常,点任何内页都是 404。
Apache 环境,确认站点根目录有 .htaccess,且 AllowOverride 是 All:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Nginx 环境,在 server 块里加:
location / {
try_files $uri $uri/ /index.php?$args;
}
配完进 设置 → 固定链接,什么都不改直接点「保存更改」。这一步会重写 rewrite 规则,很多「规则明明对但不生效」的情况,点一次就好了。固定链接本身的结构说明见 WordPress 固定链接设置。
第六步:DNS 切换与 TTL
前面的步骤都可以在新服务器上用 IP 或临时域名验证完,最后才动 DNS。顺序反了,用户会在你还没准备好的时候访问到新站。
- 提前 24 小时把旧解析的 TTL 从 3600 改成 300(5 分钟)。TTL 是「缓存多久」,改小了切换才快。
- 在新服务器上绑定域名,用 hosts 文件本地测一遍:Windows 改
C:WindowsSystem32driversetchosts,加一行新IP 你的域名,浏览器访问确认整站正常。 - 确认无误后再改 DNS 的 A 记录指向新 IP。不要删旧记录再加新的,直接改值。
- 等生效。用
nslookup 你的域名 8.8.8.8查各地解析,或在线多地 ping 工具。 - 老服务器保留至少一周,别急着退。发现漏文件还能回去取。
切完不要马上把老服务器关掉,这一步每年都有人吃亏:新站跑起来三天,才发现某个插件的数据目录忘了传,而老服务器已经释放,只能从备份里翻。
搬家后 500 与白屏:按这个顺序查
两者表现不同,原因也不同。500 是 PHP 崩了,白屏多半是 PHP 跑完但输出为空。先看日志,别猜。
先打开错误显示
在 wp-config.php 里临时加:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
错误会写进 wp-content/debug.log,比页面上那行「此站点遇到技术问题」有用得多。同时看 PHP 错误日志和 nginx 的 error.log,路径一般在 /www/wwwlogs/ 或 /var/log/nginx/。
按概率从高到低排查
| 现象 | 最可能的原因 | 处理 |
|---|---|---|
| 全部页面 500 | 目录属主不对,PHP 无权读取 | chown 改成 Web 用户,目录 755 文件 644 |
| 全部页面 500,日志报 parse error | PHP 版本过高,老主题用了已移除的函数 | 把 PHP 降到 7.4 验证,或升级主题 |
| 后台白屏,前台正常 | 内存不足或某个插件致命错误 | WP_DEBUG 看日志,重命名 plugins 目录逐个试 |
| 首页正常,内页 404 | 伪静态规则缺失 | 补 try_files 或 .htaccess,重存固定链接 |
| 整站白屏无日志 | 文件没传全,缺 wp-load.php 之类 | 核对文件数量,重新上传核心文件 |
| 提示建立数据库连接错误 | DB_HOST 或账号密码错 | 用命令行 mysql -h 测试连通性 |
白屏还有一种情况:文件传了一半。FTP 断线重传时容易出现零字节的 php 文件,PHP 解析空文件不会报错,但类没定义,页面就白。用 find . -size 0 -name "*.php" 扫一遍,命中就是证据。白屏的详细排查见 WordPress 白屏排查,数据库层面的报错见 WordPress 数据库报错。
搬完必须跑一遍的检查
- 前台首页、文章页、分类页、搜索页各点一个,确认都是 200。
- 后台登录一次,进 设置 → 常规 保存一下,确认没有权限报错。
- 上传一张图片,确认 uploads 目录可写、缩略图能生成。
- 发一条测试评论,确认邮件通知能发出(新服务器常缺 sendmail,评论发不出通知)。
- 用
curl -I https://你的域名看返回头和证书有效期。 - 确认 WP-Cron 正常:访问
wp-cron.php返回 200,不然定时发布和备份都会停。
搬家这件事,稳的做法永远是「新站先跑通,再切 DNS」,而不是「先切了再修」。用 hosts 文件验证这一步花十分钟,能省掉后面半夜回滚的风险。如果站点同时涉及版本升级,把顺序定成先搬家、观察两天、再升级,两件事混在一起出问题时无法判断是谁引起的。