• php curl封装类


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

    <?php
    namespace iphpcore;
    use iphpApp;
    /**
     * 封装了的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 iphpcollectlive;
    
    use iphpcommonMyFunctions;
    
    /**
     * 基于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;
    	}
    }
    
  • 相关阅读:
    [Dijkstra+堆优化]
    沈阳市 全国 沈阳市社会保险经办机构 信息查询 办保险用
    MS SQL 启用标识插入
    DataGridView导出到Word
    sql生成一个日期表
    精通BIRT:Eclipse商务智能报表工具开发实践指南
    BIRT-商务智能报表工具开发案例指南
    网页状态码
    javascript变量的作用域
    KAL1 LINUX 官方文档之工具---kali工具
  • 原文地址:https://www.cnblogs.com/xyloo/p/4250236.html
Copyright © 2020-2023  润新知