写了一天,就写了这么点代码,凑合用吧。
#saveImage.php
<?php /** * 图片下载方法,提供两种图片保存方式: * 1.按照图片自带的名称保存 * 2.按照自定义文件名保存 * 其中使用自带的文件名的方式中有两种获取文件名的方式: * 1.如果图片URL中包含文件名,则直接使用图片中的文件名 * 2.否则,如果图片的响应头信息中包含文件名信息,使用该文件名 * 获取文件扩展名有两种方式: * 1.如果图片的响应头信息中包含图片类型信息,直接使用类型信息作为扩展名 * 如:Content-Type: image/jpeg,这时候会使用jpeg作为文件扩展名 * 2.如果文件URL地址中包含扩展名,则使用URL中的扩展名 * * 使用的时候直接调用saveImage() * * 以下是一个例子,涉及三个参数: * $url 图片地址 * $path 图片存储路径 * $file_name 图片名称 * * 如果不需要指定文件名则可以只传前两个参数: * saveImage($url, $path); * 如果需要指定文件名则需要三个参数同时传: * saveImage($url, $path, $file_name); * @author lrx2005123@sina.com */ /** * 获取图片名称 * @param string $url 图片的地址 * @param string $header 图片的响应头信息 * @return string 返回文件名或空 */ function getImgName($url, $header) { $image_name = ''; /* 从URL中获取文件名 */ $tmp_name = getNameFromURL($url); /* URL中不包含文件名 */ if (empty ($tmp_name)) { $tmp_name = getNameFromHeader ($header); } /* 文件名不为空 */ if (!empty ($tmp_name)) { /* 但是文件名中不包含扩展名 */ if(!strpos ($tmp_name, '.')) { $tmp_ext = getExt ($url, $header); /* 从头信息中获取的文件扩展名不为空 */ if (!empty ($tmp_ext)) { $image_name = sprintf("%s.%s", $tmp_name, $tmp_ext); } } /* 文件名中包含扩站名 */ else { $image_name = $tmp_name; } } /* 头信息中没有文件名 */ else { $image_name = ''; } return $image_name; } /** * 获取图片的扩展名,先通过分析响应头信息中的Content-type的信息来确定 * 然后通过分析图片的地址URL来获取扩展名 * @param string $url 图片的地址 * @param string $header 图片的响应头信息 * @return string 返回扩展名或空 */ function getExt($url, $header) { $file_ext = ''; $file_ext = getExtFromHeader ($header); if (empty ($file_ext)) { $file_ext = getExtFromURL ($url); } return $file_ext; } /** * 通过分析图片的地址URL来获取扩展名 * @param string $url 图片的地址 * @return string 返回扩展名或空 */ function getExtFromURL($url) { $name = getNameFromURL ($url); $ext = ''; if (!empty ($name) && strpos ($name, '.') !== false) { $ext = substr ($name, strrpos ($name, '.')); } return $ext; } /** * 通过图片地址URL获取图片名称 * @param string $url 图片地址 * @return string 返回文件名或空 */ function getNameFromURL($url) { $name = ''; /* URL中包含文件名 */ if (preg_match ('/\/([^\/]+\.[a-z]{3,4})(\?.*?)?$/i',$url, $matches)) { $name = $matches[1] ? trim ($matches[1]) : ''; } return $name; } /** * 通过分析响应头信息中的Content-type的信息获取扩展名 * @param string $header 图片的响应头信息 * @return string 返回扩展名或空 */ function getExtFromHeader($header) { $file_ext = ''; if (preg_match ('/Content-Type: image\/(.*?)\n/', $header, $matches)) { $file_ext = $matches[1] ? trim ($matches[1]) : ''; } return $file_ext; } /** * 通过分析图片响应头信息获取图片名称 * @param string $header 图片的响应头信息 * @return string 返回文件名或空 */ function getNameFromHeader($header) { $file_name = ''; if (preg_match('/Content-Disposition:.*?filename="([^"]+)".*?\n/', $header, $matches)) { $file_name = $matches[1] ? trim($matches[1]) : ''; } return $file_name; } /** * 入口方法,通过图片URL地址获取图片信息并下载图片到本地 * @param string $url 图片地址 * @param string $path 图片下载路径 * @param string $file_name 图片自定义名称 default '' * @return bool */ function saveImage($url, $path, $file_name = '') { $handle = curl_init ($url); /* 显示响应头信息 */ curl_setopt ($handle, CURLOPT_HEADER, true); curl_setopt ($handle, CURLOPT_RETURNTRANSFER, 1); $img = curl_exec ($handle); $file_size = curl_getinfo ($handle, CURLINFO_SIZE_DOWNLOAD); $http_code = curl_getinfo ($handle, CURLINFO_HTTP_CODE); curl_close ($handle); list ($header, $body) = explode ("\r\n\r\n", $img, 2); wlog ("http code: $http_code"); if ($http_code == 301 || $http_code == 302) { wlog ("[$url]重定向..."); $matches = array(); if (!preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches)) { wlog ('解析头信息失败,结束。'); return false; } $redirect_url = trim (array_pop ($matches)); $url_parsed = parse_url ($redirect_url); if (isset ($url_parsed)) { wlog ("已获取重定向地址[$redirect_url],\n正在跳转..."); return saveImage ($redirect_url, $path, $file_name); } else { wlog ('获取重定向地址失败,结束。'); return false; } } elseif ($http_code == 200) { wlog ('请求成功...'); } else { wlog ('无效的请求,结束。'); return false; } if (!empty ($file_name)) { $file_ext = getExt ($url, $header); if (empty ($file_ext)) { wlog ('无效的图片地址!'); return false; } $image_name = sprintf ("%s.%s", $file_name, trim($file_ext)); } else { $image_name = getImgName ($url, $header); if (empty($image_name)) { wlog ('无效的图片地址!'); return false; } } if (!file_exists ($path)) { wlog ("目录$path不存在,正在创建..."); if (mkdir ($path)) { wlog ('目录创建成功...'); } else { wlog ('目录创建失败,结束。'); return false; } } $file_path = rtrim ($path, '/') . '/' . $image_name; $fp = fopen ($file_path, 'w'); $length = fwrite ($fp, $body); fclose ($fp); if ($length) { wlog ("文件保存成功!\n大小: $length\n位置: $file_path"); } else { wlog ('文件保存失败。'); return false; } return true; } /** * 记录日志方法 * @param string $msg * @param string $path default '' */ function wlog ($msg, $path = '') { if (empty ($path)) { $path = 'log/save_img.log'; } if (!file_exists (dirname ($path))) { if (!mkdir (dirname ($path))) { die('can not create directory' . dirname ($path)); } } $fp = @fopen ($path, 'a'); flock ($fp, LOCK_EX); fwrite ($fp, $msg . "\n"); flock ($fp, LOCK_UN); fclose ($fp); }
调用的时候直接用saveImage($url, $path)就可以了。
写了个测试的脚本,把常用的图片格式都试了一遍,都可以通过
#test.php
<?php
define('PATH', 'download/');
//require('class_inc/downloadImg.php');
require('class_inc/saveImage.php');
$img_list = ['png' => 'http://www.freepngimg.com/download/facebook/1-2-facebook-download-png.png',
'gif' => 'https://kanimg.9ku.com/Article/20170725/1500953725469381.gif',
'jpg & redirect' => 'http://pic2116.ytqmx.com:82/2017/0725/37/4.jpg',
'jpeg' => 'https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Soviet_BMP-1_IFV.JPEG/300px-Soviet_BMP-1_IFV.JPEG',
'gif' => 'http://n.sinaimg.cn/sports/transform/20170906/W34l-fykpyua5747968.gif',
'jpg with params' => 'http://img.freepik.com/free-icon/bmp-image-file-type-outlined-interface-symbol_318-72075.jpg?size=338&ext=jpg',
'webp' => 'http://www.gstatic.com/webp/gallery/1.webp',
'bmp' => 'http://samples.fileformat.info/format/bmp/sample/4cb74cda027a43f3b278c05c3770950f/MARBLES.BMP?AWSAccessKeyId=0V91BEFA7GM093MEVMG2&Signature=t18N8JiZUw0QOd%2FZcyK8oZAwUWk%3D&Expires=1505213123',
'bmp1' => 'http://cfile8.uf.tistory.com/image/167475304C879B427393BA'
];
foreach ($img_list as $type => $url)
{
echo "download image $type:";
$file_name = md5($url);
if (saveImage($url, PATH, $file_name))
{
echo "done\n";
}
else
{
echo "failed\n";
}
}