zoukankan      html  css  js  c++  java
  • 分享一个PHP下载远程图片的函数

    /**
     * 抓取远程图片
     *
     * @param string $url 远程图片路径
     * @param string $filename 本地存储文件名
     */
    function grabImage($url, $filename = '') {
        if($url == '') {
            return false; //如果 $url 为空则返回 false;
        }
        $ext_name = strrchr($url, '.'); //获取图片的扩展名
        if($ext_name != '.gif' && $ext_name != '.jpg' && $ext_name != '.bmp' && $ext_name != '.png') {
            return false; //格式不在允许的范围
        }
        if($filename == '') {
            $filename = time().$ext_name; //以时间戳另起名
        }
        //开始捕获
        ob_start();
        readfile($url);
        $img_data = ob_get_contents();
        ob_end_clean();
        $size = strlen($img_data);
        $local_file = fopen($filename , 'a');
        fwrite($local_file, $img_data);
        fclose($local_file);
        return $filename;
    }
    

    上面的函数有几个缺点:

    1.不能自动识别图片后缀名(很多图片的url并不指向一个静态图片地址,而是直接将图片流输出到客户端)

    2.不支持图片url的302跳转 

    这个函数并不符合本人项目的需求,于是花了点时间自己写了一个下载函数,此函数支持:

    1.静态图片下载

    2.服务端直接输出图片流下载

    3.服务端使用302跳转到真实图片地址的下载(可限定跳转次数)

    函数代码如下:

    /**
         * 下载远程图片
         * @param string $url 图片的绝对url
         * @param string $filepath 文件的完整路径(包括目录,不包括后缀名,例如/www/images/test) ,此函数会自动根据图片url和http头信息确定图片的后缀名
         * @return mixed 下载成功返回一个描述图片信息的数组,下载失败则返回false
         */
        function downloadImage($url, $filepath) {
            //服务器返回的头信息
            $responseHeaders = array();
            //原始图片名
            $originalfilename = '';
            //图片的后缀名
            $ext = '';
            $ch = curl_init($url);
            //设置curl_exec返回的值包含Http头
            curl_setopt($ch, CURLOPT_HEADER, 1);
            //设置curl_exec返回的值包含Http内容
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        
            //设置抓取跳转(http 301,302)后的页面
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            //设置最多的HTTP重定向的数量
            curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
    
            //服务器返回的数据(包括http头信息和内容)
            $html = curl_exec($ch);
            //获取此次抓取的相关信息
            $httpinfo = curl_getinfo($ch);
            curl_close($ch);
            if ($html !== false) {
                //分离response的header和body,由于服务器可能使用了302跳转,所以此处需要将字符串分离为 2+跳转次数 个子串
                $httpArr = explode("\r\n\r\n", $html, 2 + $httpinfo['redirect_count']);
                //倒数第二段是服务器最后一次response的http头
                $header = $httpArr[count($httpArr) - 2];
                //倒数第一段是服务器最后一次response的内容
                $body = $httpArr[count($httpArr) - 1];
                $header.="\r\n";
    
                //获取最后一次response的header信息
                preg_match_all('/([a-z0-9-_]+):\s*([^\r\n]+)\r\n/i', $header, $matches);
                if (!empty($matches) && count($matches) == 3 && !empty($matches[1]) && !empty($matches[1])) {
                    for ($i = 0; $i < count($matches[1]); $i++) {
                        if (array_key_exists($i, $matches[2])) {
                            $responseHeaders[$matches[1][$i]] = $matches[2][$i];
                        }
                    }
                }
                //获取图片后缀名
                if (0 < preg_match('{(?:[^\/\\\\]+)\.(jpg|jpeg|gif|png|bmp)$}i', $url, $matches)) {
                    $originalfilename = $matches[0];
                    $ext = $matches[1];
                } else {
                    if (array_key_exists('Content-Type', $responseHeaders)) {
                        if (0 < preg_match('{image/(\w+)}i', $responseHeaders['Content-Type'], $extmatches)) {
                            $ext = $extmatches[1];
                        }
                    }
                }
                //保存文件
                if (!empty($ext)) {
                    $filepath .= ".$ext";
                    //如果目录不存在,则先要创建目录
                    CFiles::createDirectory(dirname($filepath));
                    $local_file = fopen($filepath, 'w');
                    if (false !== $local_file) {
                        if (false !== fwrite($local_file, $body)) {
                            fclose($local_file);
                            $sizeinfo = getimagesize($filepath);
                            return array('filepath' => realpath($filepath), 'width' => $sizeinfo[0], 'height' => $sizeinfo[1], 'orginalfilename' => $originalfilename, 'filename' => pathinfo($filepath, PATHINFO_BASENAME));
                        }
                    }
                }
            }
            return false;
        }
    
    正在学习wp7
  • 相关阅读:
    爬取豆瓣分页照片下载
    css布局:三列布局,中间内容优先加载
    解决在IE下label中IMG图片无法选中radio的几个方法
    CSS架构:最新最佳实践
    JavaScript登陆弹窗,可拖拽
    网站变成灰色的代码
    5个jQuery的备选轻量级移动客户端开发(Mobile development)类库
    jQuery 底部漂浮导航当前位置突出 + 锚点平滑滚动
    Exchange 2007 自定义传输规则
    基于jQuery打造TabPanel
  • 原文地址:https://www.cnblogs.com/Toeasy/p/2658643.html
Copyright © 2011-2022 走看看