Dr.Qux
q@iiiz.org
吃了吃了

WordPress跨服务器迁移最简单的手段

最近把博客建好了以后,一直在考虑如果有一天换服务器怎么办。于是就想把wordpress迁移流程走一遍,以便以后根据需要进行迁移。在这个过程中,又走了很多弯路,费了很多时间。也有一个好处,就是大体上把wordpress在服务器的运行原理搞明白了,以后遇到问题至少可以排查哪方面存在问题。抽空把这方面的内容总结一下。

一、目前流行的Wordpress迁移方案

1. 插件迁移

目前可以提供迁移的插件有很多,主要包括All in one WP Migration, Duplicator等。这些插件的功能往往大同小异。主要方式就是先安装插件,然后在插件中将网站内容打包,打包后下载。然后在新服务器中安装空白的Wordpress→安装相应插件→上传包。此种方式的问题主要在于包的文件往往很大,需要下载上传很久,而如果选择同步至onedrive或者谷歌drive需要缴纳Pro版费用,大概$99/y。同时,wordpress一般存在上传限制,大概在 50M,需要手动进行调整,找到模版下的function.php,插入如下代码:

<?php
@ini_set( 'upload_max_size' , '50M' );
@ini_set( 'post_max_size', '50M');
@ini_set( 'max_execution_time', '300' );

可以通过将50M改成其他数字,调节大小。

2. 原文件迁移

这种方法是我比较推崇的,因为它比较简单。而且宝塔面板有远程下载和生成外链两种功能,不需要自己进行下载上传,直接在服务器端进行传输。具体方法见第二节。

二、Wordpress原文件迁移方案

1. 避坑指南

网上有教程,大概意思是将根目录下所有的文件打包下载之后,再上传到新服务器。同时,将数据库文件下载后,上传至新服务器的数据库中。可是从我此次迁移试验来看,并不成功。
(1)首先,进入phpmyadmin,将数据库导出时出现了问题。提示无法导出。具体代码已经找不到了,但是花了一个小时,排查出问题的根源在于phpmyadmin5.0与php8.0的版本不匹配,需要将php降级,或phpmyadmin升级到5.1.0。
(2)解决完问题,将数据库文件导入新的服务器后,在wp-config.php文件中加入了以下代码,转为非强制性路径:

//改为相对路径
define('WP_HOME', "");
define('WP_SITEURL', "");

并且,将https设置中的强制跳转又TRUE转为FALSE:

/* 强制后台和登录使用 SSL */
define('FORCE_SSL_LOGIN', FALSE);
define('FORCE_SSL_ADMIN', FALSE);

进行更改以后发现网页的启动并不顺利。还是有些慢,于是便修改数据库。
(3)修改数据库,将数据库wp_options下面的'home'和'siteurl'字段全部改为现在的网址,发现可以加载入页面,并且大体样式和以前相似。可是,在登陆admin账户时,出现了巨大问题。账号和密码都可以输入,输入错误会有提示,但是用户名输入正确后也没反应,无法登陆后台。尝试了多种解决方案,包括使用emergency强制修改密码,查找数据库wp_options中template, current_theme、stylesheet等字段修改主题,还是不行。
附:在根目录下(包含wp-config的文件夹)建一名为emergency.php的文件,输入代码如下:

<?php
/*
    This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

    This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

require './wp-blog-header.php';

function meh() {
    global $wpdb;

    if ( isset( $_POST['update'] ) ) {
        $user_login = ( empty( $_POST['e-name'] ) ? '' : sanitize_user( $_POST['e-name'] ) );
        $user_pass  = ( empty( $_POST[ 'e-pass' ] ) ? '' : $_POST['e-pass'] );
        $answer = ( empty( $user_login ) ? '<div id="message" class="updated fade"><p><strong>The user name field is empty.</strong></p></div>' : '' );
        $answer .= ( empty( $user_pass ) ? '<div id="message" class="updated fade"><p><strong>The password field is empty.</strong></p></div>' : '' );
        if ( $user_login != $wpdb->get_var( "SELECT user_login FROM $wpdb->users WHERE ID = '1' LIMIT 1" ) ) {
            $answer .="<div id='message' class='updated fade'><p><strong>That is not the correct administrator username.</strong></p></div>";
        }
        if ( empty( $answer ) ) {
            $wpdb->query( "UPDATE $wpdb->users SET user_pass = MD5('$user_pass'), user_activation_key = '' WHERE user_login = '$user_login'" );
            $plaintext_pass = $user_pass;
            $message = __( 'Someone, hopefully you, has reset the Administrator password for your WordPress blog. Details follow:' ). "\r\n";
            $message  .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n";
            $message .= sprintf( __( 'Password: %s' ), $plaintext_pass ) . "\r\n";
            @wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Your WordPress administrator password has been changed!' ), get_option( 'blogname' ) ), $message );
            $answer="<div id='message' class='updated fade'><p><strong>Your password has been successfully changed</strong></p><p><strong>An e-mail with this information has been dispatched to the WordPress blog administrator</strong></p><p><strong>You should now delete this file off your server. DO NOT LEAVE IT UP FOR SOMEONE ELSE TO FIND!</strong></p></div>";
        }
    }

    return empty( $answer ) ? false : $answer;
}

$answer = meh();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WordPress Emergency PassWord Reset</title>
    <meta http-equiv="Content-Type" content="<?php bloginfo( 'html_type' ); ?>; charset=<?php bloginfo( 'charset' ); ?>" />
    <link rel="stylesheet" href="<?php bloginfo( 'wpurl' ); ?>/wp-admin/wp-admin.css?version=<?php bloginfo( 'version' ); ?>" type="text/css" />
</head>
<body>
    <div class="wrap">
        <form method="post" action="">
            <h2>WordPress Emergency PassWord Reset</h2>
            <p><strong>Your use of this script is at your sole risk. All code is provided "as -is", without any warranty, whether express or implied, of its accuracy, completeness. Further, I shall not be liable for any damages you may sustain by using this script, whether direct, indirect, special, incidental or consequential.</strong></p>
            <p>This script is intended to be used as <strong>a last resort</strong> by WordPress administrators that are unable to access the database.
                Usage of this script requires that you know the Administrator's user name for the WordPress install. (For most installs, that is going to be "admin" without the quotes.)</p>
            <?php
            echo $answer;
            ?>
            <p class="submit"><input type="submit" name="update" value="Update Options" /></p>

            <fieldset class="options">
                <legend>WordPress Administrator</legend>
                <label><?php _e( 'Enter Username:' ) ?><br />
                    <input type="text" name="e-name" id="e-name" class="input" value="<?php echo attribute_escape( stripslashes( $_POST['e-name'] ) ); ?>" size="20" tabindex="10" /></label>
                </fieldset>
                <fieldset class="options">
                    <legend>Password</legend>
                    <label><?php _e( 'Enter New Password:' ) ?><br />
                    <input type="text" name="e-pass" id="e-pass" class="input" value="<?php echo attribute_escape( stripslashes( $_POST['e-pass'] ) ); ?>" size="25" tabindex="20" /></label>
                </fieldset>

                <p class="submit"><input type="submit" name="update" value="Update Options" /></p>
            </form>
        </div>
    </body>
</html>
<?php exit; ?>

在地址栏中输入http://域名/emergency.php 切记修改完毕后,将emergency文件删除。修改密码也可以通过进入后台phpmyadmin,进入wp_users数据表,选择user_login和user_pass进行修改,修改时注意选择function列表为MD5。
这几种方法都不管用,我也实在没办法了,只能请教群里的大神,大神告诉我一种简单方案,我自己改良了一下。

2. “最简单方案”

(1)首先,在新服务器中建立一个网站根目录和数据库(名字与待迁移数据库相同),安装全新的wordpress,账号密码与原wordpress一致;
(2)将原网站根目录/wp-content/uploads文件夹通过宝塔进行压缩,压缩格式tar.gz即可,右击选择共享→生成外链;

https://blog.iiiz.org/wp-content/uploads/2022/05/Screen-Shot-2022-05-12-at-18.55.45-166x300.png

https://blog.iiiz.org/wp-content/uploads/2022/05/Screen-Shot-2022-05-12-at-18.55.55-300x148.png

(3)进入phpmyadmin,对数据库进行替换,如提示表已存在,可全选删除后再导入。同时,修改'home'和'siteurl'为新地址;
(4)进入新服务器的/wp-content/中,点击远程下载,输入外链和文件名,等自动下载完成,期间删除原uploads文件夹,解压下载好的文件夹,既完成替换;
(4)这个时候界面是打不开的,因为新的wordpress中未安装相应主题,因此需输入http://域名/wp-admin 或http://域名/login.php 登陆后台,将主题修改为默认主题,这样便可以进入主页,发现文章和媒体库已完成迁移;
(5)这个时候基本上已经证明成功了,可以采取同样的手段将plugins文件夹和themes文件夹压缩后传送,替换新服务器中的相应文件夹,进入后台启用主题和插件即可;
(6)至此,会发现新网站和自己的之前的网站一摸一样。再进入数据库,将wp_posts中的原有域名替换为新域名(SQL语句见上一篇文章),便可以完成所有的网站迁移工作。

三、尾声

探索至此,已经花费了我一天多的时间,期间搜了好多文档好多教程,最后才得以完美地收官。希望可以给正在迁移的你提供一种便利的方式,条条大路通罗马,适合你的,也就是最好的。

本文遵循知识共享许可 CC-BY-SA 4.0 协议,转载请标明转自“吃了吃了”博客,地址:https://blog.iiiz.org。

drqux

文章作者

发表评论

textsms
account_circle
email

吃了吃了

WordPress跨服务器迁移最简单的手段
最近把博客建好了以后,一直在考虑如果有一天换服务器怎么办。于是就想把wordpress迁移流程走一遍,以便以后根据需要进行迁移。在这个过程中,又走了很多弯路,费了很多时间。也有一个好…
扫描二维码继续阅读
2022-05-12