二
7
2011
PHP自动保存文章中的外部图片
作者: seasun对于一些转载性质或采集性质的网站,因为外链图片有可能被来源网站删除或出现防盗链的情况,有的时候站长期望把文章中的外联图片都保存到本地空间里。解决办法是在原有的系统中添加一个PHP自动保存文章中外部图片的功能。
首先我们想到的是可以通过正则匹配来寻找文章中所有的img标签,这个表达式需要可以匹配跨行的img标签,并且需要对img标签做条件判断允许img标签带有其他属性.解决方案是使用preg_replace_callback() 这个函数。
function getRomatePic($data){
$pattern = '/<img[^\/]*src=\"([^\"]*)\"[^\/]*\/>/ims';
return preg_replace_callback($pattern,filter_image_call, $data);
}
为了完成外部图片的链接过滤及图片的本地保存,定义filter_image_call()。
function filter_image_call($match){
$postImagePath="pic/";
$postImageUrlBase="http://localhost/pic/";
$image_tag = $match[0]; //获得匹配的img标签
$image_url = $match[1]; //匹配img标签的src属性值
//如果src属性值不是http://开头的,也就是说图片已经是本地地址,不做任何修改而返回原始的img标签
if(substr($image_url, 0, 7) != 'http://'){
return $image_tag;
}
$postfix = date('Y-m-d');
$dir_prefix = $postImagePath.$postfix."/"; //预定义的本地保存图片的文件夹,根据需要改变
$url_prefix = $postImageUrlBase.$postfix."/"; //预定义的url前缀,根据需要改变
//echo $url_prefix;
//新建保存图片的文件夹
if(!file_exists($dir_prefix)){
mkdir($dir_prefix, 0777, true);
}
//随机生成图片文件名
$arr = split("[/\\.]", $image_url);
$ext = '.'.$arr[count($arr) - 1];
$file_name = substr(sha1(date('Y-m-d H:i:s') . rand(0,1000)), 0, 5) .rand_str(5) . $ext;
//使用http_get_file函数得到远程图片文件,并保存到本地
$file = http_get_file($image_url);
file_put_contents($dir_prefix . $file_name, $file);
//通过str_replace函数替换掉原始img标签中的src属性/
return str_replace($image_url, $url_prefix . $file_name, $image_tag);
}
最后,定义获取图片的函数,也可以使用discuz中的dfopen函数。
function http_get_file($url){
$url_stuff = parse_url($url);
$port = isset($url_stuff['port']) ? $url_stuff['port']:80;
$fp = fsockopen($url_stuff['host'], $port);
$query = 'GET ' . $url_stuff['path'] . " HTTP/1.0\n";
$query .= 'Host: ' . $url_stuff['host'];
$query .= "\n\n";
fwrite($fp, $query);
while ($line = fread($fp, 1024)) {
$buffer .= $line;
}
preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
return substr($buffer, - $parts[1]);
}
另外中间会用到的还有生成指点数目的随机字符串:
function rand_str($size=6,$feed="abcdefghijklmnopqrstuvwxyz0123456789"){
for ($i=0; $i < $size; $i++) {
$rand_str .= substr($feed, rand() % strlen($feed), 1);
}
return $rand_str;
}
整个方法如上,高手可以将上述修改为 WordPress插件,Discuz插件,PHPWind插件等。




