模块

Request_Client_Curl
继承自 Request_Client_External
继承自 Request_Client

Request_Client_External Curl 驱动使用 php-curl 扩展执行外部请求。 这是所有外部请求的默认驱动。

package
BootPHP
category
Base
author
Tinsh
copyright
© 2005-2016 Kilofox Studio

该类在 SYSPATH/classes/request/client/curl.php 第 14 行声明。

属性

public static string $client

定义默认使用的外部客户端

string(19) "Request_Client_Curl"

protected Cache $_cache

请求缓存的缓存库

protected array $_options

curl 选项

方法

public _send_message( Request $request ) (在 Request_Client_Curl 中定义)

发送 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;
}

public execute_request( Request $request ) (在 Request_Client_External 中定义)

处理请求,执行由 Route 确定的请求的控制器动作。

  1. 在调用控制器动作之前,将调用 Controller::before 方法。
  2. 然后调用控制器动作。
  3. 在调用控制器动作之后,将调用 Controller::after 方法。

默认情况下,来自控制器的输出被捕获并返回,并不发送头。

$request->execute();

参数

  • Request $request required - 请求对象

Tags

返回值

  • 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;
}

public static factory( [ array $params = array(0) , string $client = NULL ] ) (在 Request_Client_External 中定义)

工厂方法,根据传递的客户端名,创建一个新的 Request_Client_External 对象,或在默认情况下默认为 Request_Client_External::$client。

Request_Client_External::$client 可以在应用引导中设置。

参数

  • array $params = array(0) - 要传递给客户端的参数
  • string $client = NULL - 要使用的外部客户端

Tags

返回值

  • 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;
}

public options( [ mixed $key = NULL , mixed $value = NULL ] ) (在 Request_Client_External 中定义)

设置与获取请求的选项。

参数

  • 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;
}

public __construct( [ array $params = array(0) ] ) (在 Request_Client 中定义)

创建一个新的 `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);
		}
	}
}

public cache( [ [HTTP_Cache] $cache = NULL ] ) (在 Request_Client 中定义)

内部缓存引擎的 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;
}

public execute( Request $request ) (在 Request_Client 中定义)

处理请求,执行由 Route 确定的请求的控制器动作。

  1. 在调用控制器动作之前,将调用 Controller::before 方法。
  2. 然后调用控制器动作。
  3. 在调用控制器动作之后,将调用 Controller::after 方法。

默认情况下,来自控制器的输出被捕获并返回,并不发送头。

$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);
}