TP5.1 清除富文本 多余(不展示)的图片 (即服务器里面的图片)]
需求介绍
正常来说,当我们修改富文本图片/视频时,后端是只上传文件 , 而不是实时删除文件
我们先把 一张表中所有 content 字段的 图片路径(即img src) 存入数组
因为 preg_match_all()所以会变成二维数组,但不用慌!
复制我这个代码,直接可以用!
/**
* 获取某张表内富文本的 所有图片 或 视频 路径
*
* @param $model //模型 即数据表对象
* @param $type //类型 video img
* @return array
*/
public function getFwbSrc($model,$type=null)
{
try {
$res = $model::field('content')->select()->toArray();
$arr = []; //匹配数组
$urls = []; //存放视频路径
if($type == 'video')
$pattern = "/\<video.*?src\=\"(.*?)\"[^>]*>/i";
else
$pattern = "/\<img.*?src\=\"(.*?)\"[^>]*>/i";
foreach ($res as $k => $v) {
preg_match_all($pattern, $v['content'], $arr[]); //匹配获取视频路径
//下面是去除空数据 [$k][1]下的路径才是正确的
if (count($arr[$k][1]) == 1) //只有一条数据的数组
array_push($urls, $arr[$k][1][0]);
else if (count($arr[$k][1]) > 1) { //有多条数据的数组
foreach ($arr[$k][1] as $kk => $vv) { //再遍历一次
array_push($urls, $vv);
}
}
}
return $urls;
}catch (Exception $e){
$this->logs('报错方法是:getFwbSrc,'.'报错信息是:'.$e->getMessage().',终止运行','error');
die;
}
}
使用:
$product = new ProductModel();
$arr = $this->getFwbSrc($product,'video');
实现思路:
1.将展示的图片/视频路径放到数组A
2.服务器所有图片/视频路径放到数组B
3.求差集 并放到数组C
4.遍历数组C,并用unlink() 删除 服务器的图片/视频
实现方法:
/**
* 获取某目录下的所有文件路径
* 第一个while先获取所有子目录, 拼接路径后第二个while获取所有文件名,再把文件名拼成完整路径
*
* @param $dir //目录 PUBLIC_PATH . "/uploads/Fwbimg/"
* @return array
*/
public function getFilesUrl($dir)
{
try {
$domain = App::config('Domain');
$allUrls = []; //dir目录下所有 子目录下的文件路径,
if (is_dir($dir)) { //为合法路径
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) { //打开成功,file为 /20210703 /20210704 等
if (strlen($file) > 2) //去除错误路径
$catalog = $dir . $file; //获取目录路径 如 www/wwwroot/uploads/Fwbimg/20210703/
if ($dh2 = opendir($catalog)) { //同上
while (($fileName = readdir($dh2)) !== false) { // fileName为文件名
if (strlen($fileName) > 2) {
$url = $domain . strstr($catalog . '/' . $fileName, '/uploads'); // 如 http://craneapi.xxxx.cn/uploads/Fwbimg/20210703/8b239cad4302c014be6dce42fe07ba35.mp4
$allUrls[] = $url;
}
}
closedir($dh2);
}
}
closedir($dh);
}
}
$allUrls = array_flip($allUrls); //反转两次,用于去重
$allUrls = array_flip($allUrls);
return ($allUrls);
}catch (Exception $e){
$this->logs('报错方法是:getFilesUrl,'.'报错信息是:'.$e->getMessage().',终止运行','error');
die;
}
}
//调用两次getFwbSrc ,获取某张表富文本的 图片和视频 路径
public function getArrSrc($model)
{
try {
$video = $this->getFwbSrc($model,'video');
$img = $this->getFwbSrc($model,'img');
$arr = array_merge($video,$img);
return $arr;
}catch (Exception $e){
$this->logs('报错方法是:getArrSrc,'.'报错信息是:'.$e->getMessage().',终止运行','error');
die;
}
}
主类
protected function execute(Input $input, Output $output)
{
try {
$start = microtime(true); //计时间
$dir = __DIR__ .'/../../public'. "/uploads/Fwbimg/";
$all = $this->getFilesUrl($dir); //服务器此路径下所有文件(只有图片和视频)
$arr1 = $this->getArrSrc(new ProductModel); //有富文本字段的表
$arr2 = $this->getArrSrc(new ServiceModel);
$arr3 = $this->getArrSrc(new NewsModel);
$arr4 = $this->getArrSrc(new ConsultModel);
$arr5 = $this->getArrSrc(new OurmsgModel);
$use = array_merge($arr1,$arr2,$arr3,$arr4,$arr5); //正在使用的 图片、视频 路径
$remain = array_diff($all,$use); //求差集 获得要删除的 服务器图片、视频 路径
if(count($remain)){ //当数组不为空
foreach ($remain as $k => $url){
Hook::listen($url,'IsFwbFile');
}
}
$end = microtime(true);
$usedTime = bcsub($end, $start, 4); //计时间
$this->logs('执行总时间为:'.$usedTime);
}catch (Exception $e){
$this->logs('报错信息是:'.$e->getMessage().',终止运行','error');
die;
}
$this->logs('信息么么:报错了可能会看不到我!');
}