From a49972204760354ccd6477b9508bb39188e2dc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=91=E6=9E=97?= Date: Tue, 21 May 2019 16:01:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Http.php=20=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E6=9C=AC=E5=9C=B0=E6=96=87=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wx/Http.php | 192 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 138 insertions(+), 54 deletions(-) diff --git a/wx/Http.php b/wx/Http.php index c9d3358..31bdb34 100644 --- a/wx/Http.php +++ b/wx/Http.php @@ -2,75 +2,101 @@ namespace wchat; +use Swoole\Coroutine\Http\Client; + class Http { - private $url = 'https://api.weixin.qq.com'; + private $url = 'api.weixin.qq.com'; private $header = []; /** - * @param $url + * @param $url * @param string $pushType * @param array $data - * - * @return Result + * @param callable|NULL $callback + * @param bool $isSSL + * @return array|mixed|Result + * @throws \Exception */ private function request($url, $pushType = 'get', $data = [], callable $callback = NULL, $isSSL = FALSE) { - if ( - strpos($url, 'http://') === FALSE && - strpos($url, 'https://') === FALSE + strpos($url, 'http://') === 0 || + strpos($url, 'https://') === 0 ) { - $url = $this->url . '/' . $url; + return $this->curl($url, $pushType, $data, $callback, $isSSL); + } + if (!extension_loaded('swoole')) { + return $this->curl($url, $pushType, $data, $callback, $isSSL); + } else { + $url = 'https://' . $this->url . '/' . $url; + return $this->coroutine($url, $pushType, $data, $callback, $isSSL); } - - return $this->curl_push($url, $pushType, $data, $callback, $isSSL); } /** * @param $url * @param string $type * @param array $data - * + * @throws * @return Result - * curl请求 + * 使用swoole协程方式请求 */ - public function curl_push($url, $type = 'get', $data = [], callable $callback = NULL, $isSSL = FALSE) + private function coroutine($url, $type = 'get', $data = [], callable $callback = NULL, $isSSL = FALSE) { $_data = $this->paramEncode($data); if ($type == 'get' && is_array($_data)) { $url .= '?' . http_build_query($_data); } - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 超时设置 - curl_setopt($ch, CURLOPT_HEADER, TRUE); - if (!empty($this->header)) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header); - } + $host = \Co::getAddrInfo($this->url); + + $clientInfo = [array_shift($host), 443, TRUE]; + if ($isSSL && is_array($isSSL)) { - curl_setopt($ch, CURLOPT_SSLCERT, $isSSL[0]); - curl_setopt($ch, CURLOPT_SSLKEY, $isSSL[1]); + $this->header['ssl_cert_file'] = $isSSL[0]; + $this->header['ssl_key_file'] = $isSSL[1]; } - curl_setopt($ch, CURLOPT_NOBODY, FALSE); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);// 超时设置 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//返回内容 - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);// 跟踪重定向 - curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); + + $cli = new Client(...$clientInfo); + if (!empty($this->header)) { + $cli->setHeaders($this->header); + } + strtolower($type) == 'get' ? $cli->get($url) : $cli->post($url, $data); + + if ($cli->statusCode < 0) { + throw new \Exception('连接错误!'); + } + $body = $cli->body; + $cli->close(); + return $this->build($body, $callback, $_data); + } + + /** + * @param $url + * @param string $type + * @param array $data + * @param callable|NULL $callback + * @param bool $isSSL + * @return array|mixed|Result + */ + private function curl($url, $type = 'get', $data = [], callable $callback = NULL, $isSSL = FALSE) + { + $_data = $this->paramEncode($data); + if (is_array($_data)) $_data = http_build_query($_data); + + if ($type == 'get') $url .= '?' . $_data; + + $ch = $this->buildCurl($url, $isSSL); switch (strtolower($type)) { case 'post': curl_setopt($ch, CURLOPT_POST, 1); - if (is_array($_data)) { - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_data)); - } else { - curl_setopt($ch, CURLOPT_POSTFIELDS, $_data); - } + curl_setopt($ch, CURLOPT_POSTFIELDS, $_data); break; case 'delete': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_data)); + curl_setopt($ch, CURLOPT_POSTFIELDS, $_data); break; case 'put': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); @@ -85,11 +111,46 @@ class Http } curl_close($ch); - list($header, $body) = explode("\r\n\r\n", $output, 2); + return $this->build($output, $callback, $_data); + } + + /** + * @param $url + * @param $isSSL + * @return resource + */ + private function buildCurl($url, $isSSL) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 超时设置 + curl_setopt($ch, CURLOPT_HEADER, FALSE); + if (!empty($this->header)) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header); + } + if ($isSSL && is_array($isSSL)) { + curl_setopt($ch, CURLOPT_SSLCERT, $isSSL[0]); + curl_setopt($ch, CURLOPT_SSLKEY, $isSSL[1]); + } + curl_setopt($ch, CURLOPT_NOBODY, FALSE); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);// 超时设置 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//返回内容 + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);// 跟踪重定向 + curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); + + return $ch; + } + + private function build($body, $callback, $_data) + { $result = []; if ($callback === NULL) { if (is_null($results = json_decode($body, TRUE))) { - return new Result(['code' => 500, 'message' => '服务器连接失败']); + $data = simplexml_load_string($body, 'SimpleXMLElement', LIBXML_NOCDATA); + $results = json_decode(json_encode($data), TRUE); + } + if (!is_array($results)) { + return new Result(['code' => 505, 'message' => '服务器返回体错误!']); } if (isset($results['errcode'])) { $result['code'] = $results['errcode']; @@ -102,11 +163,9 @@ class Http } else { $result = call_user_func($callback, $body, $_data); } - if (!is_array($result)) { return $result; } - return new Result($result); } @@ -131,65 +190,90 @@ class Http } /** - * @param $url + * @param $url * @param array $data - * @param array $header - * - * @return Result + * @param callable|NULL $callback + * @param array|NULL $header + * @param bool $isSSl + * @return array|mixed|Result + * @throws */ public static function post($url, $data = [], callable $callback = NULL, array $header = NULL, $isSSl = FALSE) { static $_class = NULL; if ($_class == NULL) $_class = new Http(); - if (!empty($header)) { - $_class->setHeaders($header); - } + if (!empty($header)) $_class->setHeaders($header); return $_class->request($url, 'post', $data, $callback, $isSSl); } + /** - * @param $url + * @param $url * @param array $data + * @param callable|NULL $callback + * @param array|NULL $header + * @param bool $isSSl + * @return array|mixed|Result + * @throws + */ + public static function put($url, $data = [], callable $callback = NULL, array $header = NULL, $isSSl = FALSE) + { + static $_class = NULL; + if ($_class == NULL) $_class = new Http(); + if (!empty($header)) $_class->setHeaders($header); + return $_class->request($url, 'put', $data, $callback, $isSSl); + } + + /** + * @param $url + * @param array $data + * @param callable|NULL $callback * @param array $header - * - * @return Result + * @return array|mixed|Result + * @throws */ public static function get($url, $data = [], callable $callback = NULL, $header = []) { static $_class = NULL; if ($_class == NULL) $_class = new Http(); + if (!empty($header)) $_class->setHeaders($header); return $_class->request($url, 'get', $data, $callback); } /** - * @param $url + * @param $url * @param array $data * @param array $header - * - * @return Result + * @return array|mixed|Result + * @throws \Exception */ public static function option($url, $data = [], $header = []) { static $_class = NULL; if ($_class == NULL) $_class = new Http(); + if (!empty($header)) $_class->setHeaders($header); return $_class->request($url, 'option', $data); } /** - * @param $url + * @param $url * @param array $data * @param array $header - * - * @return Result + * @return array|mixed|Result + * @throws \Exception */ public static function delete($url, $data = [], $header = []) { static $_class = NULL; if ($_class == NULL) $_class = new Http(); + if (!empty($header)) $_class->setHeaders($header); return $_class->request($url, 'delete', $data); } - + /** + * @param array $headers + * @return array + */ public function setHeaders(array $headers) { if (empty($headers)) {