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;
}