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

#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的添加永久静态路由的static-routes方法

    一:使用 route 命令添加 使用route 命令添加的路由,机器重启或者网卡重启后路由就失效了,方法: //添加到主机的路由 # route add –host 192.168.1.11 dev ...

  2. eclipse 如何对maven项目进行打包?

      eclipse 如何对maven项目进行打包? CreateTime--2018年4月19日22:02:50 Author:Marydon 1.方式一:使用eclipse中的maven插件(命令) ...

  3. ORA-22828 输入样式或替换參数超过了32k限制大小

    今天调试程序报下面错误: ORA-22828: input pattern or replacement parameters exceed 32K size limit 22828. 00000 - ...

  4. Python之对象的属性

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python之对象的属性 #http://python.jobbole.com/82622/ #对象的属性 ...

  5. 如何让bat,cmd文件后台运行?如何把文件打包成EXE?

    方法1:在“运行”中输入IEXPRESS        这是WINDOWS自带的打包程序,好像也可以生成安装包. 下一步-下一步-随便填个名字(下一步)-下一步-下一步-ADD(选好你的BAT文件 继 ...

  6. 【微信小程序】:客服消息教程

    1.本教程完全链接W3Cschool的教程,已经讲的非常清晰和透彻. 2.链接:https://www.w3cschool.cn/weixinapp/weixinapp-api-custommsg-c ...

  7. 让 linux centos 文件夹地址栏 位置栏显示出来的方法

    今天又拿起心爱的 linux ,发现多日不用又忘记了不少知识了    , 发现忘记的速度真是惊人的! 设置方法: 编辑-> 首选项-> 勾选 总是在浏览器窗口中打开,  如图:

  8. getsockopt和accept需要注意的两个细节

    1,getsockopt连续调用问题 通常情况下,在一个socket fd上出现错误时,我们会通过 int status; socklen_t slen; getsockopt(fd, SOL_SOC ...

  9. 程序安装制作不用愁—Wise installation入门教程

    http://blog.csdn.net/terryzero/article/details/6731925最近有个项目需要把别人的工具包装集成下,所以就随便找了个制作安装的工具,正好找到了Wise ...

  10. C语言宏高级用法

    1.前言  今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜.如是上网google一下,顺便总结一下,方便以后学习和运用.C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简 ...