zoukankan      html  css  js  c++  java
  • 基于php的Http请求类封装

    <?php
    
    /**
     *
     * @desc  HTTP 请求类, 支持 CURL 和 Socket, 默认使用 CURL , 当手动指定
     *                useCurl 或者 curl 扩展没有安装时, 会使用 Socket
     *                目前支持 get 和 post 两种请求方式
     *
     * 1. 基本 get 请求:
     *    $http = new Http();        // 实例化对象
     *    $result =  $http->get('http://weibo.com/at/comment');
     * 2. 基本 post 请求:
     *    $http = new Http();        // 实例化对象
     *    $result = $http->post('http://someurl.com/post-new-article', array('title'=>$title, 'body'=>$body) );
     * 3. 模拟登录 ( post 和 get 同时使用, 利用 cookie 存储状态 ) :
     *    $http = new Http();        // 实例化对象
     *    $http->setCookiepath(substr(md5($username), 0, 10));        // 设置 cookie, 如果是多个用户请求的话
     *    // 提交 post 数据
     *    $loginData = $http->post('http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.19)',
     *        array('username'=>$username, 'loginPass'=>$password) );
     *    $result =  $http->get('http://weibo.com/at/comment');
     * 4. 利用 initialize 函数设置多个 config 信息
     *    $httpConfig['method']     = 'GET';
     *    $httpConfig['target']     = 'http://www.somedomain.com/index.html';
     *    $httpConfig['referrer']   = 'http://www.somedomain.com';
     *    $httpConfig['user_agent'] = 'My Crawler';
     *    $httpConfig['timeout']    = '30';
     *    $httpConfig['params']     = array('var1' => 'testvalue', 'var2' => 'somevalue');
     *
     *    $http = new Http();
     *    $http->initialize($httpConfig);
     *
     *    $result = $http->result;
     *
     * 5. 复杂的设置:
     *
     *    $http = new Http();
     *    $http->useCurl(false);        // 不使用 curl
     *    $http->setMethod('POST');        // 使用 POST method
     *
     *    // 设置 POST 数据
     *    $http->addParam('user_name' , 'yourusername');
     *    $http->addParam('password'  , 'yourpassword');
     *
     *    // Referrer
     *    $http->setReferrer('https://yourproject.projectpath.com/login');
     *
     *    // 开始执行请求
     *    $http->execute('https://yourproject.projectpath.com/login/authenticate');
     *    $result = $http->getResult();
     *
     * 6. 获取开启了 basic auth 的请求
     *
     *    $http = new Http();
     *
     *    // Set HTTP basic authentication realms
     *    $http->setAuth('yourusername', 'yourpassword');
     *
     *    // 获取某个被保护的应用的 feed
     *    $http->get('http://www.someblog.com/protected/feed.xml');
     *
     *    $result = $http->result;
     *
     */
    class Http
    {
        /**  目标请求 @var string */
        var $target;
    
        /**  目标 URL 的 host @var string */
        var $host;
    
        /**  请求目标的端口 @var integer */
        var $port;
    
        /** 请求目标的 path @var string */
        var $path;
    
        /** 请求目标的 schema  @var string */
        var $schema;
    
        /** 请求的 method (GET 或者 POST)  @var string */
        var $method;
    
        /** 请求的数据  @var array */
        var $params;
    
        /**  请求时候的 cookie 数据  @var array */
        var $cookies;
    
        /**  请求返回的 cookie 数据 @var array */
        var $_cookies;
    
        /** 请求超时时间, 默认是 25 @var integer */
        var $timeout;
    
        /** 是否使用 cURL , 默认为 TRUE @var boolean */
        var $useCurl;
    
        /**   referrer 信息 @var string */
        var $referrer;
    
        /** 请求客户端 User agent  @var string */
        var $userAgent;
    
        /**  Contains the cookie path (to be used with cURL) @var string */
        var $cookiePath;
    
        /**  是否使用 Cookie @var boolean */
        var $useCookie;
    
        /** 是否为下一次请求保存 Cookie @var boolean */
        var $saveCookie;
    
        /** HTTP Basic Auth 用户名 (for authentication) @var string */
        var $username;
    
        /** HTTP Basic Auth 密码 (for authentication) @var string */
        var $password;
    
        /** 请求的结果集 @var string */
        var $result;
    
        /** 最后一个请求的 headers 信息  @var array */
        var $headers;
    
        /** Contains the last call's http status code @var string */
        var $status;
    
        /** 是否跟随 http redirect 跳转  @var boolean */
        var $redirect;
    
        /** 最大 http redirect 调整数 @var integer */
        var $maxRedirect;
    
        /** 当前请求有多少个 URL  @var integer */
        var $curRedirect;
    
        /** 错误代码 @var string */
        var $error;
    
        /** Store the next token  @var string */
        var $nextToken;
    
        /** 是否存储 bug 信息 @var boolean */
        var $debug;
    
        /** Stores the debug messages  @var array @todo will keep debug messages */
        var $debugMsg;
    
        /**  Constructor for initializing the class with default values. @return void */
        public function __construct()
        {
            // 先初始化
            $this->clear();
        }
    
        /**
         * 初始化配置信息
         * Initialize preferences
         *
         * This function will take an associative array of config values and
         * will initialize the class variables using them.
         *
         * Example use:
         *
         * <pre>
         * $httpConfig['method']     = 'GET';
         * $httpConfig['target']     = 'http://www.somedomain.com/index.html';
         * $httpConfig['referrer']   = 'http://www.somedomain.com';
         * $httpConfig['user_agent'] = 'My Crawler';
         * $httpConfig['timeout']    = '30';
         * $httpConfig['params']     = array('var1' => 'testvalue', 'var2' => 'somevalue');
         *
         * $http = new Http();
         * $http->initialize($httpConfig);
         * </pre>
         *
         * @param array Config values as associative array
         * @return void
         */
        public function initialize($config = array())
        {
            $this->clear();
            foreach ($config as $key => $val) {
                if (isset($this->$key)) {
                    $method = 'set' . ucfirst(str_replace('_', '', $key));
    
                    if (method_exists($this, $method)) {
                        $this->$method($val);
                    } else {
                        $this->$key = $val;
                    }
                }
            }
        }
    
        /**
         * 初始化所有
         *
         * Clears all the properties of the class and sets the object to
         * the beginning state. Very handy if you are doing subsequent calls
         * with different data.
         *
         * @return void
         */
        public function clear()
        {
            // Set the request defaults
            $this->host = '';
            $this->port = 0;
            $this->path = '';
            $this->target = '';
            $this->method = 'GET';
            $this->schema = 'http';
            $this->params = array();
            $this->headers = array();
            $this->cookies = array();
            $this->_cookies = array();
    
            // Set the config details
            $this->debug = FALSE;
            $this->error = '';
            $this->status = 0;
            $this->timeout = '25';
            $this->useCurl = TRUE;
            $this->referrer = '';
            $this->username = '';
            $this->password = '';
            $this->redirect = TRUE;
    
            // Set the cookie and agent defaults
            $this->nextToken = '';
            $this->useCookie = FALSE;
            $this->saveCookie = FALSE;
            $this->maxRedirect = 3;
            $this->cookiePath = 'cookie.txt';
            $this->userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7';
        }
    
        /** 设置目标 @return void */
        public function setTarget($url)
        {
            $this->target = $url;
        }
    
        /** 设置 http 请求方法  @param string HTTP method to use (GET or POST)  @return void */
        public function setMethod($method)
        {
            $this->method = $method;
        }
    
        /** 设置 referrer URL @param string URL of referrer page @return void */
        public function setReferrer($referrer)
        {
            $this->referrer = $referrer;
        }
    
        /**  设置 User agent  @param string Full user agent string @return void */
        public function setUseragent($agent)
        {
            $this->userAgent = $agent;
        }
    
        /** 设置请求 timeout  @param integer Timeout delay in seconds @return void */
        public function setTimeout($seconds)
        {
            $this->timeout = $seconds;
        }
    
        /** 设置  cookie path (只支持cURL ) @param string File location of cookiejar @return void */
        public function setCookiepath($path)
        {
    
            $this->cookiePath = $path;
            $this->useCookie(TRUE);
            $this->saveCookie(TRUE);
        }
    
        /** 设置请求参数 parameters @param array GET or POST 的请求数据 @return void */
        public function setParams($dataArray)
        {
            $this->params = array_merge($this->params, $dataArray);
        }
    
        /** 设置 basic http auth 域验证 @param string 用户名  @param string 密码  @return void */
        public function setAuth($username, $password)
        {
            $this->username = $username;
            $this->password = $password;
        }
    
        /** 设置最大跳转数 @param integer Maximum number of redirects @return void */
        public function setMaxredirect($value)
        {
            $this->maxRedirect = $value;
        }
    
        /** 添加多一个新的请求数据 @param string Name of the parameter @param string Value of the paramete  @return void */
        public function addParam($name, $value)
        {
            $this->params[$name] = $value;
        }
    
        /** 添加 cookie 请求数据  @param string Name of cookie  @param string Value of cookie */
        public function addCookie($name, $value)
        {
            $this->cookies[$name] = $value;
        }
    
        /** 是否使用 curl, 默认 true, false 为使用 socket  */
        public function useCurl($value = TRUE)
        {
            if (is_bool($value)) {
                $this->useCurl = $value;
            }
        }
    
        /** 是否使用 cookie , 默认为 false  @param boolean Whether to use cookies or not  @return void */
        public function useCookie($value = FALSE)
        {
            $this->useCookie = $value;
        }
    
        /** 是否使用 cookie , 以供下一次请求使用 @param boolean Whether to save persistent cookies or not @return void */
        public function saveCookie($value = FALSE)
        {
            $this->saveCookie = $value;
        }
    
        /** 是否跟随 302 跳转 @param boolean Whether to follow HTTP redirects or not */
        public function followRedirects($value = TRUE)
        {
            $this->redirect = $value;
        }
    
        /** 获取结果集  @return string output of execution */
        public function getResult()
        {
            return $this->result;
        }
    
        /** 获取最后一个返回的 headers 数组 */
        public function getHeaders()
        {
            return $this->headers;
        }
    
        /** 获取请求的状态码  */
        public function getStatus()
        {
            return $this->status;
        }
    
        /** 获取最后运行错误   */
        public function getError()
        {
            return $this->error;
        }
    
        /** 执行一条 http get 请求  */
        public function get($url, $data = array())
        {
            $res = $this->execute($url, '', 'get', $data);
            if (empty($res)) {
                log_message('error', $url . var_export($data, true));
            }
            return $res;
        }
    
        /** 执行一条 http post 请求  */
        public function post($url, $data = array())
        {
    
            $res = $this->execute($url, '', 'post', $data);
            if (empty($res)) {
                log_message('error', $url . var_export($data, true));
            }
            return $res;
        }
    
        /** 执行一条 http upload 请求  */
        public function upload($url, $data = array())
        {
    
            $res = $this->execute($url, '', 'upload', $data);
            if (empty($res)) {
                log_message('error', $url . var_export($data, true));
            }
            return $res;
        }
    
        /**
         * 保存远程文件到本地
         *
         * @param string $request_file_url 远程的文件 url
         * @param string $save_to_filepath 本地存储的文件 路径
         * @return void
         */
        public function save($request_file_url, $save_to_filepath)
        {
            $fp = fopen($save_to_filepath, 'wb');
            return $this->execute($request_file_url, '', 'get', array(), $extra_params = array('CURLOPT_FILE' => $fp));
        }
    
        /**
         * 使用当前的配置, 发送一条 HTTP 请求
         *
         * @param string URL of the target page (optional)
         * @param string URL of the referrer page (optional)
         * @param string 请求方法 (GET or POST or upload) (optional)
         * @param array 请求数据, key 和 value 对应的数组 (optional)
         * @return string 请求的结果集
         */
        public function execute($target = '', $referrer = '', $method = '', $data = array(), $extra_params = array())
        {
            // Populate the properties
            $this->target = ($target) ? $target : $this->target;
            $this->method = ($method) ? $method : $this->method;
            $this->method = strtoupper($this->method);
            $this->referrer = ($referrer) ? $referrer : $this->referrer;
    
            // Add the new params
            if (is_array($data) && count($data) > 0) {
                $this->params = array_merge($this->params, $data);
            }
    
            // Process data, if presented
            if (is_array($this->params) && count($this->params) > 0) {
                // Get a blank slate
                $tempString = array();
    
                // Convert data array into a query string (ie animal=dog&sport=baseball)
                foreach ($this->params as $key => $value) {
    
                    if (strlen(trim($value)) > 0) {
                        $tempString[] = $key . "=" . urlencode($value);
                    }
                }
    
                $queryString = join('&', $tempString);
    
            }
    
            // 如果 cURL 没有安装就使用 fscokopen 执行请求
            $this->useCurl = $this->useCurl && in_array('curl', get_loaded_extensions());
    
            // GET method configuration
            if ($this->method == 'GET') {
                if (isset($queryString)) {
                    $this->target = $this->target . "?" . $queryString;
                }
            }
    
            // Parse target URL
            $urlParsed = parse_url($this->target);
    
            // Handle SSL connection request
            if ($urlParsed['scheme'] == 'https') {
                $this->host = 'ssl://' . $urlParsed['host'];
                $this->port = ($this->port != 0) ? $this->port : 443;
            } else {
                $this->host = $urlParsed['host'];
                $this->port = ($this->port != 0) ? $this->port : 80;
            }
    
            // Finalize the target path
            $this->path = (isset($urlParsed['path']) ? $urlParsed['path'] : '/') . (isset($urlParsed['query']) ? '?' . $urlParsed['query'] : '');
            $this->schema = $urlParsed['scheme'];
    
            // Pass the requred cookies
            $this->_passCookies();
    
            // Process cookies, if requested
            if (is_array($this->cookies) && count($this->cookies) > 0) {
                // Get a blank slate
                $tempString = array();
    
                // Convert cookiesa array into a query string (ie animal=dog&sport=baseball)
                foreach ($this->cookies as $key => $value) {
                    if (strlen(trim($value)) > 0) {
                        $tempString[] = $key . "=" . urlencode($value);
                    }
                }
    
                $cookieString = join('&', $tempString);
            }
    
            // Do we need to use cURL
            if ($this->useCurl) {
                // Initialize PHP cURL handle
                $ch = curl_init();
                // GET method configuration
                if ($this->method == 'GET') {
                    curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
                    curl_setopt($ch, CURLOPT_POST, FALSE);
                } else if ($this->method == 'UPLOAD') { //UPLOAD上传
                    curl_setopt($ch, CURLOPT_POST, TRUE);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $this->params);
                    curl_setopt($ch, CURLOPT_HTTPGET, FALSE);
                } else { // POST method configuration
                    if (isset($queryString)) {
                        curl_setopt($ch, CURLOPT_POSTFIELDS, $queryString);
                    }
    
                    curl_setopt($ch, CURLOPT_POST, TRUE);
                    curl_setopt($ch, CURLOPT_HTTPGET, FALSE);
                }
    
                // Basic Authentication configuration
                if ($this->username && $this->password) {
                    curl_setopt($ch, CURLOPT_USERPWD, $this->username . ':' . $this->password);
                }
    
                // Custom cookie configuration
                if ($this->useCookie && isset($cookieString)) {
                    curl_setopt($ch, CURLOPT_COOKIE, $cookieString);
                }
    
                curl_setopt($ch, CURLOPT_HEADER, array('Accept-Language: zh-cn', 'Connection: Keep-Alive', 'Cache-Control: no-cache'));                 // No need of headers
                curl_setopt($ch, CURLOPT_NOBODY, FALSE);                // Return body
    
                curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiePath);    // cookie 文件
                curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiePath);    // cookie 文件
    
                // 去掉秒级超时改为毫秒超时
                // curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);       // Timeout
                curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeout * 1000);       // Timeout
    
                /**
                 * 绕过libcurl使用standard name server时的bug
                 * http://www.laruence.com/2014/01/21/2939.html
                 */
                curl_setopt($ch, CURLOPT_NOSIGNAL, true);
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->timeout * 1000); // 毫秒级超时
    
                curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);     // Webbot name
                curl_setopt($ch, CURLOPT_URL, $this->target);        // Target site
                curl_setopt($ch, CURLOPT_REFERER, $this->referrer);      // Referer value
    
                curl_setopt($ch, CURLOPT_VERBOSE, FALSE);                // Minimize logs
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);                // No certificate  - SSH
    
                curl_setopt($ch, CURLOPT_ENCODING, '');                             // "Gzip" "deflate" "identity"
    
                //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->redirect);      // Follow redirects
                curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirect);   // Limit redirections to four
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);                 // 是否以 string 格式返回
    
                if (isset($extra_params['CURLOPT_FILE'])) {
                    curl_setopt($ch, CURLOPT_FILE, $extra_params['CURLOPT_FILE']);
                    curl_setopt($ch, CURLOPT_HEADER, 0);
                }
    
                //curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect'));
                // Get the target contents
                $content = curl_exec($ch);
    
                // Get the request info
                $curl_info = curl_getinfo($ch);
                $header_size = $curl_info["header_size"];
    
                // 值结果集
                $this->result = substr($content, $header_size);
    
                $this->status = $curl_info['http_code'];
    
                // Parse the headers
                $this->_parseHeaders(explode("
    
    ", trim(substr($content, 0, $header_size))));
    
                // Store the error (is any)
                $this->_setError(curl_error($ch));
    
                // Close PHP cURL handle
                curl_close($ch);
            } else {
                // Get a file pointer
                $filePointer = fsockopen($this->host, $this->port, $errorNumber, $errorString, $this->timeout);
    
                // We have an error if pointer is not there
                if (!$filePointer) {
                    $this->_setError('Failed opening http socket connection: ' . $errorString . ' (' . $errorNumber . ')');
                    return FALSE;
                }
    
                // Set http headers with host, user-agent and content type
                $requestHeader = $this->method . " " . $this->path . "  HTTP/1.1
    ";
                $requestHeader .= "Host: " . $urlParsed['host'] . "
    ";
                $requestHeader .= "User-Agent: " . $this->userAgent . "
    ";
                $requestHeader .= "Content-Type: application/x-www-form-urlencoded
    ";
    
                // Specify the custom cookies
                if ($this->useCookie && $cookieString != '') {
                    $requestHeader .= "Cookie: " . $cookieString . "
    ";
                }
    
                // POST method configuration
                if ($this->method == "POST") {
                    $requestHeader .= "Content-Length: " . strlen($queryString) . "
    ";
                }
    
                // Specify the referrer
                if ($this->referrer != '') {
                    $requestHeader .= "Referer: " . $this->referrer . "
    ";
                }
    
                // Specify http authentication (basic)
                if ($this->username && $this->password) {
                    $requestHeader .= "Authorization: Basic " . base64_encode($this->username . ':' . $this->password) . "
    ";
                }
    
                $requestHeader .= "Connection: close
    
    ";
    
                // POST method configuration
                if ($this->method == "POST") {
                    $requestHeader .= $queryString;
                }
    
                // We're ready to launch
                fwrite($filePointer, $requestHeader);
    
                // Clean the slate
                $responseHeader = '';
                $responseContent = '';
    
                // 3...2...1...Launch !
                do {
                    $responseHeader .= fread($filePointer, 1);
                } while (!preg_match('/\r\n\r\n$/', $responseHeader));
    
                // Parse the headers
                $this->_parseHeaders($responseHeader);
    
                // Do we have a 301/302 redirect ?
                if (($this->status == '301' || $this->status == '302') && $this->redirect == TRUE) {
                    if ($this->curRedirect < $this->maxRedirect) {
                        // Let's find out the new redirect URL
                        $newUrlParsed = parse_url($this->headers['location']);
    
                        if ($newUrlParsed['host']) {
                            $newTarget = $this->headers['location'];
                        } else {
                            $newTarget = $this->schema . '://' . $this->host . '/' . $this->headers['location'];
                        }
    
                        // Reset some of the properties
                        $this->port = 0;
                        $this->status = 0;
                        $this->params = array();
                        $this->method = 'GET';
                        $this->referrer = $this->target;
    
                        // Increase the redirect counter
                        $this->curRedirect++;
    
                        // Let's go, go, go !
                        $this->result = $this->execute($newTarget);
                    } else {
                        $this->_setError('Too many redirects.');
                        return FALSE;
                    }
                } else {
                    // Nope...so lets get the rest of the contents (non-chunked)
                    if ($this->headers['transfer-encoding'] != 'chunked') {
                        while (!feof($filePointer)) {
                            $responseContent .= fgets($filePointer, 128);
                        }
                    } else {
                        // Get the contents (chunked)
                        while ($chunkLength = hexdec(fgets($filePointer))) {
                            $responseContentChunk = '';
                            $readLength = 0;
    
                            while ($readLength < $chunkLength) {
                                $responseContentChunk .= fread($filePointer, $chunkLength - $readLength);
                                $readLength = strlen($responseContentChunk);
                            }
    
                            $responseContent .= $responseContentChunk;
                            fgets($filePointer);
                        }
                    }
    
                    // Store the target contents
                    $this->result = chop($responseContent);
                }
            }
    
            // log data
            $logarr = array(
                'Method' => $this->method,
                'Params' => $this->params,
                'Result' => $this->result,
                'Status' => $this->status,
                'Headers' => $this->headers,
                'Errors' => $this->error
            );
            // Debug::log($this->target, $logarr ,"HTTP");
    
            // There it is! We have it!! Return to base !!!
            return $this->result;
        }
    
        /** 解析 header 信息*/
        private function _parseHeaders($responseHeader)
        {
            // Break up the headers
            $headers = $responseHeader;
    
            // Clear the header array
            $this->_clearHeaders();
    
            // Get resposne status
            if ($this->status == 0) {
                // Oooops !
                if (!preg_match($match = "#^http/[0-9]+\.[0-9]+[ 	]+([0-9]+)[ 	]*(.*)$#i", $headers[0], $matches)) {
                    $this->_setError('Unexpected HTTP response status');
                    return FALSE;
                }
    
                // Gotcha!
                $this->status = $matches[1];
    
                array_shift($headers);
            }
    
            // Prepare all the other headers
            $_headers =  explode('<br />', nl2br($headers[0]));
            array_shift($_headers);
            foreach ($_headers as $header) {
                // Get name and value
                $headerName = trim(chop(strtolower($this->_tokenize($header, ':'))));
                // $headerValue = trim(chop($this->_tokenize("
    ")));
                $headerValue = explode(': ', $header)[1];
    
                // If its already there, then add as an array. Otherwise, just keep there
                if (isset($this->headers[$headerName])) {
                    if (gettype($this->headers[$headerName]) == "string") {
                        $this->headers[$headerName] = array($this->headers[$headerName]);
                    }
    
                    $this->headers[$headerName][] = $headerValue;
                } else {
                    $this->headers[$headerName] = $headerValue;
                }
            }
    
            // Save cookies if asked
            if ($this->saveCookie && isset($this->headers['set-cookie'])) {
                $this->_parseCookie();
            }
        }
    
        /** 去除所有 header 信息 */
        private function _clearHeaders()
        {
            $this->headers = array();
        }
    
        /** 解析 COOKIE */
        private function _parseCookie()
        {
            // Get the cookie header as array
            if (gettype($this->headers['set-cookie']) == "array") {
                $cookieHeaders = $this->headers['set-cookie'];
            } else {
                $cookieHeaders = array($this->headers['set-cookie']);
            }
    
            // Loop through the cookies
            for ($cookie = 0; $cookie < count($cookieHeaders); $cookie++) {
                $cookieName = trim($this->_tokenize($cookieHeaders[$cookie], "="));
                $cookieValue = $this->_tokenize(";");
    
                $urlParsed = parse_url($this->target);
    
                $domain = $urlParsed['host'];
                $secure = '0';
    
                $path = "/";
                $expires = "";
    
                while (($name = trim(urldecode($this->_tokenize("=")))) != "") {
                    $value = urldecode($this->_tokenize(";"));
    
                    switch ($name) {
                        case "path"     :
                            $path = $value;
                            break;
                        case "domain"   :
                            $domain = $value;
                            break;
                        case "secure"   :
                            $secure = ($value != '') ? '1' : '0';
                            break;
                    }
                }
    
                $this->_setCookie($cookieName, $cookieValue, $expires, $path, $domain, $secure);
            }
        }
    
        /** 设置 cookie , 为下一次请求做准备 */
        private function _setCookie($name, $value, $expires = "", $path = "/", $domain = "", $secure = 0)
        {
            if (strlen($name) == 0) {
                return ($this->_setError("No valid cookie name was specified."));
            }
    
            if (strlen($path) == 0 || strcmp($path[0], "/")) {
                return ($this->_setError("$path is not a valid path for setting cookie $name."));
            }
    
            if ($domain == "" || !strpos($domain, ".", $domain[0] == "." ? 1 : 0)) {
                return ($this->_setError("$domain is not a valid domain for setting cookie $name."));
            }
    
            $domain = strtolower($domain);
    
            if (!strcmp($domain[0], ".")) {
                $domain = substr($domain, 1);
            }
    
            $name = $this->_encodeCookie($name, true);
            $value = $this->_encodeCookie($value, false);
    
            $secure = intval($secure);
    
            $this->_cookies[] = array("name" => $name,
                "value" => $value,
                "domain" => $domain,
                "path" => $path,
                "expires" => $expires,
                "secure" => $secure
            );
        }
    
        /** cookie  数据集编码  */
        private function _encodeCookie($value, $name)
        {
            return ($name ? str_replace("=", "%25", $value) : str_replace(";", "%3B", $value));
        }
    
        /** 把正确的 cookie 传输给当前请求 */
        private function _passCookies()
        {
            if (is_array($this->_cookies) && count($this->_cookies) > 0) {
                $urlParsed = parse_url($this->target);
                $tempCookies = array();
    
                foreach ($this->_cookies as $cookie) {
                    if ($this->_domainMatch($urlParsed['host'], $cookie['domain']) && (0 === strpos($urlParsed['path'], $cookie['path']))
                        && (empty($cookie['secure']) || $urlParsed['protocol'] == 'https')
                    ) {
                        $tempCookies[$cookie['name']][strlen($cookie['path'])] = $cookie['value'];
                    }
                }
    
                // cookies with longer paths go first
                foreach ($tempCookies as $name => $values) {
                    krsort($values);
                    foreach ($values as $value) {
                        $this->addCookie($name, $value);
                    }
                }
            }
        }
    
        /** 匹配域名 */
        private function _domainMatch($requestHost, $cookieDomain)
        {
            if ('.' != $cookieDomain{0}) {
                return $requestHost == $cookieDomain;
            } elseif (substr_count($cookieDomain, '.') < 2) {
                return false;
            } else {
                return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain;
            }
        }
    
        /** 给当前操作做记号用的 */
        private function _tokenize($string, $separator = '')
        {
            if (!strcmp($separator, '')) {
                $separator = $string;
                $string = $this->nextToken;
            }
    
            for ($character = 0; $character < strlen($separator); $character++) {
                if (gettype($position = strpos($string, $separator[$character])) == "integer") {
                    $found = (isset($found) ? min($found, $position) : $position);
                }
            }
    
            if (isset($found)) {
                $this->nextToken = substr($string, $found + 1);
                return (substr($string, 0, $found));
            } else {
                $this->nextToken = '';
                return ($string);
            }
        }
    
        /** 设置错误信息 */
        private function _setError($error)
        {
            if ($error != '') {
                $this->error = $error;
                return $error;
            }
        }
    }
    
    ?>
    $response = $http_service->$method($url, $param);
            if (empty($response) || !$response = @json_decode($response, true)) {
                log_message('error', "empty response for {$url} , params " . json_encode($param));
                return false;
            } else if ($response['status'] != 200) {
                log_message('error', "invalid response for {$url} , params " . json_encode($param) . ", response:" . $response['msg']);
                return false;
            } else {
                return $response['msg'];
            }
  • 相关阅读:
    爬虫模块BeautifulSoup
    移动端开发概览【webview和touch事件】
    实战JS正则表达式
    相识HTML5 canvas
    运算符中的一些小技巧
    再看Ajax
    跨终端开发必备概念汇总
    谈谈工作,聊聊生活,想想以后
    页面元素坐标和偏移(clientX/pageX/screenX/layerX/offsetWidth/scrollWidth/clientWidth等)相关整理
    CSS3 Flexbox不迷路指南
  • 原文地址:https://www.cnblogs.com/wt645631686/p/13454420.html
Copyright © 2011-2022 走看看