• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

使用php (正则) 给 wordpress网站更换域名

wordpress Mr.Adam 4年前 (2020-11-19) 1408次浏览 已收录 0个评论

使用 php (正则) 给 wordpress 网站更换域名

使用 php (正则) 给 wordpress 网站更换域名

继上次分享使用 python 脚本更换 wordpress 网站的域名,这次是一个直接更换数据库内的网站域名,相比替换 sql 文件来说,这个速度就有点慢了,但是优化之后还是可以使用的(只要数据库不是几十个 g 的那种…)!
使用 python (正则) 替换 php 序列化内的字符串
贴代码:

<?php

ini_set("display_errors", "On");
error_reporting(E_ALL & ~E_NOTICE);

$host      = $argv[1];    // 数据库 HOST
$user      = $argv[2];    // 用户名
$passwd    = $argv[3];    // 密码
$dbname    = $argv[4];    // 库名
$find      = $argv[5];    // 查找字符
$replace   = $argv[6];    // 替换字符

if (count($argv) !== 7) {
    exit('缺少参数');
}

class Main {

    public $db = null;

    public $tables = null;

    public $conn = null;

    public $page = 1;

    public $old_str = null;

    public $old = null;

    public $new = null;

    public $pattern = "";

    public $last_id = 0;

    public $queue = [];

    public function __construct($host,$user,$passwd,$dbname,$old,$new)
    {
        $this->conn = new Mysqli($host, $user, $passwd, $dbname);
        if ($this->conn->connect_error) {
            exit("连接数据库出错" . $this->conn->connect_error);
        }
        $this->old_str = $old;
        $this->old = explode("|", $old);
        if (count($this->old) > 1) {
            $pattern = "/(";
            foreach ($this->old as $str) {
                if(substr($str,strlen($str)-2) == "co"){
                    $pattern .= "(?<!.){$str}" . "(?!m)|";
                }else{
                    $pattern .= "(?<!.){$str}" . "|";
                }
            }
            $pattern = rtrim($pattern, "|");
            $pattern .= ")/i";
        } else {
            $pattern = "/{$this->old[0]}/i";
        }
        $pattern = str_replace(".", '\.', $pattern);
        $pattern = str_replace("-", '\-', $pattern);
        $pattern = str_replace("_", '\_', $pattern);
        $this->pattern = $pattern;
        $this->new = $new;
        $this->tables = $this->get_tables();
    }

    //执行替换
    public function doReplace($data,$replace){
        if(is_string($data)){
            return preg_replace($this->pattern,$replace,$data);
        }else if(is_array($data) || is_object($data)) {
            foreach ($data as $k => $v) {
                if(is_array($data)){
                    $data[$k] = $this->doReplace($v, $replace);
                }else if(is_object($data)){
                    $data->$k = $this->doReplace($v, $replace);
                }
            }
            return $data;
        }else{
            return $data;
        }
    }

    //查询
    public function query($sql){
        return $this->conn->query($sql);
    }

    //一次分页获取 20 个
    public function get_ten($sql,$page = 1){
        $len = 20;
        $start = ($page-1)*$len;
        $limit = $start.",".$len;
        $sql .= " limit ".$limit;
        $res = $this->query($sql);
        $data = $res->fetch_all();
        $res->free();
        if(!$data){
            return false;
        }
        return $data;
    }

    //获取表名
    public function get_tables(){
        $res = $this->query("show tables");
        $arr = $res->fetch_all();
        $r = [];
        foreach($arr as $v){
            $r[] = $v[0];
        }
        $res->free();
        return $r;
    }

    //获取表名与字段名
    public function select($table){
        $sql = "select * from `{$table}` where 1 limit 1";
        $res = $this->query($sql);
        $cols = $res->fetch_fields();
        $res->free();
        return $cols;
    }

    public function get_total($sql){
        $res = $this->query($sql);
        $n = $res->fetch_row();
        $res->free();
        return $n[0];
    }

    //加任务
    public function detach($table,$index,$col,$total,$s_total){
        if(!isset($this->queue[$table])){
            $this->queue[$table] = [];
        }
        $this->queue[$table][] = [
            "col"=>$col->name,
            "index"=>$index->name,
            "total"=>$total,
            "s_total"=>$s_total
        ];
    }

    //对象初始化
    public function init(){
        foreach($this->tables as $table){
            $sql = "select * from `{$table}` where 1 limit 1";
            $res = $this->query($sql);
            $data = $res->fetch_fields();
            $index = $data[0];
            if(!$data){
                continue;
            }
            foreach($data as $col){
                if($col->type != 252 && $col->type != 253 && $col->type != 254){
                    continue;
                }
                $sql = "select count(*) from `{$table}` where `{$col->name}` like \"a:%{$this->old[0]}%\"";
                $sql_two = "select count(*) from `{$table}` where `{$col->name}` like \"%{$this->old[0]}%\"";
                if(count($this->old) > 1){
                    foreach($this->old as $k=>$old){
                        if($k == 0){
                            continue;
                        }
                        $sql_two .= " or `{$col->name}` like \"a:%$old%\"";
                        $sql_two .= " or `{$col->name}` like \"o:%$old%\"";
                        $sql .= " or `{$col->name}` like \"%{$old}%\"";
                    }
                }
                $s_total = $this->get_total($sql_two);
                $total = $this->get_total($sql);
                if($s_total || $total){
                    $this->detach($table,$index,$col,$total,$s_total);
                }
            }
            $res->free();
        }
    }

    public function Exec($table,$index,$id,$data,$act='update'){
        if($act == 'insert'){
            $sql = "insert into ".$table." (";
            $sql .= implode(",",array_keys($data)).") values ('";
            $sql .= implode("','",array_values($data))."');";
        }else if($act == 'update'){
            $sql = "update `".$table."` set ";
            foreach($data as $k=>$v){
                $v = str_replace("\"","\\\"",$v);
                $v = str_replace('\\\\"','\\\\\\"',$v);
                $sql .= '`'.$k.'`="'.$v.'",';
            }
            $sql = rtrim($sql,",") . " where ".$index."=".$id;
        }
        $rs = $this->query($sql);
        if($rs){
            if($id == $this->last_id){
                return false;
            }
            $this->last_id = $id;
        }
        return $rs?true:false;
    }
}
$start = time();
$main = new Main($host,$user,$passwd,$dbname,$find,$replace);
echo date("Y-m-d H:i:s")."---开始处理...".PHP_EOL;
$main->init();
echo date("Y-m-d H:i:s")."---初始化完成...".PHP_EOL;
$queue = $main->queue;
$n = 0;
foreach($queue as $table=>$arr){
    foreach($arr as $d){
        if(count($main->old) > 1){
            $sql = "select `{$d['index']}`,`{$d['col']}` from {$table} where `{$d['col']}` like \"%{$main->old[0]}%\"";
            foreach($main->old as $k=>$o){
                if($k == 0){
                    continue;
                }
                $sql .= " or `{$d['col']}` like \"%{$o}%\"";
            }
        }else{
            $sql = "select `{$d['index']}`,`{$d['col']}` from `{$table}` where `{$d['col']}` like \"%{$main->old[0]}%\"";
        }

        while($list = $main->get_ten($sql)){
            foreach($list as $row){
                $new = "";
                if(substr($row[1],0,2) == "a:" || substr($row[1],0,2) == "o:" || substr($row[1],0,2) == "s:"){
                    $new = preg_replace_callback("/(?:s\:)(\d+)(?:\:\")([\s\S]*?)(?:\"\;)/",function($match) use ($main){
                        $old = $match[2];
                        $new = preg_replace($main->pattern,$main->new,$match[2]);
                        if(strlen($old) != strlen($new)){
                            $cut_num = strlen($new) - strlen($old);
                            $match[1] += $cut_num;
                            return "s:{$match[1]}:\"{$new}\";";
                        }
                        return $new;
                    },$row[1]);
                    $new = preg_replace($main->pattern,$main->new,$new);
                }else{
                    $new = preg_replace($main->pattern,$main->new,$row[1]);
                }
                //修改
                $n +=1;
                $r = $main->Exec($table,$d["index"],$row[0],[$d["col"]=>$new]);
                echo "修改了{$n}条数据!".PHP_EOL;
            }
        }
    }
}
$end = time();
$time = round(($end-$start)/60,2);
echo date("Y-m-d H:i:s")."---修改数据库任务执行完成,修改了{$n}条数据,共耗时 {$time} 分钟!".PHP_EOL;
?>

使用教程:
把数据库中的 a.com,b.com,c.co 全部替换为 abc.com

php change_domain.php $host $use $passwd "a.com|b.com|c.co" "abc.com"

经过多次测试,大概 2 万条数据 5 分钟就替换完了,速度还是不错的! :mrgreen:
主要应用的是preg_replace_callback,它接受一个回调函数来处理并替换正则匹配到的参数


小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明使用 php (正则) 给 wordpress 网站更换域名
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址