写了一天,就写了这么点代码,凑合用吧。

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

php下载图片到本地的更多相关文章

  1. 通过scrapy内置的ImagePipeline下载图片到本地、并提取本地保存地址

    1.通过scrapy内置的ImagePipeline下载图片到本地 2.获取图片保存本地的地址 1.通过scrapy内置的ImagePipeline下载图片到本地 1)在settings.py中打开  ...

  2. scrapy中的ImagePipeline下载图片到本地、并提取本地的保存地址

    通过scrapy内置到ImagePipeline下载图片到本地 在settings中打开 ITEM_PIPELINES的注释,并在这里面加入 'scrapy.pipelines.images.Imag ...

  3. 通过HttpURLConnection下载图片到本地--下载附件

    一.背景说明 现在我做的系统中,需要有一个下载附件的功能,其实就是下载图片到本地中.相应的图片保存在多媒体系统中,我们只能拿到它的资源地址(url),而不是真实的文件. 这里记录的是下载单个图片.下篇 ...

  4. 利用node来下载图片到本地

      本文是针对于知道图片地址的下载图片方法. 同时也是我的处男作(额,怪怪的〜);不要在意这些细节. 最近在弄项目迁移,需要把http的链接全换成https的:以前的cms不支持http的协议,然后就 ...

  5. URL地址下载图片到本地

    package test.dao; import eh.base.dao.DoctorDAO; import eh.entity.base.Doctor; import junit.framework ...

  6. python3 中自带urllib库可下载图片到本地

    刚从python3下载图片的语句python2的不太一样,具体python3语句如下: form urllib import request jpg_link = '......'  #图片链接 re ...

  7. java从网络中下载图片到本地

    public class imageDownload { public static void main(String[] args) { String url = "http://loca ...

  8. QT通过url下载图片到本地

    /* strUrl:下载图片时需要的url strFilePath:下载图片的位置(/home/XXX/YYY.png) */ void ThorPromote::downloadFileFromUr ...

  9. java根据图片的url地址下载图片到本地

    package com.daojia.haobo.aicircle.util; import sun.misc.BASE64Encoder; import java.io.*; import java ...

随机推荐

  1. 〖Linux〗使用gsoap搭建web server(C)

    1. gsoap的好处就不用说了:百度百科 2. gsoap的下载地址:项目地址,目前我使用的是2.8.15版本 3. 开发环境:Ubuntu13.10 4. 具体操作步骤(以简单相加为例): 1) ...

  2. 对opencv MeanShift 融合矩形框的改进

    OPENCV 中的代码改进.当然要依据自己的实际情况来,OPENCV 中行人检測有两种矩形框的融合算法.这里仅仅对meanshift 方法做改进 假设有更好的方法.希望能够跟我讲下. 对于去除重合部分 ...

  3. 使用 Jenkins 实现软件开发的持续集成

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-jenkinsintegrate/ Jenkins 是一种易于使用的持续集成系统,它可以使开发者从繁 ...

  4. 路径,通过navigation可以查看 *.class文件

    ?.class文件内的代码所在的文件的路径默认 举例1:读取项目根目录下的数据. private static void readRoot() throws FileNotFoundException ...

  5. js setAttribute removeAttribute

    <input type="button" value="生效" style="font-size:111px"/> <sc ...

  6. ArchLinux新版本(pacstrap安装)及国内较优源推荐

    下载安装镜像和配置虚拟机都略过. 进入安装模式以后第一件事是要进行分区,分区很重要,怎么分区是由后面的grub的模式来决定的.grub有3种模式,分别对应grub-bios-gpt,grub-bios ...

  7. Lucene的索引不跨平台

    在windows上使用Lucene生成索引文件,将索引文件复制到Linux服务器上,报错"校验错误,可能是硬件问题". 所以,Lucene的跨平台只是代码跨平台,生成的索引不跨平台 ...

  8. HTML:减少页面加载时间的方法

    1. 重复的HTTP请求数量应尽量减少 (1)减少调用其他页面.文件的数量. (2)在使用css格式时,常会采用background载入图形文件,而每个background的图像都会产生1次HTTP ...

  9. ASP.NET中UrlEncode应该用Uri.EscapeDataString()

    今天,茄子_2008反馈他博客中的“C++”标签失效.检查了一下代码,生成链接时用的是HttpUtility.UrlEncode(url),从链接地址获取标签时用的是HttpUtility.UrlDe ...

  10. 【jQuery】清空表单内容

    function resertForm(){ $(':input','#formId') .not(':button, :submit, :reset, :hidden') .val('') .rem ...