场景复现:对采集的图片进行压缩处理出现失败的情况,跟踪打印 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后,复试,成功。