zoukankan      html  css  js  c++  java
  • 【PHP开发】远程文件(图片)下载

      这一篇文章介绍的方法不算原创了,只是引用的别人的文章,加上自己的注释,因为接触php时间不长,所以尝试的东西比较多,自己加的注释也比较简单,php高手请略过。

      我要用到远程下载图片,是在做微信公众平台开发中“微信墙”这个子任务时遇到的,该需求中需要显示用户的头像,对于一般订阅号来说,我们在服务端拿到用户发送的消息时,是无法获得用户的名字、头像路径等基本信息的,我想到的解决方法主要有二:

      1. 自己建一个用户表,用来存储微信一般消息里包含的用户名(FromUserName)和该用户真实名字以及该用户fakeid的对应关系,,实验发现,用户的FromUserName是一个和用户、公众平台微信号有关的字符串,具体生成策略不清楚,同一个用户往不同公众号上发消息,FromUserName是不同的,而每一个用户则对应唯一的fakeid,根据用户的fakeid,可以拼出头像url的地址,在我们的服务端收到用户发送的消息的时候,检查本地用户表中是否存有该FromUserName用户的真实信息,如果有,直接保存该条消息,如果没有,则模拟登陆微信公众平台的后台,拉取最近的新消息列表,比对得知该用户的用户名和fakeid,对于服务号来说,微信提供了接口来获取用户头像,但对于普通订阅号,只能根据用户的fakeid来拿头像,而且,这个头像必须是已登录用户才能访问的,为了防止模拟登陆中session超时等一系列问题,我就在模拟登陆拉用户信息的时候,直接将他的头像下载到本地保存。

      2. 另一种思路是,不在收到用户消息的时候触发模拟登陆微信号后台的操作,而是定时地去微信后台拉取数据,根据lastmsgid,将最新的消息存到本地数据库,当然存储用户信息的方式,和前文介绍的相同。

      不管用哪一种思路(实际中我用的是第一种),我都需要远程下载用户头像,因为之前没有接触过php,这个需求的解决,就google来解决了,测试代码如下:

    <?php
    function download($url, $cookie="", $file="", $timeout=60) {
        $file = empty($file) ? pathinfo($url, PATHINFO_BASENAME) : $file;
        $dir = pathinfo($file, PATHINFO_DIRNAME);
        !is_dir($dir) && @mkdir($dir,0755,true);
        $url = str_replace(" ","%20",$url);
    
        if(function_exists('curl_init')) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ch, CURLOPT_COOKIE, $cookie);
            $temp = curl_exec($ch);
            if(@file_put_contents($file, $temp) && !curl_error($ch)) {
                return $file;
            } else {
                return false;
            }
        } else {
            $opts = array(
                "http"=>array(
                "method"=>"GET",
                "header"=>"",
                "timeout"=>$timeout)
            );
            $context = stream_context_create($opts);
            if(@copy($url, $file, $context)) {
                //$http_response_header
                return $file;
            } else {
                return false;
            }
        }
    }
    $url = 'http://www.google.com.hk/images/srpr/logo11w.png';
    echo download($url, '', $_SERVER['DOCUMENT_ROOT'] . '/Public/google.png');

      该函数的四个参数,分别是要下载头像的url,cookie串,保存到哪个目录下(本机的绝对路径,使用$_SERVER['DOCUMENT_ROOT']获取Web根目录在本机的位置),请求超时时间,该代码的逐行解释如下:

    // 如果没有指定保存路径,则把url中的文件名作为保存后的文件名
    $file = empty($file) ? pathinfo($url, PATHINFO_BASENAME) : $file;
    // 如果没有指定保存路径,或指定了保存的文件名但没有目录,则使用当前目录'.',若指定了则使用指定目录
    $dir = pathinfo($file, PATHINFO_DIRNAME);
    // 如果该目录不存在,则递归(第三个参数)创建该目录,权限为755,windows中,权限这个参数是被忽略的
    // php中在函数名前+@来抑制函数的错误输出
    !is_dir($dir) && @mkdir($dir, 0755, true);
    // 将url中的空格使用url编码来进行编码
    $url = str_replace(" ","%20",$url);

      如果启用了curl则执行以下代码,因为一般php都会开启curl,所以else里的代码我没有验证,在这里只说使用curl方法的,curl的方法在性能上要略优于file_get_contents:

    // 初始化curl,指定目标url、超时时间、要求返回数据和cookie(a=111&b=222的形式)
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    // 执行curl,拉取数据
    $temp = curl_exec($ch);
    // 将返回的数据写入文件,如果写入的字节数不为0且curl未发生错误,则返回文件路径或文件名
    if(@file_put_contents($file, $temp) && !curl_error($ch)) {
        return $file;
    }

      至此,下载操作完成,该方法来源:PHP代码实现远程下载文件到本地的函数

  • 相关阅读:
    docker 的基本使用
    yum 工具安装的程序默认目录与位置
    Tampermonkey 脚本记录
    Windows 安装配置sublime-text3与破解
    heidisql 轻量级工具
    ubuntu 系统配置静态IP地址
    linux 日志分析
    Windows 桌面整理工具
    高效实用Linux命令行
    物联网实验4 alljoyn物联网实验之手机局域网控制设备
  • 原文地址:https://www.cnblogs.com/smarterplanet/p/3531776.html
Copyright © 2011-2022 走看看