public function __construct(array $options) { $options = ['baseUri' => Arr::get($options, 'baseUri', $this->baseUri), 'timeout' => Arr::get($options, 'timeout', $this->timeout), 'proxy' => Arr::get($options, 'proxy', $this->proxy), 'auth' => Arr::get($options, 'auth', $this->auth), 'logger' => Arr::get($options, 'logger')]; try { V::arrayVal()->key('baseUri', V::url()->notEmpty())->key('timeout', V::floatVal()->min(0))->key('proxy', V::optional(V::url()))->key('auth', V::arrayVal()->key('user', V::stringType())->key('pass', V::stringType()))->key('logger', V::instance('\\Psr\\Log\\LoggerInterface'))->assert($options); } catch (\InvalidArgumentException $e) { $errors = array_filter($e->findMessages(['baseUri' => 'Required correct baseUri', 'timeout' => 'Required correct timeout', 'proxy' => 'Required correct proxy', 'auth' => 'Required correct authuser', 'logger' => 'Required a logger instance of psr\\log'])); $errmsg = array_shift($errors); throw new Exception($errmsg); } $this->baseUri = $options['baseUri']; $this->timeout = $options['timeout']; $this->proxy = $options['proxy']; $this->auth = $options['auth']; $this->logger = $options['logger']; }
/** * @brief 对资源发起POST请求 * * @param string $method 请求方法 * @param stirng $requestUri 请求URI * @param array $params 请求参数 * * @return string or null 响应内容 */ public function request($method, $requestUri, array $params = []) { $options = ['base_uri' => $this->conf->baseUri, 'timeout' => $this->conf->timeout]; //毫秒超时 if ($this->conf->timeout < 1) { //需要cURL版本大于7.16.2 $support = version_compare(curl_version()['version'], '7.16.2', '>='); if ($support) { //此设置会让DNS无超时,建议libcurl使用c-ares做异步DNS $options['curl'] = [CURLOPT_NOSIGNAL => 1]; } else { $this->conf->logger->warning('TIMEOUT_MS added in cURL 7.16.2 .'); $this->conf->timeout = 1; } } //设置代理 if ($this->conf->proxy) { $options['proxy'] = $this->conf->proxy; } //设置认证信息 if ($this->conf->auth['user']) { $options['auth'] = array_values($this->conf->auth); } //追加caller $params['caller'] = $this->caller; //配置请求参数 if ($params) { switch ($method) { case 'GET': $options['query'] = $params; break; case 'POST': $options['form_params'] = $params; break; case 'PUT': $options['body'] = http_build_query($params); break; default: } } //设置头信息 if ($this->headers) { $options['headers'] = $this->headers; } //设置cookie if ($this->cookies) { $options['cookies'] = $this->cookies; } //传输细节 $options['on_stats'] = function ($stats) use($method, $params) { //记录请求日志 $requestInfo = 'Request'; $requestInfo .= ' [method] ' . $method; $requestInfo .= ' [uri] ' . $stats->getEffectiveUri(); $requestInfo .= ' [usetime] ' . round($stats->getTransferTime(), 2) . '(s)'; $this->conf->logger->info($requestInfo, $params); $statsInfo = $stats->getHandlerStats(); //记录请求慢日志 if ($statsInfo['total_time'] > self::WARNING_COST_TIME) { $this->conf->logger->warning('Request time is too long.', Arr::extract($statsInfo, ['total_time', 'namelookup_time', 'connect_time', 'pretransfer_time', 'starttransfer_time'])); } }; try { //开始请求 $response = $this->client->request($method, $requestUri, $options); if ($response->getStatusCode() === 200) { //获取响应内容 $data = $response->getBody()->getContents(); //响应内容记录DEBUG日志 $this->conf->logger->info('Response [content] ' . $data); return $data; } else { return null; } } catch (\Exception $e) { //请求异常记录ERROR日志 $this->conf->logger->error($e->getMessage()); return null; } }