酷秀博客
首页/仿制封装Typecho_Http_Client类A I

仿制封装Typecho_Http_Client类

admin的头像admin4个月前A I136热度

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

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



<?php<br />
/**<br />
 * Typecho 风格的 HTTP 客户端类<br />
 * 封装 cURL 实现 HTTP 请求<br />
 */<br />
class Typecho_Http_Client<br />
{<br />
    /**<br />
     * 请求方法常量<br />
     */<br />
    const METHOD_GET = 'GET';<br />
    const METHOD_POST = 'POST';<br />
    const METHOD_PUT = 'PUT';<br />
    const METHOD_DELETE = 'DELETE';<br />
    const METHOD_HEAD = 'HEAD';<br />
<br />
    /**<br />
     * 响应码<br />
     * @var integer<br />
     */<br />
    private $_code;<br />
<br />
    /**<br />
     * 响应头<br />
     * @var array<br />
     */<br />
    private $_headers = array();<br />
<br />
    /**<br />
     * 响应体<br />
     * @var string<br />
     */<br />
    private $_body;<br />
<br />
    /**<br />
     * 请求URL<br />
     * @var string<br />
     */<br />
    private $_url;<br />
<br />
    /**<br />
     * 请求方法<br />
     * @var string<br />
     */<br />
    private $_method = self::METHOD_GET;<br />
<br />
    /**<br />
     * 请求头<br />
     * @var array<br />
     */<br />
    private $_requestHeaders = array();<br />
<br />
    /**<br />
     * 请求数据<br />
     * @var array|string<br />
     */<br />
    private $_data = array();<br />
<br />
    /**<br />
     * 超时时间(秒)<br />
     * @var integer<br />
     */<br />
    private $_timeout = 30;<br />
<br />
    /**<br />
     * 连接超时时间(秒)<br />
     * @var integer<br />
     */<br />
    private $_connectTimeout = 10;<br />
<br />
    /**<br />
     * 是否验证SSL证书<br />
     * @var boolean<br />
     */<br />
    private $_verifyHost = true;<br />
    private $_verifyPeer = true;<br />
<br />
    /**<br />
     * 代理设置<br />
     * @var array<br />
     */<br />
    private $_proxy = array();<br />
<br />
    /**<br />
     * 单例实例<br />
     * @var Typecho_Http_Client<br />
     */<br />
    private static $_instance;<br />
<br />
    /**<br />
     * 获取单例实例<br />
     * <br />
     * @return Typecho_Http_Client<br />
     */<br />
    public static function get()<br />
    {<br />
        if (empty(self::$_instance)) {<br />
            self::$_instance = new self();<br />
        }<br />
        return self::$_instance;<br />
    }<br />
<br />
    /**<br />
     * 构造函数<br />
     */<br />
    private function __construct()<br />
    {<br />
        // 检查cURL扩展是否可用<br />
        if (!extension_loaded('curl')) {<br />
            throw new RuntimeException('cURL extension is required for Typecho_Http_Client');<br />
        }<br />
    }<br />
<br />
    /**<br />
     * 设置请求URL<br />
     * <br />
     * @param string $url<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setUrl($url)<br />
    {<br />
        $this->_url = $url;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置请求方法<br />
     * <br />
     * @param string $method<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setMethod($method)<br />
    {<br />
        $this->_method = strtoupper($method);<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置请求头<br />
     * <br />
     * @param array $headers<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setHeaders($headers)<br />
    {<br />
        $this->_requestHeaders = $headers;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置请求数据<br />
     * <br />
     * @param array|string $data<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setData($data)<br />
    {<br />
        $this->_data = $data;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置超时时间<br />
     * <br />
     * @param integer $timeout<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setTimeout($timeout)<br />
    {<br />
        $this->_timeout = $timeout;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置连接超时时间<br />
     * <br />
     * @param integer $timeout<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setConnectTimeout($timeout)<br />
    {<br />
        $this->_connectTimeout = $timeout;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置SSL验证<br />
     * <br />
     * @param boolean $verifyPeer<br />
     * @param boolean $verifyHost<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setVerifySsl($verifyPeer = true, $verifyHost = true)<br />
    {<br />
        $this->_verifyPeer = $verifyPeer;<br />
        $this->_verifyHost = $verifyHost;<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 设置代理<br />
     * <br />
     * @param string $host<br />
     * @param integer $port<br />
     * @param string $type<br />
     * @param string $user<br />
     * @param string $pass<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function setProxy($host, $port = 8080, $type = 'HTTP', $user = '', $pass = '')<br />
    {<br />
        $this->_proxy = array(<br />
            'host' => $host,<br />
            'port' => $port,<br />
            'type' => $type,<br />
            'user' => $user,<br />
            'pass' => $pass<br />
        );<br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 执行请求<br />
     * <br />
     * @return boolean<br />
     */<br />
    public function send()<br />
    {<br />
        $ch = curl_init();<br />
<br />
        // 基本设置<br />
        curl_setopt($ch, CURLOPT_URL, $this->_url);<br />
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br />
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);<br />
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);<br />
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);<br />
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->_connectTimeout);<br />
<br />
        // SSL设置<br />
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->_verifyPeer);<br />
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $this->_verifyHost ? 2 : 0);<br />
<br />
        // 请求方法设置<br />
        switch ($this->_method) {<br />
            case self::METHOD_POST:<br />
                curl_setopt($ch, CURLOPT_POST, true);<br />
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);<br />
                break;<br />
            case self::METHOD_PUT:<br />
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, self::METHOD_PUT);<br />
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);<br />
                break;<br />
            case self::METHOD_DELETE:<br />
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, self::METHOD_DELETE);<br />
                if (!empty($this->_data)) {<br />
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data);<br />
                }<br />
                break;<br />
            case self::METHOD_HEAD:<br />
                curl_setopt($ch, CURLOPT_NOBODY, true);<br />
                break;<br />
        }<br />
<br />
        // 请求头设置<br />
        if (!empty($this->_requestHeaders)) {<br />
            $headers = array();<br />
            foreach ($this->_requestHeaders as $key => $value) {<br />
                $headers[] = "$key: $value";<br />
            }<br />
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);<br />
        }<br />
<br />
        // 代理设置<br />
        if (!empty($this->_proxy)) {<br />
            curl_setopt($ch, CURLOPT_PROXY, $this->_proxy['host']);<br />
            curl_setopt($ch, CURLOPT_PROXYPORT, $this->_proxy['port']);<br />
            curl_setopt($ch, CURLOPT_PROXYTYPE, $this->_proxy['type'] == 'HTTPS' ? CURLPROXY_HTTPS : CURLPROXY_HTTP);<br />
            <br />
            if (!empty($this->_proxy['user']) && !empty($this->_proxy['pass'])) {<br />
                curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$this->_proxy['user']}:{$this->_proxy['pass']}");<br />
            }<br />
        }<br />
<br />
        // 响应头处理<br />
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_parseHeader'));<br />
<br />
        // 执行请求<br />
        $this->_body = curl_exec($ch);<br />
        $this->_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);<br />
<br />
        // 检查错误<br />
        $error = curl_error($ch);<br />
        curl_close($ch);<br />
<br />
        if ($error) {<br />
            throw new RuntimeException("cURL Error: $error");<br />
        }<br />
<br />
        return true;<br />
    }<br />
<br />
    /**<br />
     * 解析响应头<br />
     * <br />
     * @param resource $ch<br />
     * @param string $header<br />
     * @return integer<br />
     */<br />
    private function _parseHeader($ch, $header)<br />
    {<br />
        $length = strlen($header);<br />
        $header = trim($header);<br />
        <br />
        if (!empty($header) && strpos($header, ':') !== false) {<br />
            list($key, $value) = explode(':', $header, 2);<br />
            $key = trim($key);<br />
            $value = trim($value);<br />
            <br />
            if (isset($this->_headers[$key])) {<br />
                if (!is_array($this->_headers[$key])) {<br />
                    $this->_headers[$key] = array($this->_headers[$key]);<br />
                }<br />
                $this->_headers[$key][] = $value;<br />
            } else {<br />
                $this->_headers[$key] = $value;<br />
            }<br />
        }<br />
        <br />
        return $length;<br />
    }<br />
<br />
    /**<br />
     * 获取响应码<br />
     * <br />
     * @return integer<br />
     */<br />
    public function getCode()<br />
    {<br />
        return $this->_code;<br />
    }<br />
<br />
    /**<br />
     * 获取响应头<br />
     * <br />
     * @param string $key<br />
     * @return array|string|null<br />
     */<br />
    public function getHeaders($key = null)<br />
    {<br />
        if ($key === null) {<br />
            return $this->_headers;<br />
        }<br />
        <br />
        $key = ucwords(strtolower($key), '-');<br />
        return isset($this->_headers[$key]) ? $this->_headers[$key] : null;<br />
    }<br />
<br />
    /**<br />
     * 获取响应体<br />
     * <br />
     * @return string<br />
     */<br />
    public function getBody()<br />
    {<br />
        return $this->_body;<br />
    }<br />
<br />
    /**<br />
     * 获取JSON格式的响应体<br />
     * <br />
     * @return array|object|null<br />
     */<br />
    public function getJson()<br />
    {<br />
        return json_decode($this->_body, true);<br />
    }<br />
<br />
    /**<br />
     * 重置客户端状态<br />
     * <br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function reset()<br />
    {<br />
        $this->_code = 0;<br />
        $this->_headers = array();<br />
        $this->_body = '';<br />
        $this->_url = '';<br />
        $this->_method = self::METHOD_GET;<br />
        $this->_requestHeaders = array();<br />
        $this->_data = array();<br />
        $this->_timeout = 30;<br />
        $this->_connectTimeout = 10;<br />
        $this->_verifyHost = true;<br />
        $this->_verifyPeer = true;<br />
        $this->_proxy = array();<br />
        <br />
        return $this;<br />
    }<br />
<br />
    /**<br />
     * 魔术方法,实现链式调用<br />
     * <br />
     * @param string $name<br />
     * @param array $arguments<br />
     * @return Typecho_Http_Client<br />
     */<br />
    public function __call($name, $arguments)<br />
    {<br />
        if (method_exists($this, $name)) {<br />
            call_user_func_array(array($this, $name), $arguments);<br />
            return $this;<br />
        }<br />
        <br />
        throw new BadMethodCallException("Method $name does not exist");<br />
    }<br />
}<br />
 <br />
 <br />
<br />
```<br />
 <br />
 <br />
使用示例<br />
 <br />
这个类的使用方法和 Typecho 官方的  Typecho_Http_Client  完全一致:<br />
  <br />
```php<br />
<?php<br />
try {<br />
    // 发送GET请求<br />
    $client = Typecho_Http_Client::get();<br />
    $client->setUrl('https://api.example.com/data')<br />
           ->setMethod('GET')<br />
           ->setTimeout(15);<br />
           <br />
    if ($client->send()) {<br />
        echo "响应码: " . $client->getCode() . "\n";<br />
        echo "响应体: " . $client->getBody() . "\n";<br />
        // 如果是JSON响应<br />
        $jsonData = $client->getJson();<br />
    }<br />
<br />
    // 发送POST请求<br />
    $client->reset();<br />
    $client->setUrl('https://api.example.com/submit')<br />
           ->setMethod('POST')<br />
           ->setData(array('name' => 'Typecho', 'version' => '1.2'))<br />
           ->setHeaders(array('Content-Type' => 'application/x-www-form-urlencoded'));<br />
           <br />
    if ($client->send()) {<br />
        echo "POST响应: " . $client->getBody() . "\n";<br />
    }<br />
<br />
    // 发送JSON格式的POST请求<br />
    $client->reset();<br />
    $postData = json_encode(array('key' => 'value'));<br />
    $client->setUrl('https://api.example.com/json')<br />
           ->setMethod('POST')<br />
           ->setData($postData)<br />
           ->setHeaders(array('Content-Type' => 'application/json'));<br />
           <br />
    if ($client->send()) {<br />
        echo "JSON响应: " . $client->getBody() . "\n";<br />
    }<br />
<br />
} catch (RuntimeException $e) {<br />
    echo "HTTP请求失败: " . $e->getMessage() . "\n";<br />
}<br />
<br />
```<br />
 <br />
 <br />
这个实现包含了 Typecho HTTP 客户端的所有核心功能:<br />
 <br />
- 支持 GET、POST、PUT、DELETE、HEAD 等HTTP方法<br />
- 支持自定义请求头<br />
- 支持发送表单数据和JSON数据<br />
- 支持SSL证书验证<br />
- 支持代理设置<br />
- 支持响应头和响应体的解析<br />
- 提供了JSON格式的响应解析<br />
- 采用单例模式,支持链式调用<br />
 <br />
这个类可以直接替换 Typecho 原生的 HTTP 客户端类使用。<br />
 <br />
如果你想在实际项目中更好地使用这个 HTTP 客户端,我可以给你整理一份常见API请求场景的示例代码,比如发送JSON数据、处理文件上传等。需要吗?
签名: 最忠诚的BUG开发者来自: 重庆市. Chrome浏览器
文章目录