php下载功能实现

PHP下载远程文件可以通过多种方式。如果下载链接直接对应于远程文件,使用fopen($url, 'rb');返回句柄读取即可。

Warning: 注意设置fopen的timeout;注意判断句柄是否为空。

 1 function download($src, $dst) 
 2 {   
 3     $timeout = 100;
 4     $old = ini_set('default_socket_timeout', $timeout);
 5     $srcH = fopen($src, "rb");
 6     ini_set('default_socket_timeout', $old);
 7     if(!$srcH){
 8         fclose($srcH);
 9         Util::log($src. " not exists!");
10         return false;
11     }   
12     $dstH = fopen($dst, "wb");
13     # file open error. filePath not exists.
14     if(!$dstH) {
15         $dirname = dirname($dst);
16         if(!file_exists($dirname)) {
17             mkdir($dirname);
18         }   
19         $dstH = fopen($dst, "wb");
20     }   
21     while (!feof($srcH)) {
22         $part = fread($srcH, 65535);
23         fwrite($dstH, $part);
24     }   
25     fclose($srcH);
26     fclose($dstH);
27     return true;
28 } 

有些时候,网站会释放一个下载地址查询接口,访问接口查询到真实下载地址,通过302跳转到下载地址,完成下载。

function download($src, $dst) 
{   
    $ch = curl_init($src);
    $dstH = fopen($dst, "wb");
    # 判断路径是否存在
    if(!$dstH) {
        $dirname = dirname($dst);
        if(!file_exists($dirname)) {
            mkdir($dirname);
        }   
        $dstH = fopen($dst, "wb");
    }   
    curl_setopt($ch, CURLOPT_FILE, $dstH);
    curl_setopt($ch, CURL_HEADER, 0); 
    # 这个参数非常重要。
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    $result = curl_exec($ch);
    $ret['curl_info']  = curl_getinfo($ch);
    if($result === false || $ret['curl_info']['http_code']!=200){
        $ret['curl_errno'] = curl_errno($ch);
        $ret['curl_error'] = curl_error($ch);
        Util::log(var_export($ret, true));
        $result = false;
    }   
    curl_close($ch);
    fclose($dstH);
    return $result;
} 

 

开发期间需要开发一个下载功能。首先完成第一版,但是使用fopen有一个严重问题。很多下载地址是一个302跳转,fopen无法继续打开后续的跳转地址,在第一地址,fopen失败。

curl中有一个重要参数CURLOPT_FOLLOWLOCATION: 启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。

加入这个参数,遇到302跳转,会继续访问跳转地址,直到遇到非302,从而获得真正的下载地址,进行下载。

 

posted @ 2013-07-17 11:36  代码会说话  阅读(324)  评论(0编辑  收藏  举报