Request_Client_External Curl 驱动使用 php-curl 扩展执行外部请求。 这是所有外部请求的默认驱动。
该类在 SYSPATH/classes/request/client/curl.php 第 14 行声明。
string
$client定义默认使用的外部客户端
string(19) "Request_Client_Curl"
Cache
$_cache请求缓存的缓存库
array
$_optionscurl 选项
发送 HTTP 消息 Request 给远程服务器并处理响应。
Request
$request
required - 要发送的请求 Response
public function _send_message(Request $request)
{
// 响应头部
$response_headers = array();
// 设置请求方式
$options[CURLOPT_CUSTOMREQUEST] = $request->method();
// 设置请求主体。与 POST 不同,这在 cURL 中是完全合法的,即使是使用了请求。
// PUT 不支持这个方法,并且不需要在 put 之前向磁盘中写数据。如果阅读了 PHP 文档,您可能会有这样的印象。
$options[CURLOPT_POSTFIELDS] = $request->body();
// 处理头部
if ($headers = $request->headers())
{
$http_headers = array();
foreach ($headers as $key => $value)
{
$http_headers[] = $key . ': ' . $value;
}
$options[CURLOPT_HTTPHEADER] = $http_headers;
}
// 处理 cookies
if ($cookies = $request->cookie())
{
$options[CURLOPT_COOKIE] = http_build_query($cookies, NULL, '; ');
}
// 创建响应
$response = $request->create_response();
$response_header = $response->headers();
// 实现标准的解析参数
$options[CURLOPT_HEADERFUNCTION] = array($response_header, 'parse_header_string');
$this->_options[CURLOPT_RETURNTRANSFER] = true;
$this->_options[CURLOPT_HEADER] = false;
// 应用其它选项设置
$options += $this->_options;
$uri = $request->uri();
if ($query = $request->query())
{
$uri .= '?' . http_build_query($query, NULL, '&');
}
// 打开一个新的远程连接
$curl = curl_init($uri);
// 设置连接选项
if (!curl_setopt_array($curl, $options))
{
throw new Request_Exception('Failed to set CURL options, check CURL documentation: :url', array(':url' => 'http://php.net/curl_setopt_array'));
}
// 获得响应主体
$body = curl_exec($curl);
// 获得响应信息
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($body === false)
{
$error = curl_error($curl);
}
// 关闭连接
curl_close($curl);
if (isset($error))
{
throw new Request_Exception('Error fetching remote :url [ status :code ] :error', array(':url' => $request->url(), ':code' => $code, ':error' => $error));
}
$response->status($code)
->body($body);
return $response;
}
处理请求,执行由 Route 确定的请求的控制器动作。
默认情况下,来自控制器的输出被捕获并返回,并不发送头。
$request->execute();
Request
$request
required - 请求对象 Response
public function execute_request(Request $request)
{
if (BootPHP::$profiling)
{
// 设置 benchmark 名称
$benchmark = '"' . $request->uri() . '"';
if ($request !== Request::$initial && Request::$current)
{
// 添加父请求 URI
$benchmark .= ' ? "' . Request::$current->uri() . '"';
}
// 启动 benchmarking
$benchmark = Profiler::start('Requests', $benchmark);
}
// 保存当前活动请求,并用新的请求替换当前的
$previous = Request::$current;
Request::$current = $request;
// 解决 POST 字段
if ($post = $request->post())
{
$request->body(http_build_query($post, NULL, '&'))
->headers('content-type', 'application/x-www-form-urlencoded');
}
// 如果 BootPHP 暴露,设置 user-agent
if (BootPHP::$expose)
{
$request->headers('user-agent', 'BootPHP Framework ' . BootPHP::VERSION);
}
try
{
$response = $this->_send_message($request);
}
catch (Exception $e)
{
// 恢复上一个请求
Request::$current = $previous;
if (isset($benchmark))
{
// 删除 benchmark,无效了
Profiler::delete($benchmark);
}
// 重新抛出异常
throw $e;
}
// 恢复上一个请求
Request::$current = $previous;
if (isset($benchmark))
{
// 停止 benchmark
Profiler::stop($benchmark);
}
// 返回响应
return $response;
}
工厂方法,根据传递的客户端名,创建一个新的 Request_Client_External 对象,或在默认情况下默认为 Request_Client_External::$client。
Request_Client_External::$client 可以在应用引导中设置。
array
$params
= array(0) - 要传递给客户端的参数 string
$client
= NULL - 要使用的外部客户端 Request_Client_External
public static function factory(array $params = array(), $client = NULL)
{
if ($client === NULL)
{
$client = Request_Client_External::$client;
}
$client = new $client($params);
if (!$client instanceof Request_Client_External)
{
throw new Request_Exception('Selected client is not a Request_Client_External object.');
}
return $client;
}
设置与获取请求的选项。
mixed
$key
= NULL - 选项名,或选项数组 mixed
$value
= NULL - 选项值 mixed
Request_Client_External
public function options($key = NULL, $value = NULL)
{
if ($key === NULL)
return $this->_options;
if (is_array($key))
{
$this->_options = $key;
}
elseif ($value === NULL)
{
return Arr::get($this->_options, $key);
}
else
{
$this->_options[$key] = $value;
}
return $this;
}
创建一个新的 `Request_Client` 对象,允许依赖注入。
array
$params
= array(0) - 参数 public function __construct(array $params = array())
{
foreach ($params as $key => $value)
{
if (method_exists($this, $key))
{
$this->$key($value);
}
}
}
内部缓存引擎的 Getter 与 setter,用来缓存响应(如果可用且有效)。
[HTTP_Cache]
$cache
= NULL - 缓存引擎 [HTTP_Cache]
[Request_Client]
public function cache(HTTP_Cache $cache = NULL)
{
if ($cache === NULL)
return $this->_cache;
$this->_cache = $cache;
return $this;
}
处理请求,执行由 Route 确定的请求的控制器动作。
默认情况下,来自控制器的输出被捕获并返回,并不发送头。
$request->execute();
Request
$request
required - $request Response
public function execute(Request $request)
{
if ($this->_cache instanceof HTTP_Cache)
return $this->_cache->execute($this, $request);
return $this->execute_request($request);
}