thinkphp5 正则采集远程图片并生成缩略图;Image::open 处理图片失败的情况

场景复现:对采集的图片进行压缩处理出现失败的情况,跟踪打印 image::open无返回值

采集流程:数据库提前录入产品的外部链接,正则匹配图片地址,获取到图片的url,通过curl下载到本地,再进行处理。

//定时任务:定时采集有赞图片
public function timing_get_goods_img(){
	$get_img = Db::name('goods')->field('goods_id,out_link')->where('out_link',"<>",'')->order('goods_id asc')->limit(1)->find();
	$result = trimall(file_get_contents($get_img['out_link']));
	$json = preg_match_all("/buyer_id(.*)null}}/",$result,$match);

	$str = '{"'.$match[0][0];
	$goods_info = json_decode($str,true);

	$goods_picture = $goods_info['goodsData']['goods']['pictures'];

	if(havedata($goods_picture)){
		$slide_img = [];
		foreach($goods_picture as $key=>$item){
			$url = $item['url'];
			$dir = ROOT_PATH . 'public'.DS .'uploads'.DS .'product/'.date("Ymd",time()).'/';
			$file_name = time().rand(10000,99999).getRandNumber().strrchr($url,'.');
			$download_effect = getImage($url,$dir,$file_name);
			if($download_effect['error'] == 0){
				$image = \think\Image::open($dir.$download_effect['file_name']);
				$image->thumb(500, 500,\think\Image:: THUMB_SCALING)->save($dir.$download_effect['file_name']);
				$slide_img[] = date('Ymd',time()).'/'.$download_effect['file_name'];
			}
		}

		//处理图片
		$update_data = [
			'goods_img' => $slide_img[0],
			'slide_img' => implode(",", $slide_img),
			'out_link' => ''
		];
		$effect = Db::name("goods")->where('goods_id',$get_img['goods_id'])->update($update_data);
	}
}

公共函数:getImage,trimall,getRandNumber,havedata

function getRandNumber($start=0,$end=9,$length=8){
    //初始化变量为0
    $connt = 0;
    //建一个新数组
    $temp = array();
    while($connt < $length){
        //在一定范围内随机生成一个数放入数组中
        $temp[] = mt_rand($start, $end);
        //$data = array_unique($temp);
        //去除数组中的重复值用了“翻翻法”,就是用array_flip()把数组的key和value交换两次。这种做法比用 array_unique() 快得多。  
        $data = array_flip(array_flip($temp));
        //将数组的数量存入变量count中  
        $connt = count($data);
    }
    //为数组赋予新的键名
    shuffle($data);
    //数组转字符串
    $str=implode(",", $data);
    //替换掉逗号
    $number=str_replace(',', '', $str);
    return $number;
}

//删除空格
function trimall($str){
    $oldchar=array(" "," ","\t","\n","\r");
    $newchar=array("","","","","");
    return str_replace($oldchar,$newchar,$str);
}

//获取远程图片
function getImage($url,$save_dir='',$filename='',$type=0){
    if(trim($url)==''){
        return array('file_name'=>'','save_path'=>'','error'=>1);
    }
    if(trim($save_dir)==''){
        $save_dir='./';
    }
    if(trim($filename)==''){//保存文件名
        $ext=strrchr($url,'.');
        if($ext!='.gif'&& $ext!='.jpg'){
            return array('file_name'=>'','save_path'=>'','error'=>3);
        }
        $filename=time().$ext;
    }
    if(0!==strrpos($save_dir,'/')){
        $save_dir.='/';
    }
    //创建保存目录
    if(!file_exists($save_dir)&&!mkdir($save_dir,0777,true)){
        return array('file_name'=>'','save_path'=>'','error'=>5);
    }
    //获取远程文件所采用的方法
    if($type){
        $ch=curl_init();
        $timeout=5;
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
        $img=curl_exec($ch);
        curl_close($ch);
    }else{
        ob_start();
        readfile($url);
        $img=ob_get_contents();
        ob_end_clean();
    }
    $fp2=@fopen($save_dir.$filename,'a');
    chmod($save_dir.$filename,777);
    fwrite($fp2,$img);
    fclose($fp2);
    unset($img,$url);
    return array('file_name'=>$filename,'save_path'=>$save_dir.$filename,'error'=>0);
}

//判断数组是否存在
function havedata($array){
	if(isset($array) && !empty($array)){
		return true;
	}else{
		return false;
	}
}

采集150个产品链接,采集到一半发现定时任务失败,去除掉缩略图生成程序就恢复正常,初步判断是缩略图生成问题,在确认了下载图片权限,路径都是对的之后,对失败的这个产品图片进行单独分析,结果发现下载下来的原图居然有5000*6000像素那么大,怀疑是不是因为图片太大问题,度娘一查,果然是因为处理高清图造成的内存崩溃所以无法返回处理结果。

处理方法:修改 memory_limit 为256M后,复试,成功。

 

你可能感兴趣的:(thinkphp5开发总结)