将wordpress文章中的历史图片上传到七牛云并替换

以前历史文章是用wordpress自带的媒体库,会将图片这些上传到本地;现在是使用七牛CDN来存图片,更快,也更好管理,那以前的那些文章中图片怎么办呢?

我管理七牛图片使用的是WP-QINIU插件,但是这个插件并没有处理历史图片的功能,只能自己写一个了。

为了方便修改数据,实际上是懒得写SQL,我就用Yii来做这个。

环境准备

  1. 本地拉一个yii2 basic项目运行起来;
  2. 连上wordpress的数据库;
  3. 添加七牛php-sdk,根目录运行composer require qiniu/php-sdk
  4. 去七牛云注册账号并新建一个存储空间,拿到七牛的accessKeysecretKey七牛云传送门
  5. 为新建对象存储bucket绑定一个可访问的域名,用来访问图片资源;

开整

commands文件夹下创建控制器ImageController,代码如下;

each() as $post) {
            preg_match_all('/src.*?(http.*?\.(jpg|jpeg|png))/', $post->post_content, $images);

            if(!empty($images[1])) {
                echo "处理文章{$post->ID}" . PHP_EOL;
                $newImgs = [];
                $oldImgs = [];
                foreach ($images[1] as $img) {
                    echo $img . PHP_EOL;

                    if(strpos($img, 'wp-content/uploads') !== false) {
                        $nameInfo = explode('.', $img);
                        $ext = end($nameInfo);
                        $outFile = $this->tempPath . date('YmdHis_') . uniqid() . '.' . $ext;
                        echo "保存地址:{$outFile}" . PHP_EOL;
                        if($this->download($img, $outFile) && file_exists($outFile)) {
                            echo "下载成功" . PHP_EOL;
                        } else {
                            die("下载失败:{$img}" . PHP_EOL);
                        }
                        // 上传
                        $res = $this->upload($outFile);
                        if($res) {
                            $newImg = $this->qiniuDomain . $res;
                            echo $newImg . PHP_EOL;
                            $newImgs[] = $newImg;
                            $oldImgs[] = $img;
                        }
                    } else {
                        echo "跳过" . PHP_EOL;
                    }
                }
                if(!empty($newImgs)) {
                    var_dump($oldImgs);
                    var_dump($newImgs);
                    $newContent = str_replace($oldImgs, $newImgs, $post->post_content);
                    $newFilterContent = str_replace($oldImgs, $newImgs, $post->post_content_filtered);
                    $post->post_content = $newContent;
                    $post->post_content_filtered = $newFilterContent;
                    if($post->save(false)) {
                        echo "文章{$post->ID}替换完成";
                    } else {
                        echo array_values($post->firstErrors)[0];
                    }
                }
            }
        }
    }

    /**
     * 下载本地图片
     * @param $url
     * @param $outFile
     * @return bool
     */
    public function download($url, $outFile)
    {
        $opts = [
            'http' => ['method' => 'GET', 'timeout' => 15,]
        ];
        $context = stream_context_create($opts);
        try {
            $file = file_get_contents($url, false, $context);
            if ($file) {
                file_put_contents($outFile, $file);
            }
        } catch (\ErrorException $e) {
            echo "远程转换下载错误:" . PHP_EOL;
            echo $e->getTraceAsString() . PHP_EOL;
            return false;
        }
        return true;
    }

    /**
     * 图片上传到七牛云
     * @param $filePath
     * @return bool
     */
    public function upload($filePath)
    {
        $accessKey = $this->accessKey;
        $secretKey = $this->secretKey;
        $bucket = $this->bucket;

        // 构建鉴权对象
        $auth = new Auth($accessKey, $secretKey);
        // 生成上传 Token
        $token = $auth->uploadToken($bucket);
        if(!is_file($filePath)) {
            echo "{$filePath}不是有效文件" . PHP_EOL;
            return false;
        }
        $info = pathinfo($filePath);
        $key = $info['basename'];
        echo "上传文件名:{$key}" . PHP_EOL;
        // 初始化 UploadManager 对象并进行文件的上传。
        $uploadMgr = new UploadManager();
        // 调用 UploadManager 的 putFile 方法进行文件的上传。
        list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
        if ($err !== null) {
            var_dump($err);
            return false;
        } else {
            var_dump($ret);
            return $ret['key'];
        }
    }

}

把上面控制器里正确配置你的参数,然后到命令行中进入项目根目录运行php yii image/replace 即可完成文章本地图片上传到七牛云和图片网址替换。

关键提醒

进行操作前做好数据库备份,出错了可恢复;

这里是通过图片地址中是否含有wp-content/uploads来判断是否是本地需要上传的图片,可以根据自己不同的需求来修改代码达到域名例外等需求。

2条评论

    1. 可以用我这个,把以前的图片一次性上传到七牛并且替换,后面再发文章就用WP-QINIU插件来管理就好了

发表评论

电子邮件地址不会被公开。 必填项已用*标注