curlの同時メカニズムによるphp一括ダウンロード

4932 ワード

<?php

class Download {

    /**
     *       ,   
     * @var int
     */
    public $_timeout = 20;

    /**
     *       
     * note:      “/”   
     * @var string
     */
    private $_savePath = './';

    /**
     *       
     * @param int $second    
     */
    public function setTimeout($second) {
        $this->_timeout = intval($second);
    }

    /**
     *       
     * @param $path
     */
    public function setSavePath($path) {
        $this->_savePath = $path;
    }

    /**
     * curl      
     * @param array $urls     
     * @param string $callback     
     * @return array
     */
    public function multiDown(array $urls,$callback)
    {
        if (empty($urls)) {
            return array();
        }

        $urlsMap = array(); //  curl   url   
        $chs = curl_multi_init();
        foreach ($urls as $url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);               //    
            curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout); //      ,         ,         
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);       //   1,             
            curl_setopt($ch, CURLOPT_NOSIGNAL, true);          //    ,       
            curl_setopt($ch, CURLOPT_HEADER, 0);               //       
            curl_multi_add_handle($chs,$ch);
            $urlsMap[strval($ch)] = $url;
        }

        $active = null;
        $response = array(); //        
        do {
            if (curl_multi_exec($chs,$active) == CURLE_OK) {
                while ($done = curl_multi_info_read($chs)) {
                    $url = $urlsMap[strval($done['handle'])];
                    $args = $this->_getCurlDetail($done['handle'],$url);
                    if ($callback && method_exists($this,$callback)) {
                        $this->$callback($args);
                    }
                    $response[$url] = $args;
                    curl_multi_remove_handle($chs,$done['handle']);
                    curl_close($done['handle']);
                }
            }
        } while ($active > 0);

        curl_multi_close($chs);
        return $response;
    }

    /**
     *   curl  (  ,  ,  ,  url)
     * @param $ch curl  
     * @param $url
     * @return array
     */
    private function _getCurlDetail($ch,$url)
    {
        $args = array();

        if (empty($ch)) {
            return $args;
        }

        $args['error'] = curl_error($ch);
        $args['info'] = curl_getinfo($ch);
        $args['result'] = curl_multi_getcontent($ch);
        $args['url'] = $url;
        return $args;
    }

    /**
     *   curl    
     * @param $args
     */
    private function _dealData($args)
    {
        if (empty($args['error'])) {
            if ($args['info']['http_code'] == '200') {
                $color = 'green';
                file_put_contents($this->_getFilename($args['url']),$args['result']);
            } else {
                $color = 'orange';
            }
            $content = $args['url'].' -- '.$args['info']['http_code'];
        } else {
            $color = 'red';
            $content = $args['url'].' -- '.$args['error'];
        }

        $this->_showHtml($content,$args['url'],$color);
    }

    /**
     *        
     * @param $content
     * @param $url
     * @param $color
     */
    private function _showHtml($content,$url,$color)
    {
        echo '<li>';
        echo '<a href="'.$url.'" style="color: '.$color.'">'.$content.'</a>';
        echo '</li>';
    }

    /**
     *   url     
     * note:         url    ,         
     * @param $url
     * @param string $ext      ,   zip
     * @param bool $isRename       
     * @return string
     */
    private function _getFilename($url,$ext = '.zip',$isRename = true)
    {
        if ($filename = strrchr($url,'/')) {
            if (strpos($filename,'.') === false) {
                $filename = rand(1,99999).$ext;
            }
        }
        $filename = $this->_savePath.$filename;
        if (file_exists($filename) && $isRename) {
            $filename .= rand(1,9999);
        }
        return $filename;
    }
}


//    
$download = new Download();

//    
$urls = array(
    'http://img.my.csdn.net/uploads/201212/28/1356680367_3703.jpg',
    'http://newtab.firefoxchina.cn/img/sitenav/logo.png',
);
$download->setTimeout(10);
$download->setSavePath('./');
$result = $download->multiDown($urls,'_dealData');
//var_dump($result);

参考ブログ:http://www.eer3.com/article/artdetails/40.htm