以前历史文章是用 wordpress
自带的媒体库,会将图片这些上传到本地;现在是使用七牛 CDN
来存图片,更快,也更好管理,那以前的那些文章中图片怎么办呢?
我管理七牛图片使用的是 WP-QINIU
插件,但是这个插件并没有处理历史图片的功能,只能自己写一个了。
为了方便修改数据,实际上是懒得写 SQL
,我就用 Yii
来做这个。
环境准备
- 本地拉一个
yii2 basic
项目运行起来; - 连上
wordpress
的数据库; - 添加七牛
php-sdk
,根目录运行composer require qiniu/php-sdk
; - 七牛云注册账号并新建一个存储空间,拿到七牛的
accessKey
和secretKey
,七牛云传送门。 - 为新建对象存储
bucket
绑定一个可访问的域名,用来访问图片资源;
开整
在 commands
文件夹下创建控制器 ImageController
,代码如下;
<?php
namespace appcommands;
use appmodelsPosts;
use yiiconsoleController;
use QiniuAuth;
use QiniuStorageUploadManager;
class ImageController extends Controller
{
// 本地缓存目录,会先把远程图片下载到这个目录
private $tempPath = 'd:/temp/';
// 七牛云对象存储绑定的访问域名
private $qiniuDomain = 'https://images.beltxman.com/';
private $accessKey = '七牛的accessKey';
private $secretKey = '七牛的secretKey';
private $bucket = '七牛的bucket';
public function actionReplace()
{
$query = Posts::find();
foreach ($query->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
来判断是否是本地需要上传的图片,可以根据自己不同的需求来修改代码达到域名例外等需求。
我也想给WordPress的图片弄个CDN加速功能,但是我发现我连网上现有的教程的都看不懂,所以现在很少用照片。
可以用我这个,把以前的图片一次性上传到七牛并且替换,后面再发文章就用WP-QINIU插件来管理就好了