ThinkPHP结合ueditor编辑器抓取远程图片上传到OSS


这只是抓取远程图片的代码片段,详情请查看


http://test.scriptjc.com/article/445


/**
* 抓取远程文件
* @param 
*/
public function catchImage($CONFIG){
	// 上传配置,可从配置文件中限制某些情况的抓取
	$config = array(
		"pathFormat"	=> $CONFIG['catcherPathFormat'],
		"maxSize"		=> $CONFIG['catcherMaxSize'],
		"allowFiles"		=> $CONFIG['catcherAllowFiles'],
		"oriName"		=> "remote.png"
	);
	$fieldName = $CONFIG['catcherFieldName'];
	
	// 抓取远程图片 $source 为一张张图片数组 http://img1.mm131.com/pic/1615/0.jpg
	$list = array();
	if (isset($_POST[$fieldName])){
		$source = $_POST[$fieldName];
	}else{
		$source = $_GET[$fieldName];
	}
	
	foreach ($source as $imgUrl) {
		// $imgUrl 为单张图片
		$info = $this->saveRemote($imgUrl,$config);
		array_push($list, array(
			"state" => $info["state"],
			"url" => $info["url"],
			"size" => $info["size"],
			"title" => htmlspecialchars($info["title"]),
			"original" => htmlspecialchars($info["original"]),
			"source" => htmlspecialchars($imgUrl)
		));
	}
	// 返回抓取数据
	return json_encode(array(
		'state'=> count($list) ? 'SUCCESS':'ERROR',
		'list'=> $list
	));
}


/**
* 拉取远程图片
* @return mixed array(
		"state"	=> 'SUCCESS',
		'url'	=> $this->domain.$url.$this->imageSize,
		'title'	=> $title,
		'original' => $oriName,
		'type'	=> $ext,
		'size'	=> $fileSize,
);*/
private function saveRemote($fileField,$config)
{
	$imgUrl = htmlspecialchars($fileField);
	$imgUrl = str_replace("&", "&", $imgUrl);
	
	//----------------------一些验证------------------------------
	//http开头验证
	if (strpos($imgUrl, "http") !== 0) {
		return array("state" => '链接不是http链接');
	}
	
	preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
	$host_with_protocol = count($matches) > 1 ? $matches[1] : '';
	
	// 判断是否是合法 url
	if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
		return array("state" => 'URL不合法');
	}
	
	preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
	$host_without_protocol = count($matches) > 1 ? $matches[1] : '';
	
	// 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
	$ip = gethostbyname($host_without_protocol);
	// 判断是否是私有 ip
	if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
		return array("state" => '是私有ip');
	}
	
	//获取请求头并检测死链
	$heads = get_headers($imgUrl);
	if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
		return array("state" => '链接不可用');
	}
	
	//格式验证(扩展名验证和Content-Type验证)
	$fileType = strtolower(strrchr($imgUrl, '.'));
	if (!in_array($fileType, $config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
		return array("state" => '链接contentType不正确');
	}
	//------------------------------------------------------------
	
	//打开输出缓冲区并获取远程图片
	ob_start();
	$context = stream_context_create(
		array('http' => array(
			'follow_location' => false // don't follow redirects
		))
	);
	readfile($imgUrl, false, $context);
	$img = ob_get_contents();
	ob_end_clean();
	preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);

	$oriName = $m ? $m[1]:"";
	$fileSize = strlen($img);
	
	//检查文件大小是否超出限制
	if ($fileSize  >  $config["maxSize"]){
		return array("state" => '文件大小超出网站限制');
	}
	
	// 文件后缀
	$ext	= strtolower(strrchr($oriName, '.'));
	$key	= $this->prefix. time().rand(1000,9999);
	$url		= $key.$ext;
	$title	= substr($url, strrpos($url, '/') + 1);
	
	// 上传变量到文件
	$this->OSSUploadContent($url,$img);
	
	return array(
		"state"	=> 'SUCCESS',
		'url'       => $this->domain.$url.$this->imageSize,
		'title'	=> $title,
		'original' => $oriName,
		'type'	=> $ext,
		'size'	=> $fileSize,
	);
}



/**
* 上传变量到文件
* @param string $object object名称
* @param string $content 文件内容,变量
*/
protected function OSSUploadContent($object, $content){
	Vendor('OSS.autoload');
	$ossClient = new \OSS\OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
	try{
		$ossClient->putObject($this->bucket, $object, $content,array());
	}catch(OssException $e){
		$this->UploadErrorMsg = $e->getMessage();
		return false;
	}
	return true;
}