diff --git a/test.php b/test.php index 7983425..aa56d60 100644 --- a/test.php +++ b/test.php @@ -5,73 +5,29 @@ * Date: 2018/7/19 0019 * Time: 18:38 */ +include_once __DIR__ . '/wchat/common/Progaram.php'; +include_once __DIR__ . '/wchat/common/Miniprogarampage.php'; +include_once __DIR__ . '/wchat/common/Help.php'; +include_once __DIR__ . '/wchat/common/Config.php'; +include_once __DIR__ . '/wchat/common/Result.php'; +include_once __DIR__ . '/wchat/common/HttpClient.php'; +include_once __DIR__ . '/wchat/qq/SmallProgram.php'; +include_once __DIR__ . '/wchat/qq/Template.php'; -use officialaccount\AccessToken; -use wchat\Recharge; +use wchat\common\HttpClient; -$config = new \common\Config(); -$config->setAppid(''); -$config->setAppsecret(''); -$config->setMchId(''); -$config->setKey(''); -$config->setRemoteAddr(''); -$config->setDeviceInfo(''); -$config->setAccessToken(''); +\Swoole\Coroutine::create(function () { + $data = '{"id":"681133","username":"","nickname":"???? 闫 ????","openId":"ovnGZ5cj4GtvTeaRZqxYtTwp4lCc","gzhOpenId":"null","phone":"","email":"","password":"","server":0,"xcx_server":0,"unionID":"","avatar":"https:\/\/wx.qlogo.cn\/mmopen\/vi_32\/mGkblm7Ffz4o0prJKnqysoicFWYmwk2YzDqGecsAA10a1QSsRDEH70IserwXKBVMSjBHCaq7Z8YIeccXEHJt9lw\/132","sex":2,"city":"Shijiazhuang","province":"Hebei","country":"China","createTime":1530404031,"modifyTime":1530404048,"lastSeetime":0,"status":1,"groupId":0}'; + $config = new \wchat\common\Config(); + $config->setUsrSwoole(true); -/** @var AccessToken $container */ -$container = Container::newInstance(AccessToken::class, $config); -try { - $params = $container->generateAccess_token(); -} catch (Exception $e) { -} + /** @var \wchat\qq\Template $model */ + $model = \wchat\qq\Template::getInstance($config); + var_dump($model->sendTemplate()); +// $json = json_decode($data, true); +// +// var_dump($json); -/** @var Recharge $container */ -$container = Container::newInstance(\wchat\Recharge::class, $config); -$container->cashWithdrawal(1, 'xxx', 'xxx'); -$container->recharge(1, 'xxx', 'xxx'); - - -/** @var \wchat\Account $account */ -$account = Container::newInstance(\wchat\Account::class, $config); -$account->login(''); -$account->setSavePath(''); -$account->login(''); -try { - $account->createwxaqrcode('pages/index/index', 200); - $account->getwxacode('pages/index/index', 150, true); - $account->getwxacodeunlimit('pages/index/index', 150, true); -} catch (Exception $exception) { - -} -/** @var \wchat\Message $message */ -$message = Container::newInstance(\wchat\Message::class, $config); -$message->setOpenid(''); -try { - $message->sendCardNews(''); - $message->sendTextNews(''); - $message->sendImageNews(''); - $message->sendVoiceNews(''); - $message->sendMpNewsNews(''); - $message->sendNewsNews('', '', '', ''); - $message->sendMusicNews('', '', '', '', ''); - $message->sendMenuNews('', ''); - $message->sendMiniprogrampageNews('', '', '', ''); - $message->sendVideoNews('', '', '', ''); -} catch (Exception $exception) { - -} - -try { - /** @var \wchat\Template $template */ - $template = Container::newInstance(\wchat\Template::class, $config); - $template->setOpenid(''); - $template->setOpenId(''); - $template->setFormId(''); - $template->setTemplateId(''); - $template->setPage(''); - $template->sendTemplate(); -} catch (Exception $exception) { - -} +}); diff --git a/wchat/common/Help.php b/wchat/common/Help.php index ae1e7ab..fa6e9df 100644 --- a/wchat/common/Help.php +++ b/wchat/common/Help.php @@ -81,6 +81,30 @@ class Help extends Miniprogarampage return $xml; } + /** + * @param mixed $json + * @return false|mixed|string + */ + public static function toJson($json) + { + if (is_object($json)) { + $json = get_object_vars($json); + } + if (is_array($json)) { + return json_encode($json, JSON_UNESCAPED_UNICODE); + } + $matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><\/\4>)+<\/\2>/'; + if (preg_match($matchQuote, $json)) { + $json = self::xmlToArray($json); + } else { + $json = json_decode($json, true); + } + if (!is_array($json)) { + $json = []; + } + return json_encode($json, JSON_UNESCAPED_UNICODE); + } + /** * @param int $length * @return string diff --git a/wchat/common/HttpClient.php b/wchat/common/HttpClient.php index 7ef8097..be90da8 100644 --- a/wchat/common/HttpClient.php +++ b/wchat/common/HttpClient.php @@ -4,6 +4,7 @@ namespace wchat\common; use Swoole\Coroutine\Http\Client as SClient; use Swoole\Coroutine\System; +use Swoole\Coroutine\Client; class HttpClient { @@ -28,6 +29,10 @@ class HttpClient private $ca = ''; private $port = ''; + /** @var string $_message 错误信息 */ + private $_message = ''; + private $_data = ''; + /** * @return string */ @@ -74,6 +79,9 @@ class HttpClient { } + /** + * @param $data + */ public function setData($data) { $this->_data = $data; @@ -174,27 +182,26 @@ class HttpClient */ public function grpc($path, array $data) { - $client = new \Swoole\Coroutine\Client(SWOOLE_TCP); + $client = new Client(SWOOLE_TCP); if (empty($this->host) || empty($this->port)) { - return new Result(['code' => 0, 'message' => '']); + return new Result(['code' => 500, 'message' => 'Host and port is null']); } if (!$client->connect($this->host, $this->port)) { return new Result(['code' => 500, 'message' => $client->errMsg]); } $path = $this->port . '/' . ltrim($path, '/'); - $send = $client->send(serialize([ - 'body' => $data, - 'header' => [ - 'request_uri' => $path, - 'request_method' => 'grpc' - ] - ])); - $client->close(); - if ($send) { - $param = ['code' => 0, 'message' => '']; + + $params['body'] = $data; + $params['header']['request_uri'] = $path; + $params['header']['request_method'] = 'grpc'; + + if ($client->send($params)) { + $recv = $client->recv(); + $param = ['code' => 0, 'message' => Help::toArray($recv)]; } else { $param = ['code' => 500, 'message' => $client->errMsg]; } + $client->close(); return new Result($param); } @@ -306,60 +313,40 @@ class HttpClient return false; } - // 手动设置请求域名 - if (!empty($this->host)) { - if (!$this->checkIsIp($this->host)) { - $this->host = System::gethostbyname($this->host); - } + if ($this->isHttp($string)) { + $string = str_replace('http://', '', $string); + $hostAndUrls = explode('/', $string); - if ($this->isHttp($string)) { - $string = str_replace('http://', '', $string); - $hostAndUrls = explode('/', $string); - - $this->host = array_shift($hostAndUrls); - $string = implode('/', $hostAndUrls); - } else if ($this->isHttps($string)) { - $string = str_replace('https://', '', $string); - $this->setIsSSL(true); - - $hostAndUrls = explode('/', $string); - - $this->host = array_shift($hostAndUrls); - $string = implode('/', $hostAndUrls); - } - - return $string; - } - - // 替换请求头为空 - $string = str_replace('http://', '', $string); - if ($this->isHttps($string)) { + $this->host = array_shift($hostAndUrls); + $string = implode('/', $hostAndUrls); + } else if ($this->isHttps($string)) { $string = str_replace('https://', '', $string); $this->setIsSSL(true); + + $hostAndUrls = explode('/', $string); + + $this->host = array_shift($hostAndUrls); + $string = implode('/', $hostAndUrls); + } else if (empty($this->host)) { + $hostAndUrls = explode('/', $string); + $this->host = array_shift($hostAndUrls); + + $string = implode('/', $hostAndUrls); } - $hostAndUrls = explode('/', $string); - if (empty($hostAndUrls)) { - return false; - } - - $this->host = array_shift($hostAndUrls); - $hostAndUrls = implode('/', $hostAndUrls); if (strpos($this->host, ':') !== false) { [$this->host, $this->port] = explode(':', $this->host); - if ($this->checkIsIp($this->host)) { - return $hostAndUrls; - } } - if (!$this->isDomainName($this->host)) { - return false; + if (!$this->checkIsIp($this->host)) { + $this->host = System::gethostbyname($this->host); } + if (!$this->checkIsIp($this->host) && !$this->isDomainName($this->host)) { + throw new \Exception('Client Host error.'); + } - $this->host = System::gethostbyname($this->host); - - return $hostAndUrls; + return $string; } /** @@ -378,12 +365,17 @@ class HttpClient * @param $url * @param $data * @return array|Result|mixed + * @throws */ private function useCurl($url, $data) { if ($this->isHttp($url) || $this->isHttps($url)) { return $this->curl($url, $data); } + $url = $this->matchHost(ltrim($url, '/')); + if (!empty($this->port)) { + $this->host .= ':' . $this->port; + } if ($this->isSSL) { return $this->curl('https://' . $this->host . '/' . $url, $data); } else { @@ -391,41 +383,6 @@ class HttpClient } } - /** - * @param $url - * @return array - */ - private function parseUrlHost($url) - { - if (!$this->isHttp($url) && !$this->isHttps($url)) { - $url = ($this->isSSL ? 'https://' : 'http://') . $url; - } - $url = $this->matchHost($url); - if ($this->checkIsIp($this->host)) { - return [$url, $this->host]; - } - return [$url, System::gethostbyname($this->host)]; - } - - /** - * @param $url - * @return mixed - */ - private function cutRequestUrl($url) - { - $url = $this->replaceHost($url); - $explode = explode('/', $url); - $first = array_shift($explode); - if (strpos($first, ':') !== false) { - [$first, $this->port] = explode(':', $first); - if ($this->port !== 443) { - $this->isSSL = false; - } - } - $url = '/' . implode('/', $explode); - return [$first, $url]; - } - /** * @param $host * @return string|string[] @@ -478,38 +435,36 @@ class HttpClient */ private function coroutine($url, $data = []) { - $client = $this->generate_client($this->host, $url, $data); - if ($client->statusCode < 0) { - throw new \Exception($client->errMsg); - } - - $body = $client->body; - - $header = $client->getHeaders(); - - $body = $this->resolve($header, $body); - - unset($this->_data); - - if ($client->getStatusCode() != 200) { - if (is_string($body)) { - $message = 'Request error code ' . $client->getStatusCode(); - } else { - $message = $this->searchMessageByData($body); + try { + $client = $this->generate_client($this->host, $url, $data); + if ($client->statusCode < 0) { + throw new \Exception($client->errMsg); } - return new Result(['code' => $client->getStatusCode(), 'message' => $message, 'data' => $body]); + unset($this->_data); + + $body = $this->resolve($client->getHeaders(), $client->body); + if ($client->getStatusCode() != 200) { + if (is_string($body)) { + $message = 'Request error code ' . $client->getStatusCode(); + } else { + $message = $this->searchMessageByData($body); + } + $response['code'] = $client->getStatusCode(); + $response['message'] = $message; + $response['data'] = $body; + } else { + $response = $this->structure($body, $data, $client->getHeaders()); + } + } catch (\Throwable $exception) { + $response['code'] = 500; + $response['message'] = $exception->getMessage(); + $response['data'] = array_slice($exception->getTrace(), 0, 6); + $response['header'] = []; } - - return $this->structure($body, $data, $header); - } - - /** - * @return mixed - */ - private function getHostIp() - { - $host = \Co::getAddrInfo($this->host); - return array_shift($host); + if (!($response instanceof Result)) { + $response = new Result($response); + } + return $response; } /** @@ -532,12 +487,13 @@ class HttpClient * @param $data * @return \Swoole\Coroutine\Http\Client */ - private function generate_client($host, $url, $data) + private function generate_client($host, $url, $data = []) { $client = new SClient($host, $this->getHostPort(), $this->isSSL); if (strpos($url, '/') !== 0) { $url = '/' . $url; } + $client->set($this->settings()); if (!empty($this->agent)) { $this->header['User-Agent'] = $this->agent; @@ -545,40 +501,65 @@ class HttpClient if (!empty($this->header)) { $client->setHeaders($this->header); } + + $client->setMethod(strtoupper($this->method)); + if (strtolower($this->method) == self::GET && !empty($data)) { + $url .= '?' . $data; + } else { + $this->_data = $this->mergeParams($data); + } + if (!empty($this->_data)) { $client->setData($this->_data); } - if (strtolower($this->method) == self::GET) { - if (!empty($data)) { - $url .= '?' . $data; - } - $client->get($url); - } else if (strtolower($this->method) == self::PUT) { - $client->setMethod('PUT'); - if (!is_string($data)) { - $data = json_encode($data); - } - if (!empty($data)) { - $client->setData($data); - } - $client->execute($url); - } else if (strtolower($this->method) == self::DELETE) { - $client->setMethod('DELETE'); - if (!is_string($data)) { - $data = json_encode($data); - } - if (!empty($data)) { - $client->setData($data); - } - $client->execute($url); - } else { - $client->post($url, $data); - } + $client->execute($url); $client->close(); return $client; } + /** + * @param $newData + * @return mixed + */ + private function mergeParams($newData) + { + if (empty($this->_data)) { + return $this->toRequest($newData); + } else if (empty($newData)) { + return $this->toRequest($this->_data); + } + $newData = Help::toArray($newData); + $array = Help::toArray($this->_data); + + $params = array_merge($array, $newData); + + return $this->toRequest($params); + } + + + /** + * @param $data + * @return false|mixed|string + */ + private function toRequest($data) + { + if (!is_array($data)) { + $data = Help::toArray($data); + } + $contentType = $this->header['Content-Type'] ?? 'application/json'; + if (strpos($contentType, 'json') !== false) { + return Help::toJson($data); + } else if (strpos($contentType, 'xml') !== false) { + return Help::toXml($data); + } else { + return Help::toJson($data); + } + } + + /** + * @return array + */ private function settings() { $sslCert = $this->getSslCertFile(); @@ -606,58 +587,72 @@ class HttpClient private function curl($url, $data = []) { try { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $this->createRequestUrl($url, $data)); - curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 超时设置 - curl_setopt($ch, CURLOPT_HEADER, true); - - if ($headers = $this->parseHeaderMat()) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - } - - if (!empty($this->agent)) { - curl_setopt($ch, CURLOPT_USERAGENT, $this->agent); - } - curl_setopt($ch, CURLOPT_SSLCERT, $this->getSslCertFile()); - curl_setopt($ch, CURLOPT_SSLKEY, $this->getSslKeyFile()); - 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'); - - if ($this->method == self::POST) { - curl_setopt($ch, CURLOPT_POST, 1); - } - if ($this->method != self::GET) { - if (!empty($this->_data)) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_data); - } else { - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - } - } - - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($this->method)); - $output = curl_exec($ch); - curl_close($ch); - + $output = $this->curlParse($url, $this->mergeParams($data)); if ($output === FALSE) { - $data = new Result(['code' => 500, 'message' => curl_error($ch)]); - } else { - [$header, $body, $status] = $this->explode($output); - if ($status != 200) { - $data = new Result(['code' => 500, 'message' => $body, 'header' => $header]); - } else { - $data = $this->structure($body, $data, $header); - } + return new Result(['code' => 500, 'message' => $output]); + } + [$header, $body, $status] = $this->explode($output); + if ($status != 200 && $status != 201) { + $data = new Result(['code' => $status, 'message' => $body, 'header' => $header]); + } else { + $data = $this->structure($body, $data, $header); } - unset($ch); return $data; - } catch (\Exception $exception) { - return new Result(['code' => 500, 'message' => $exception->getMessage(), 'header' => []]); + } catch (\Throwable $exception) { + $response['code'] = 500; + $response['message'] = $exception->getMessage(); + $response['data'] = array_slice($exception->getTrace(), 0, 6); + $response['header'] = []; + return new Result($response); } } + /** + * @param $url + * @param $data + * @return bool|string + * @throws \Exception + */ + private function curlParse($url, $data) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $this->createRequestUrl($url, $data)); + curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 超时设置 + curl_setopt($ch, CURLOPT_HEADER, true); + + if ($headers = $this->parseHeaderMat()) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + } + + if (!empty($this->agent)) { + curl_setopt($ch, CURLOPT_USERAGENT, $this->agent); + } + + curl_setopt($ch, CURLOPT_SSLCERT, $this->getSslCertFile()); + curl_setopt($ch, CURLOPT_SSLKEY, $this->getSslKeyFile()); + 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'); + + if ($this->method == self::POST) { + curl_setopt($ch, CURLOPT_POST, 1); + } + + if ($this->method != self::GET) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($this->method)); + $output = curl_exec($ch); + if ($output === false) { + throw new \Exception(curl_error($ch)); + } + curl_close($ch); + return $output; + } + /** * @param $output * @return array diff --git a/wchat/common/Miniprogarampage.php b/wchat/common/Miniprogarampage.php index 4b061ef..5549ef4 100644 --- a/wchat/common/Miniprogarampage.php +++ b/wchat/common/Miniprogarampage.php @@ -85,6 +85,7 @@ abstract class Miniprogarampage implements Progaram static::$instance = new static(); } static::$instance->config = $config; + static::$instance->request = HttpClient::NewRequest(); static::$instance->request->setAgent($config->getAgent()); static::$instance->request->setUseSwoole($config->isUsrSwoole()); diff --git a/wchat/common/Result.php b/wchat/common/Result.php index 02884db..bf25a47 100644 --- a/wchat/common/Result.php +++ b/wchat/common/Result.php @@ -151,6 +151,9 @@ class Result */ public function append($key, $data) { + if (!is_array($this->data)) { + $this->data = []; + } $this->data[$key] = $data; return $this; } diff --git a/wchat/qq/Template.php b/wchat/qq/Template.php index fa9cd1e..694ce2a 100644 --- a/wchat/qq/Template.php +++ b/wchat/qq/Template.php @@ -140,7 +140,7 @@ class Template extends SmallProgram $this->request->setErrorField('errcode'); $this->request->setErrorMsgField('errmsg'); $result = $this->request->post($url, $params); -// $result->append('postBody', $params); + $result->append('postBody', $params); $this->openId = ''; $this->keywords = [];