洛丽糖
洛丽糖(luolt.cn),致力于互联网资源的共享, 分享各类技术教程,typecho主题模板,zblog主题模板,网站源码等各种资源。
avatar
1281 文章 1477 评论 4 分类 8 页面
仿Typecho中的Http请求过滤
寻梦xunm| 25| 网络收集
4小时前

Typecho 的  Typecho_Http_Client  类功能非常强大,它封装了 PHP 的 cURL 扩展,提供了简洁的 HTTP 请求接口。

下面是一个功能和接口都与 Typecho 官方  Typecho_Http_Client  几乎完全一样的实现:

<?php
/**
 * Typecho 风格的 HTTP 客户端类
 * 封装 cURL 实现 HTTP 请求
 */
class Typecho_Http_Client
{
    /**
     * 请求方法常量
     */
    const METHOD_GET = 'GET';
    const METHOD_POST = 'POST';
    const METHOD_PUT = 'PUT';
    const METHOD_DELETE = 'DELETE';
    const METHOD_HEAD = 'HEAD';

    /**
     * 响应码
     * @var integer
     */
    private $_code;

    /**
     * 响应头
     * @var array
     */
    private $_headers = array();

    /**
     * 响应体
     * @var string
     */
    private $_body;

    /**
     * 请求URL
     * @var string
     */
    private $_url;

    /**
     * 请求方法
     * @var string
     */
    private $_method = self::METHOD_GET;

    /**
     * 请求头
     * @var array
     */
    private $_requestHeaders = array();

    /**
     * 请求数据
     * @var array|string
     */
    private $_data = array();

    /**
     * 超时时间(秒)
     * @var integer
     */
    private $_timeout = 30;

    /**
     * 连接超时时间(秒)
     * @var integer
     */
    private $_connectTimeout = 10;

    /**
     * 是否验证SSL证书
     * @var boolean
     */
    private $_verifyHost = true;
    private $_verifyPeer = true;

    /**
     * 代理设置
     * @var array
     */
    private $_proxy = array();

    /**
     * 单例实例
     * @var Typecho_Http_Client
     */
    private static $_instance;

    /**
     * 获取单例实例
     * 
     * @return Typecho_Http_Client
     */
    public static function get()
    {
        if (empty(self::$_instance)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 构造函数
     */
    private function __construct()
    {
        // 检查cURL扩展是否可用
        if (!extension_loaded('curl')) {
            throw new RuntimeException('cURL extension is required for Typecho_Http_Client');
        }
    }

    /**
     * 设置请求URL
     * 
     * @param string $url
     * @return Typecho_Http_Client
     */
    public function setUrl($url)
    {
        $this->_url = $url;
        return $this;
    }

    /**
     * 设置请求方法
     * 
     * @param string $method
     * @return Typecho_Http_Client
     */
    public function setMethod($method)
    {
        $this->_method = strtoupper($method);
        return $this;
    }

    /**
     * 设置请求头
     * 
     * @param array $headers
     * @return Typecho_Http_Client
     */
    public function setHeaders($headers)
    {
        $this->_requestHeaders = $headers;
        return $this;
    }

    /**
     * 设置请求数据
     * 
     * @param array|string $data
     * @return Typecho_Http_Client
     */
    public function setData($data)
    {
        $this->_data = $data;
        return $this;
    }

    /**
     * 设置超时时间
     * 
     * @param integer $timeout
     * @return Typecho_Http_Client
     */
    public function setTimeout($timeout)
    {
        $this->_timeout = $timeout;
        return $this;
    }

    /**
     * 设置连接超时时间
     * 
     * @param integer $timeout
     * @return Typecho_Http_Client
     */
    public function setConnectTimeout($timeout)
    {
        $this->_connectTimeout = $timeout;
        return $this;
    }

    /**
     * 设置SSL验证
     * 
     * @param boolean $verifyPeer
     * @param boolean $verifyHost
     * @return Typecho_Http_Client
     */
    public function setVerifySsl($verifyPeer = true, $verifyHost = true)
    {
        $this->_verifyPeer = $verifyPeer;
        $this->_verifyHost = $verifyHost;
        return $this;
    }

    /**
     * 设置代理
     * 
     * @param string $host
     * @param integer $port
     * @param string $type
     * @param string $user
     * @param string $pass
     * @return Typecho_Http_Client
     */
    public function setProxy($host, $port = 8080, $type = 'HTTP', $user = '', $pass = '')
    {
        $this->_proxy = array(
            'host' => $host,
            'port' => $port,
            'type' => $type,
            'user' => $user,
            'pass' => $pass
        );
        return $this;
    }

    /**
     * 执行请求
     * 
     * @return boolean
     */
    public function send()
    {
        $ch = curl_init();

        // 基本设置
        curl_setopt($ch, CURLOPT_URL, $this->_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->_connectTimeout);

        // SSL设置
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->_verifyPeer);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $this->_verifyHost ? 2 : 0);

        // 请求方法设置
        switch ($this->_method) {
            case self::METHOD_POST:
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);
                break;
            case self::METHOD_PUT:
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, self::METHOD_PUT);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);
                break;
            case self::METHOD_DELETE:
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, self::METHOD_DELETE);
                if (!empty($this->_data)) {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);
                }
                break;
            case self::METHOD_HEAD:
                curl_setopt($ch, CURLOPT_NOBODY, true);
                break;
        }

        // 请求头设置
        if (!empty($this->_requestHeaders)) {
            $headers = array();
            foreach ($this->_requestHeaders as $key => $value) {
                $headers[] = "$key: $value";
            }
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        // 代理设置
        if (!empty($this->_proxy)) {
            curl_setopt($ch, CURLOPT_PROXY, $this->_proxy['host']);
            curl_setopt($ch, CURLOPT_PROXYPORT, $this->_proxy['port']);
            curl_setopt($ch, CURLOPT_PROXYTYPE, $this->_proxy['type'] == 'HTTPS' ? CURLPROXY_HTTPS : CURLPROXY_HTTP);
            
            if (!empty($this->_proxy['user']) && !empty($this->_proxy['pass'])) {
                curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$this->_proxy['user']}:{$this->_proxy['pass']}");
            }
        }

        // 响应头处理
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_parseHeader'));

        // 执行请求
        $this->_body = curl_exec($ch);
        $this->_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        // 检查错误
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new RuntimeException("cURL Error: $error");
        }

        return true;
    }

    /**
     * 解析响应头
     * 
     * @param resource $ch
     * @param string $header
     * @return integer
     */
    private function _parseHeader($ch, $header)
    {
        $length = strlen($header);
        $header = trim($header);
        
        if (!empty($header) && strpos($header, ':') !== false) {
            list($key, $value) = explode(':', $header, 2);
            $key = trim($key);
            $value = trim($value);
            
            if (isset($this->_headers[$key])) {
                if (!is_array($this->_headers[$key])) {
                    $this->_headers[$key] = array($this->_headers[$key]);
                }
                $this->_headers[$key][] = $value;
            } else {
                $this->_headers[$key] = $value;
            }
        }
        
        return $length;
    }

    /**
     * 获取响应码
     * 
     * @return integer
     */
    public function getCode()
    {
        return $this->_code;
    }

    /**
     * 获取响应头
     * 
     * @param string $key
     * @return array|string|null
     */
    public function getHeaders($key = null)
    {
        if ($key === null) {
            return $this->_headers;
        }
        
        $key = ucwords(strtolower($key), '-');
        return isset($this->_headers[$key]) ? $this->_headers[$key] : null;
    }

    /**
     * 获取响应体
     * 
     * @return string
     */
    public function getBody()
    {
        return $this->_body;
    }

    /**
     * 获取JSON格式的响应体
     * 
     * @return array|object|null
     */
    public function getJson()
    {
        return json_decode($this->_body, true);
    }

    /**
     * 重置客户端状态
     * 
     * @return Typecho_Http_Client
     */
    public function reset()
    {
        $this->_code = 0;
        $this->_headers = array();
        $this->_body = '';
        $this->_url = '';
        $this->_method = self::METHOD_GET;
        $this->_requestHeaders = array();
        $this->_data = array();
        $this->_timeout = 30;
        $this->_connectTimeout = 10;
        $this->_verifyHost = true;
        $this->_verifyPeer = true;
        $this->_proxy = array();
        
        return $this;
    }

    /**
     * 魔术方法,实现链式调用
     * 
     * @param string $name
     * @param array $arguments
     * @return Typecho_Http_Client
     */
    public function __call($name, $arguments)
    {
        if (method_exists($this, $name)) {
            call_user_func_array(array($this, $name), $arguments);
            return $this;
        }
        
        throw new BadMethodCallException("Method $name does not exist");
    }
}
 
 

 

使用示例

这个类的使用方法和 Typecho 官方的  Typecho_Http_Client  完全一致:

<?php
try {
    // 发送GET请求
    $client = Typecho_Http_Client::get();
    $client->setUrl('https://api.example.com/data')
           ->setMethod('GET')
           ->setTimeout(15);
           
    if ($client->send()) {
        echo "响应码: " . $client->getCode() . "\n";
        echo "响应体: " . $client->getBody() . "\n";
        // 如果是JSON响应
        $jsonData = $client->getJson();
    }

    // 发送POST请求
    $client->reset();
    $client->setUrl('https://api.example.com/submit')
           ->setMethod('POST')
           ->setData(array('name' => 'Typecho', 'version' => '1.2'))
           ->setHeaders(array('Content-Type' => 'application/x-www-form-urlencoded'));
           
    if ($client->send()) {
        echo "POST响应: " . $client->getBody() . "\n";
    }

    // 发送JSON格式的POST请求
    $client->reset();
    $postData = json_encode(array('key' => 'value'));
    $client->setUrl('https://api.example.com/json')
           ->setMethod('POST')
           ->setData($postData)
           ->setHeaders(array('Content-Type' => 'application/json'));
           
    if ($client->send()) {
        echo "JSON响应: " . $client->getBody() . "\n";
    }

} catch (RuntimeException $e) {
    echo "HTTP请求失败: " . $e->getMessage() . "\n";
}

 

这个实现包含了 Typecho HTTP 客户端的所有核心功能:

  • 支持 GET、POST、PUT、DELETE、HEAD 等HTTP方法
  • 支持自定义请求头
  • 支持发送表单数据和JSON数据
  • 支持SSL证书验证
  • 支持代理设置
  • 支持响应头和响应体的解析
  • 提供了JSON格式的响应解析
  • 采用单例模式,支持链式调用

这个类可以直接替换 Typecho 原生的 HTTP 客户端类使用。

如果你想在实际项目中更好地使用这个 HTTP 客户端,我可以给你整理一份常见API请求场景的示例代码,比如发送JSON数据、处理文件上传等。需要吗?

none
0 赞 or 打赏
喜欢就打赏一点
微信 支付宝
下一篇

没有了

站内搜索
Q Q:1340326824
邮箱:vipshiyi@qq.com
QQ群:422720328
本站没得会员制度,所有资源都有白嫖的方法,且用且珍惜! 本站相关资源来自互联网用户收集发布,仅供用于学习和交流。 如有侵权之处,请联系站长并出示相关证明以便删除,敬请谅解!

我的音乐