php curl封装类

一个php curl封装的类,减少代码量,简化采集工作。这个类也是我工作的最常用的类之一。这里分享给大家。配合上phpquery,十分好用。

 

<?php

namespace iphp\core;

use iphp\App;

/**

 * 封装了的curl http请求类

 * @author xuen

 */

class MyCurl

{

    public $ch; // 当前链接对象

    public $str = ''; // 当前串

    public $match; // 正则表达式

    /**

     * 将curl常量属性转变成一个数组,便于使用

     * @var string

     */

    public $defaultOpt = array(

        CURLOPT_URL => '', // 请求的URL

        CURLOPT_RETURNTRANSFER => 1, // 设置有返回信息,以流的形式返回,非不是直接输出

        CURLOPT_HTTPGET => 1, // 设定为GET请求。

        // 定义默认的回调函数,这样exec()将在成功后返回1

        CURLOPT_CONNECTTIMEOUT => 30, // 设置默认链接超时间为30秒

        CURLOPT_TIMEOUT=>30,//设置下载时间最多30秒。

        // 自动跟踪重定向。

        CURLOPT_FOLLOWLOCATION => true,

        // 设置客户端支持gzip压缩,默认不开启,用于节省流量。

        CURLOPT_ENCODING => 'gzip',

        // 设定默认header头

        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0'

    );

    

    public $opt;

    

    public $cookieFile = false; // 保存的COOKIE文件

    /**

     * http请求响应的缓存,默认缓存在数组中,最大为512个

     * @var array

     */

    public $cache = array();



    public function __construct ()

    {

        // 完成CH的初始化

        $this->ch = curl_init();

        if (! $this->ch)

            die('当前环境不支持CURL');

        $this->opt=$this->defaultOpt;

    }

    // 执行HTTP请求,并得到返回数据

    // 返回指定匹配的串,如果匹配失败将返回全部文档

    public function exec ($opt)

    {

        //如查参数只是一个串,就认为是一个url

        if(!is_array($opt))

        {

            $url=$opt;

            $opt=array();

            $opt['url']=$url;

        }

        // 如果存在缓存,则返回缓存的字符串。

        $key = md5($opt['url'] . $opt['post'] . $opt['match']. $opt['return']);

        if (($str = $this->getCache($key)) != false)

            return $str;

            // 每次执行前,清空当前str,每次请求,返回值可能不一样

        $this->str = '';

        // 参数设置失败和执行行失败都将返回 fasle;

        if (! $this->setOptions($opt))

            return false;

        $flag = curl_exec($this->ch);

        $this->setCache($key, $this->str ? $this->str : $flag);

        

        //执行完成后,基于长驻内存和考虑,上一次连接的选项可以对下一次靠成影响

        $this->opt=$this->defaultOpt;

        

        if ($this->str == '') // 表示没有执行回调函数

            return $flag;

        else

            return $this->str;

    }

    

    /**

     * 简单封装的file_get_contents函数

     * 只是使用的缓存而已。

     */ 

    public function getContent ($url)

    {

        $key = md5($url);

        if (($str = $this->getCache($key)) != false)

            return $str;

        $str = file_get_contents($url);

        $this->setCache($key, $str);

        return $str;

    }

    // 设置CURL属性

    public function setOptions ($opt)

    {

        foreach ($opt as $key => $value) {

            // 以下值为可以设定的值。如果没有,将使用默认值;

            switch ($key) {

                case 'url': // 设定当前请求的URL

                    $this->opt[CURLOPT_URL] = $value;

                    break;

                case 'str': // 设定信息返方式,默认为1

                    $this->opt[CURLOPT_RETURNTRANSFER] = $value;

                    break; // 默认值也为1

                case 'method': // 设定请求方式,默认为POST

                    if ($value == 'get')

                        $this->opt[CURLOPT_HTTPGET] = 1; // 设为GET请求

                    elseif ($value == 'put')

                        $this->opt[CURLOPT_PUT] = 1; // ftp文件上传

                    else

                        $this->opt[CURLOPT_POST] = 1;

                    break;

                case 'post': // 设定POST请求主体,数组形式,如果上传文件,文件名前加@

                    $this->opt[CURLOPT_POSTFIELDS] = $value;

                    break;

                case 'header': // 设定HEADER请求头;默认不使用,数组形式

                    $this->opt[CURLOPT_HTTPHEADER] = $value;

                    break;

                case 'referer': // 设定REFERER信息,默认为空

                    $this->opt[CURLOPT_REFERER] = $value;

                    break;

                case 'auth': // 设定要请求的用户密码[username]:[password]

                    $this->opt[CURLOPT_USERPWD] = $value;

                    break;

                case 'connect_time': // 发起链接前的等待时间

                    $this->opt[CURLOPT_CONNECTTIMEOUT] = $value;

                    break;

                case 'load_time'://文件下载最长时间。

                    $this->opt[CURLOPT_TIMEOUT]=$value;

                    break;

                case 'callback': // 定义回调函数

                    $this->opt[CURLOPT_WRITEFUNCTION] = $value;

                    break;

                case 'match': // 寻找指定段的正则表达式

                    $this->opt[CURLOPT_WRITEFUNCTION] = array(

                        'self',

                        'callback'

                    );

                    $this->match = $value;

                case 'proxy':

                    $this->opt[CURLOPT_PROXY] = $value;

                    break;

                case 'file': // 用FTP上传的文件名柄

                    $this->opt[CURLOPT_VERBOSE] = 1;

                    $this->opt[CURLOPT_INFILE] = $value; // 上传句柄

                    $this->opt[CURLOPT_NOPROGRESS] = false;

                    $this->opt[CURLOPT_FTP_USE_EPRT] = true;

                    $this->opt[CURLOPT_FTP_USE_EPSV] = true;

                    break;

                case 'cookie_file': // 设置cookie文件。

                     $this->cookieFile =APP_PATH . '/runtime/cookie.txt';

                     // 发送COOKIE

                     $this->opt[CURLOPT_COOKIEFILE] = $this->cookieFile;

                     // 设置cookie

                    $this->opt[CURLOPT_COOKIEJAR] = $this->cookieFile;

                    break;

                case 'cookie'://设置访问cookie为一个字符串

                    $this->opt[CURLOPT_COOKIE]=$value;

                    break;

                case 'return': // 设定返回的类型

                    if ($value == 'head') // 表示只得到header头

                    {

                        $this->opt[CURLOPT_NOBODY] = 1;

                        $this->opt[CURLOPT_HEADER] = 1;

                    } 

                    elseif ($value == 'body') {}// 默认值,只返回body体

                    elseif ($value == 'all')

                        $this->opt[CURLOPT_HEADER] = 1;

                    break;

                case 'location'://是不是跟踪重定向

                    $this->opt[CURLOPT_FOLLOWLOCATION]=$value;

                    break;

                case 'client_type'://设定客户端类型

                    $this->setClientType($value);

                    break;

                case 'client_ip'://设定客户端IP地址,只是在header头,不是真实伪造

                    $this->opt[CURLOPT_HTTPHEADER][]='X-FORWARDED-FOR: '.$value;

                    $this->opt[CURLOPT_HTTPHEADER][]='CLIENT-IP: '.$value;

                    break;

            }

        }

        // 设定当前链接选项,选项设置失败返回false;

        return curl_setopt_array($this->ch, $this->opt);

    }

    // 回调函数,返回指定正则表达式的HTML段

    public function callback ($ch, $str)

    {

        $this->str .= $str;

        preg_match($this->match, $this->str, $match);

        if (! empty($match)) 

        {

            // 存在一个子模式,则返回这个子模式

            if (isset($match[1]))

                $this->str = $match[1];

            else

                $this->str = $match[0];

            return false; // 中断请求

        }

        return strlen($str);

    }



    /**

     * 得到当前请求的错误信息

     * @param int $type

     *  0表示得到错误编码,1表示得到错误信息,2表示得到所有信息

     * @return mixed

     */

    public function getError ($type = 11)

    {

        switch ($type) {

            case 0:

                $info = curl_errno($this->ch);

                break;

            case 1:

                $info = curl_error($this->ch);

                break;

            default:

                $info = curl_getinfo($this->ch);

        }

        return $info;

    }



    /**

     * 清除缓存。

     */

    public function __destruct ()

    {

        curl_close($this->ch);

        $this->cache = array();

    }



    /**

     * 设置缓存,以减少http请求数量。

     * 大量采集中,你应改使用重写此方法。

     * 默认将使用内存缓存

     * 如果缓存数组超过512个,清空数组缓存。

     * @param string $key            

     * @param string $str            

     * @return string boolean

     */

    public function setCache ($key, $str)

    {

        if(count($this->cache)>512)

            $this->cache=array();

        $this->cache[$key] = $str;

        

        //如果引入的phpquery对象

        if(class_exists('\\phpQuery') && count(\phpQuery::$documents)>512)

            \phpQuery::$documents=array();

    }



    /**

     * 得到缓存数据

     * 

     * @param string $key            

     * @return string boolean

     */

    public function getCache ($key)

    {

        if ($this->cache[$key])

            return $this->cache[$key];

        else

            return false;

    }

    /**

     * 调用远程http接口,返回一个数组

     * 当前只支持get请求

     * @param string $url

     * @param array $query get方式查询参数

     * 		其中两个参数为自定义参数

     * 		_method:为请求的类型

     * 		_type:为返回的数据类型,支持xml,json.

     * 		这两个参数不做查询字符串

     * @param array $type 返回的格式类型

     */

    public function getArray($url,$query=array())

    {

        $method=($query['_method']=='post')?'post':'get';

        $type = ($query['_type']=='xml')?'xml':'json';

    	if($query['_method'])

    	    unset($query['_method']);

    	if($query['_type'])

    	    unset($query['_type']);

    	if($method=='get')

    	{

    	    if($query)

    	        $nowUrl=$url.'?'.http_build_query($query);

    	    else 

    	        $nowUrl=$url;

    	    $str=$this->exec(array(

    		    	'url'=>$nowUrl,

    		    	'method'=>'get',

    		    ));

    	}

    	else 

    	    $str=$this->exec(array(

    	        'url'=>$url,

    	        'method'=>'post',

    	        'post'=>$query

    	    ));

    	if(!$str)

    	    return false;

		$arr=$this->toArray($str,$type);

		if(!$arr || !is_array($arr))

		    return false;

		return $arr;    	    

    }

    /**

     * 将一个{}格式的javasrcipt对象转变成一个php数组

     * 以避免过多的使用正则表达式。

     * 目前支持一维数组;

     * 如果js对像里面还有一个对象。可能会有问题。

     * 通常情况下,你应该在页面中只匹配一个JS对象。

     * @param string $str

     * @return array|bool

     */

    public function jsArray($str)

    {

        $return=array();

    	$str=str_replace(array(

    	    '"',

    	    "'",

    	    '{',

    	    '}'

    	), '', $str);

    	$arr=explode(',', $str);

    	foreach($arr as $row)

    	{

    		$tmpArr=explode(':', $row);

    		$return[trim($tmpArr[0])]=trim($tmpArr[1]);

    	}

    	return $return;

    }

    /**

     * 使用phpquery来进行html页面采集

     * @param unknown $str 字符串

     * @param string $query 选择器表达式

     * @return \phpQuery

     */

    public function getDom($str,$query='')

    {

        require_once APP_PATH.'/iphp/extension/phpQuery/phpQuery.php';

        $domObject=\phpQuery::newDocument($str);

        if($query=='')

            return $domObject;

        return pq($query);

    }

    

    /**

     * 将字符串转变成一个数组;

     * @param string $str 字符串

     * @param string $type 类型。

     * @return array|bool

     */

    public function toArray($str,$type="json")

    {

        if($type=='xml')

        {

            $doc=simplexml_load_string($str);

            $xml=App::getApp()->getXml();

            return $xml->getTreeArray($doc);

        }

        elseif($type=='json')

            return json_decode($str,true);

        elseif($type=='query')

        {

            $parse=parse_url($str);

            parse_str($parse['query'],$params);

            return $params;

        }

        elseif($type=='pathinfo')

        {

            	

        }

    }

    

    /**

     * 根据type类型默认浏览器客户端

     * @param type $type

     * iphone 表示iphone客户端,

     * pc 表示电脑客户客户端,

     * android 表示安卓客户端 

     */

    public function setClientType($type)

    {

    	$userAgent=array(

    	    'pc'=>'Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0',

    	    'iphone'=>'Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.10',

    	    'android'=>'Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'

    	);

    	if(array_key_exists($type,$userAgent))

    	    $this->opt[CURLOPT_USERAGENT]=$userAgent[$type];

    }

    

    //关闭当前资源连接

    public function close()

    {

        curl_close($this->ch);

    }

}

 使用示例:

<?php



namespace iphp\collect\live;



use iphp\common\MyFunctions;



/**

 * 基于http://m.iqilu.com/的直播地址解析

 * 只有流畅一个清晰度。

 *

 * @author 123

 *        

 */

class Iqilu extends LiveBase {

	// 入品地址,可以得到频道列表

	public $listUrl = 'http://v.iqilu.com/live/sdtv/';

	public $sourceName = 'iqilu';

	public function getList() {

		$lists = array (

				0 => array (

						'sdtv',

						'98/0',

						'山东卫视' 

				),

				1 => array (

						'qlpd',

						'98/1',

						'齐鲁频道' 

				),

				2 => array (

						'ggpd',

						'98/2',

						'公共频道' 

				),

				3 => array (

						'typd',

						'98/3',

						'体育频道' 

				),

				4 => array (

						'shpd',

						'99/2',

						'生活频道' 

				),

				5 => array (

						'zypd',

						'100/0',

						'综艺频道' 

				),

				6 => array (

						'nkpd',

						'99/0',

						'农科频道' 

				),

				7 => array (

						'yspd',

						'99/3',

						'影视频道' 

				),

				8 => array (

						'sepd',

						'99/1',

						'少儿频道' 

				),

				9 => array (

						'gjpd',

						'100/1',

						'国际频道' 

				)/*,

				10 => array (

						'dspd',

						'107/6',

						'读书频道' 

				) */

		);

		foreach ( $lists as $item ) {

			

			$vid = $item [0] . ',' . $item [1] . ',' . $item [2];

			$channel_name = $item [2];

			$link = $this->getAll ( $vid );

			

			$this->info [] = array (

					'channel_name' => $channel_name,

					'channel_link' => $link 

			);

		}

		return $this->info;

	}

	public function one($vid, $format) {

		$arr2 = explode ( ',', $vid );

		if ($format != 1) {

			return false;

		}

		

		$url = "http://huodong.iqilu.com/active/video/clientnew/public_s/?c=";

		

		$str = $this->curl->exec ( array (

				'url' => $url . $arr2 [0],

				'header' => array (

						'Host: huodong.iqilu.com',

						//'User-Agent: Android',

						//"Referer: http://v.iqilu.com/live/{$arr2[0]}/",

						'User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; Coolpad 8675 Build/KOT49H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.7.500 U3/0.8.0 Mobile Safari/534.30',

				),

				'referer' => "http://m.iqilu.com/vms/live/{$arr2[0]}/",

				'client_type' => "android"

						 

		) );

		$arr = explode('|', $str);

		$vid = "http://m3u8.iqilu.com/live/$arr2[1].m3u8?st=".$arr[16].$arr[17]."&e=".$arr[19].$arr[20];//&e={$arr[17]};



		return $vid;

	}

}

 

你可能感兴趣的:(curl)