完美修改wordpress网站域名地址(无需登录wordpress后台)

有时候我们会遇到域名地址失效等情况导致wordpress网站无法打开,此时旧域名已经不想使用了,或者是复制了一份域名正在使用中的网站数据,想打开却没办法登录wordpress后台去修改域名,那么怎么让网站无法打开的情况下完美迁移到新的域名上并能打开访问呢?

网上很多教程是让修改wp-config.php文件,或者是直接修改数据库中的wp_options表。但是这样直接修改往往会出现一些奇怪的问题,会有很多资源无法正常访问,这里给大家分享一个无需登录后台就能完美修改wordpress网站域名的方法。

1、将以下代码保存成db-replace.php,名称可自定义,后缀不能变

复制代码
<?php
/**
 * WordPress 数据库批量替换工具 (独立单文件版)
 * 作者: Junson142099
 * 此php文件根据子比主题作者老唐的一键换域名插件修改,实现了无需登录wordpress即可运行,https://www.zibll.com/19369.html
 * 修改: 适配无后台、无鉴权模式
 * * 警告:使用完毕后请务必删除此文件!!!
 */

// 1. 尝试加载 WordPress 环境
if (file_exists('wp-load.php')) {
    require_once('wp-load.php');
} elseif (file_exists('../wp-load.php')) {
    require_once('../wp-load.php');
} else {
    die('错误:无法找到 wp-load.php,请将此文件上传到 WordPress 网站根目录。');
}

// 定义常量,防止报错
if (!defined('SQL_REPLACE_TEXT_DOMAIN')) define('SQL_REPLACE_TEXT_DOMAIN', 'default');

// 2. 处理 POST 请求 (AJAX逻辑)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
    $replacer = new SqlReplaceSingle();
    
    if ($_POST['action'] === 'sql_replace_next') {
        $replacer->ajax_next();
    } elseif ($_POST['action'] === 'sql_replace_submit') {
        $replacer->ajax_submit();
    }
    exit; // 处理完 API 后退出
}

// 3. 类定义 (精简版)
class SqlReplaceSingle {
    
    // 获取需要搜索的表和列
    public function get_db_table_args() {
        global $wpdb;
        $args = array(
            array('table_name' => $wpdb->posts, 'column_name' => 'post_content'),
            array('table_name' => $wpdb->posts, 'column_name' => 'guid'),
            array('table_name' => $wpdb->posts, 'column_name' => 'post_excerpt'),
            array('table_name' => $wpdb->posts, 'column_name' => 'post_title'),
            array('table_name' => $wpdb->postmeta, 'column_name' => 'meta_value'),
            array('table_name' => $wpdb->comments, 'column_name' => 'comment_content'),
            array('table_name' => $wpdb->comments, 'column_name' => 'comment_author_url'),
            array('table_name' => $wpdb->commentmeta, 'column_name' => 'meta_value'),
            array('table_name' => $wpdb->users, 'column_name' => 'user_url'),
            array('table_name' => $wpdb->usermeta, 'column_name' => 'meta_value'),
            array('table_name' => $wpdb->termmeta, 'column_name' => 'meta_value'),
            array('table_name' => $wpdb->term_taxonomy, 'column_name' => 'description'),
        );

        $eliminate_table_names = array_column($args, 'table_name');
        $eliminate_table_names[] = $wpdb->options;

        $sql = "SELECT t.TABLE_NAME as table_name ,c.COLUMN_NAME as column_name FROM information_schema.TABLES t,INFORMATION_SCHEMA.Columns c WHERE c.TABLE_NAME=t.TABLE_NAME AND c.TABLE_SCHEMA = '" . DB_NAME . "' AND c.DATA_TYPE in ('longtext','text') AND t.TABLE_NAME NOT IN ('" . implode("','", $eliminate_table_names) . "')";
        $result = $wpdb->get_results($sql);
        if ($result) {
            $args = array_merge($args, $result);
        }

        $args[] = array('table_name' => $wpdb->options, 'column_name' => 'option_value');
        return $args;
    }

    // 搜索
    public function db_select($key, $new = '') {
        global $wpdb;
        $is_str_strlen_same = true;
        if ($new && strlen($new) !== strlen($key)) {
            $is_str_strlen_same = false;
        }

        $table_args = $this->get_db_table_args();
        $data = array();
        $statistics = array('count' => 0, 'serialize_count' => 0);

        foreach ($table_args as $args) {
            $args = (array) $args;
            $s_name = $args['table_name'];
            $s_columns = $args['column_name'];
            
            // 检查表是否存在,防止报错
            if($wpdb->get_var("SHOW TABLES LIKE '$s_name'") != $s_name) continue;

            $sql = "SELECT count(*) FROM `$s_name` WHERE `$s_columns` like '%$key%'";
            $count = $wpdb->get_var($sql);
            $statistics['count'] += $count;

            if ($count) {
                $serialize_count = 0;
                $serialize_sql = '';
                if (!$is_str_strlen_same) {
                    $serialize_sql = $sql . " and `$s_columns` LIKE '%{%' and `$s_columns` LIKE '%}'";
                    $serialize_count = $wpdb->get_var($serialize_sql);
                    $statistics['serialize_count'] += $serialize_count;
                }
                $data[] = array(
                    'table_name' => $s_name,
                    'column_name' => $s_columns,
                    'count' => $count,
                    'serialize_count' => $serialize_count,
                );
            }
        }
        return array('data' => $data, 'statistics' => $statistics);
    }

    // 执行替换
    public function db_replace($old, $new) {
        global $wpdb;
        $is_str_strlen_same = strlen($old) === strlen($new);
        $table_args = $this->get_db_table_args();
        $data = array(
            'serialize' => array('count' => 0, 'detail' => array()), 
            'routine' => array('count' => 0, 'detail' => array())
        );

        if (!$is_str_strlen_same) {
            $data['serialize'] = $this->db_replace_serialize($old, $new);
            if (!empty($data['serialize']['time_over'])) {
                $data['time_over'] = true;
                return $data;
            }
        }

        foreach ($table_args as $args) {
            $args = (array) $args;
            $s_name = $args['table_name'];
            $s_columns = $args['column_name'];
             // 检查表是否存在
            if($wpdb->get_var("SHOW TABLES LIKE '$s_name'") != $s_name) continue;

            $sql = "UPDATE `$s_name` SET `$s_columns` = replace(`$s_columns`,'$old','$new')";
            if (!$is_str_strlen_same) {
                $sql .= " WHERE `$s_columns` NOT LIKE '%{%' OR `$s_columns` NOT LIKE '%}'";
            }
            $count = $wpdb->query($sql);
            $data['routine']['detail'][] = array(
                'table_name' => $s_name,
                'column_name' => $s_columns,
                'count' => $count,
            );
            $data['routine']['count'] += $count;
        }
        return $data;
    }

    // 序列化替换
    public function db_replace_serialize($old, $new) {
        global $wpdb;
        $time_over_second = 8; 
        $table_args = $this->get_db_table_args();
        $data = array('count' => 0, 'detail' => array());
        $start_time = microtime(true);

        foreach ($table_args as $args) {
            $args = (array) $args;
            $s_name = $args['table_name'];
            $s_columns = $args['column_name'];
            if($wpdb->get_var("SHOW TABLES LIKE '$s_name'") != $s_name) continue;

            $sql_paged_size = 100; 
            $sql_paged_start = 0;

            while(true) {
                $sql = "SELECT `$s_columns` as `s_val` FROM `$s_name` WHERE `$s_columns` like '%$old%' and `$s_columns` LIKE '%{%' and `$s_columns` LIKE '%}' LIMIT $sql_paged_start,$sql_paged_size";
                $results = $wpdb->get_results($sql);

                if ($results && is_array($results)) {
                    $i = 0;
                    foreach ($results as $result) {
                        if ($this->db_save_serialize_data($s_name, $s_columns, $result->s_val, $old, $new)) {
                            $i++;
                        }
                    }
                    $data['detail'][] = array('table_name' => $s_name, 'column_name' => $s_columns, 'count' => $i);
                    $data['count'] += $i;
                }

                $sql_paged_start += $sql_paged_size;

                if ((microtime(true) - $start_time) > $time_over_second) {
                    $data['time_over'] = true;
                    return $data;
                }

                if (count($results) < $sql_paged_size) break;
            }
        }
        return $data;
    }

    public function db_save_serialize_data($s_name, $s_columns, $result, $old, $new) {
        global $wpdb;
        if (is_serialized($result)) {
            $new_val = $this->serialize_data_replace(maybe_unserialize($result), $old, $new);
        } else {
            $new_val = str_replace($old, $new, $result);
        }
        $new_val = maybe_serialize($new_val);
        return $wpdb->update($s_name, array($s_columns => $new_val), array($s_columns => $result));
    }

    public function serialize_data_replace($result, $old, $new) {
        if (is_array($result)) {
            foreach ($result as $k => $v) {
                $result[$k] = $this->serialize_data_replace($v, $old, $new);
            }
        } elseif (is_object($result)) {
            $result = (object) $this->serialize_data_replace((array) $result, $old, $new);
        } else {
            $result = str_replace($old, $new, $result);
        }
        return $result;
    }

    public function ajax_next() {
        $old = wp_unslash($_POST['old']);
        $new = wp_unslash($_POST['new']);
        
        if (!$old || !$new) wp_send_json_error('请输入内容');
        if ($new === $old) wp_send_json_error('新内容不能与旧内容相同');

        $db_select = $this->db_select($old, $new);
        if (empty($db_select['data'])) wp_send_json_error('数据库未查询到可替换的内容');

        $send_msg = '';
        if (strlen($new) < 5 || strlen($old) < 5) {
            $send_msg = '警告:输入内容过短,容易误伤数据,请谨慎!';
        }
        if ($db_select['statistics']['serialize_count'] > 500) {
            $send_msg .= '<br>序列化数据较多,请耐心等待。';
        }

        wp_send_json_success(['msg' => $send_msg, 'old' => $old, 'new' => $new, 'data' => $db_select['data'], 'statistics' => $db_select['statistics']]);
    }

    public function ajax_submit() {
        $old = wp_unslash($_POST['old']);
        $new = wp_unslash($_POST['new']);
        
        $db_result = $this->db_replace($old, $new);
        $count = $db_result['routine']['count'] + $db_result['serialize']['count'];
        $time_over = !empty($db_result['time_over']);
        $send_msg = $time_over ? '正在处理中...' : '数据库替换完成!如修改了域名,请使用新域名访问。';
        
        wp_cache_flush();
        wp_send_json_success(['msg' => $send_msg, 'time_over' => $time_over, 'count' => $count, 'old' => $old, 'new' => $new, 'data' => $db_result]);
    }
}
?>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WordPress 数据库应急替换工具 (单文件版)</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; background: #f0f0f1; display: flex; justify-content: center; padding-top: 50px; }
        .sql-replace-wrap { max-width: 700px; width: 100%; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }
        .sql-replace-wrap .sql-header { padding: 20px; color: #fff; background: linear-gradient(135deg, #f97794 10%, #8d43ca 100%); }
        .sql-replace-wrap .sql-titel { font-weight: bold; font-size: 22px; margin: 0; }
        .sql-replace-wrap .sql-content-wrap { padding: 20px; }
        .sql-input { display: flex; align-items: center; flex-wrap: wrap; margin-bottom: 15px; }
        .sql-input > div { margin-right: 10px; font-weight: bold; color: #333; }
        .sql-input input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; min-width: 200px; }
        .sql-btns { text-align: right; margin-top: 20px; }
        .sql-btn { background: #2271b1; color: #fff; border: none; padding: 10px 25px; border-radius: 4px; cursor: pointer; font-size: 14px; text-decoration: none; display: inline-block; }
        .sql-btn:hover { background: #135e96; }
        .sql-btn.sql-submit { background: #d63638; margin-left: 10px; }
        .sql-btn.sql-submit:hover { background: #a0282a; }
        .sql-notice { margin-top: 20px; background: #fff; border: 1px solid #c3c4c7; border-left-width: 4px; padding: 12px; min-height: 20px; display: none; word-break: break-all;}
        .sql-notice.info { border-left-color: #72aee6; display: block; }
        .sql-notice.error { border-left-color: #d63638; display: block; }
        .sql-notice.success { border-left-color: #00a32a; display: block; }
        .sql-warning { background: #fcf8e3; color: #8a6d3b; padding: 10px; border-radius: 4px; margin-bottom: 10px; }
        .sql-key { background: #eee; padding: 2px 5px; border-radius: 3px; font-weight: bold; }
        .alert-danger { color: red; font-weight: bold; padding: 10px; background: #fee; border: 1px solid red; margin: 20px; text-align: center; }
    </style>
    <script>
        // 配置信息
        var _sql = {
            ajax_url: window.location.href, // 直接提交到当前页面
            nonce: 'ignored',
            lang: {
                replace_reminder: '将 {old} 替换为 {new}',
                replace_count_reminder: '共计替换 {count} 条数据,替换后无法撤回,请确保已备份数据库!',
                query_title: '查询结果预览:',
                requery_btn: '重新查询',
                not_reminder: '没有找到匹配的内容',
                reconfirm_reminder: '危险操作!\n\n请再次确认将【{old}】替换为【{new}】吗?\n\n操作无法撤销!',
                parameter_error: '参数错误',
                loading_text: '正在处理中...',
                replace_title: '常规数据替换详情:',
                replace_serialize_title: '序列化数据替换详情:',
                replace_success_title: '操作成功',
                replace_success_text: '已将 {old} 替换为 {new}'
            }
        };
    </script>
</head>
<body>

<div class="sql-replace-wrap">
    <div class="sql-header">
        <div class="sql-titel">WordPress 数据库批量替换 (应急版)</div>
        <div style="font-size: 12px; opacity: 0.8; margin-top: 5px;">无需进入后台,直接修改数据库</div>
    </div>

    <div class="alert-danger">
        安全警告:此文件没有任何权限验证!<br>使用完毕后请务必通过 FTP/文件管理器 立即删除此文件!
    </div>

    <div class="sql-content-wrap">
        <div class="sql-input">
            <div class="sql-st">将旧域名:</div>
            <input class="sql-input-old" type="text" name="old" placeholder="例如: http://old-domain.com" value="">
        </div>
        <div class="sql-input">
            <div class="sql-st">替换为新域名:</div>
            <input class="sql-input-new" type="text" name="new" placeholder="例如: https://new-domain.com" value="">
        </div>

        <div class="sql-btns">
            <a href="javascript:;" class="sql-btn sql-next">第一步:查询并分析</a>
            <a href="javascript:;" class="sql-btn sql-submit" style="display: none;">第二步:确认替换</a>
        </div>

        <div class="sql-notice"></div>
    </div>
</div>

<script>
(function ($, document) {
    $(document).ready(function ($) {
        var _wrap = $('.sql-replace-wrap');
        var key_calss_text = 'sql-key';
        var lang = _sql.lang;

        function notice(msg, type, is_add) {
            var _notice = $('.sql-notice');
            type = type || 'info';
            _notice.removeClass('error success info').addClass(type);
            if (is_add) {
                _notice.append(msg);
            } else {
                _notice.html(msg).show();
            }
        }

        function notice_loading(auto_submit) {
            $('.sql-notice').find('.sql-loading-box').remove();
            notice('<div class="sql-loading-box">' + lang.loading_text + '</div>', 'info', auto_submit);
        }

        function ajax(btn, data, successCallback) {
            if (btn.attr('disabled')) return false;
            var originalText = btn.text();
            btn.attr('disabled', true).text('处理中...');

            $.ajax({
                type: 'POST',
                url: _sql.ajax_url,
                data: data,
                dataType: 'json',
                error: function (n) {
                    btn.attr('disabled', false).text(originalText);
                    notice('Ajax Error: ' + n.status + ' ' + n.statusText, 'error');
                },
                success: function (res) {
                    btn.attr('disabled', false).text(originalText);
                    if (!res.success) {
                        return notice(res.data, 'error');
                    }
                    successCallback(res);
                }
            });
        }

        // 第一步:查询
        _wrap.on('click', '.sql-next', function () {
            var _this = $(this);
            var old_text = $('.sql-input-old').val();
            var new_text = $('.sql-input-new').val();
            var _submit_btn = $('.sql-submit');

            ajax(_this, { action: 'sql_replace_next', old: old_text, new: new_text }, function (res) {
                var lists = '';
                var all_count = 0;
                if (res.data.data) {
                    $.each(res.data.data, function (i, item) {
                        var count = parseInt(item.count);
                        if (count) {
                            all_count += count;
                            lists += '<div>表: ' + item.table_name + ' => 列: ' + item.column_name + ' => 数量: ' + item.count + (parseInt(item.serialize_count) ? ' (含序列化: ' + item.serialize_count + ')' : '') + '</div>';
                        }
                    });
                }

                if (lists) {
                    var html = '<div class="sql-warning">' + lang.replace_reminder.replace('{old}', old_text).replace('{new}', new_text) + '</div>';
                    html += '<div class="sql-warning" style="color:red;font-weight:bold;">' + lang.replace_count_reminder.replace('{count}', all_count) + '</div>';
                    if (res.data.msg) html += '<div class="sql-warning">' + res.data.msg + '</div>';
                    html += '<div><div style="font-weight:bold;margin:10px 0;">' + lang.query_title + '</div>' + lists + '</div>';
                    
                    notice(html, 'info');
                    _this.text(lang.requery_btn);
                    _submit_btn.show();
                } else {
                    notice(lang.not_reminder, 'error');
                    _submit_btn.hide();
                }
            });
        });

        // 第二步:替换
        _wrap.on('click', '.sql-submit', function () {
            var _this = $(this);
            var old_text = $('.sql-input-old').val();
            var new_text = $('.sql-input-new').val();

            if (!confirm(lang.reconfirm_reminder.replace('{old}', old_text).replace('{new}', new_text))) return;

            function do_submit(auto_submit) {
                notice_loading(auto_submit);
                var _next_btn = $('.sql-next').attr('disabled', true);

                ajax(_this, { action: 'sql_replace_submit', old: old_text, new: new_text }, function (res) {
                    _next_btn.attr('disabled', false);
                    var data = res.data;
                    var lists = '';

                    // 构建结果列表
                    if (data.data.routine && data.data.routine.detail) {
                        $.each(data.data.routine.detail, function (i, d) {
                            if (parseInt(d.count)) lists += '<div>常规替换: ' + d.table_name + '.' + d.column_name + ' (' + d.count + ')</div>';
                        });
                    }
                    if (data.data.serialize && data.data.serialize.detail) {
                        $.each(data.data.serialize.detail, function (i, d) {
                            if (parseInt(d.count)) lists += '<div>序列化替换: ' + d.table_name + '.' + d.column_name + ' (' + d.count + ')</div>';
                        });
                    }

                    var html = '';
                    if (!data.time_over) {
                        html += '<div class="sql-success" style="color:green;font-weight:bold;font-size:16px;">SUCCESS: ' + lang.replace_success_text.replace('{old}', data.old).replace('{new}', data.new) + '</div>';
                    }
                    if (data.msg) html += '<div class="sql-warning">' + data.msg + '</div>';
                    html += lists;

                    notice(html, 'info', auto_submit);

                    if (data.time_over) {
                        do_submit(true); // 超时自动重试
                    } else {
                        _this.hide();
                    }
                });
            }
            do_submit(false);
        });
    });
})(jQuery, document);
</script>
</body>
</html>

2、将php文件上传到网站根目录,也就是跟wp-config.php同一个目录下

3、给网站分配公网ip端口地址,设置成没在用的端口就行,实现公网ip地址加端口号就能访问,例如我这里用宝塔给网站分配了9005端口。

4、备份数据库,一会儿要对数据库进行操作,为防止出现错误导致不必要的麻烦,建议先备份数据库

5、使用http://公网ip:端口号/db-replace.php访问该php文件,如果没有打开强制跳转到https的开关的话,就不用加https

6、之后根据引导,将旧域名替换成新域名,请一定严格按照格式填写域名地址,不要添加其他字符,此操作将会对数据库进行操作

7、修改完之后,在dns设置好新域名的解析,宝塔的站点设置上添加好新域名,配置好证书,应该就能正常访问了

相关推荐
syjy21 天前
WooCommerce Variation Swatches Pro WordPress插件使用教程(含下载)
wordpress·wordpress插件
WordPress学习笔记1 天前
模板业(mobanye)各行各业的网站模板
wordpress
syjy22 天前
(含下载)All in One SEO Pack Pro WordPress插件使用教程
wordpress·wordpress插件
syjy23 天前
WP Smush Pro WordPress插件使用教程(含下载)
wordpress·wordpress插件
代龙涛3 天前
WordPress archive.php 分类与归档页面开发指南
开发语言·后端·php·wordpress
WordPress学习笔记4 天前
Grace主题(Grace Theme):高端原创设计 优雅大气的WordPress主题
wordpress
WordPress学习笔记5 天前
建跨境独立站用XXTheme主题好还是GraceTheme主题好?
wordpress
WordPress学习笔记7 天前
外贸模板推荐
wordpress
WordPress学习笔记8 天前
用“第一性原理”思维,为搜索引擎收录铺就坦途
搜索引擎·wordpress
Web极客码9 天前
深入了解WordPress网站访客意图
服务器·前端·wordpress