sabre / http
sabre/http 库提供了处理 HTTP 请求和响应的实用工具。
Requires
- php: ^7.4 || ^8.0
- ext-ctype: *
- ext-curl: *
- ext-mbstring: *
- sabre/event: ^6.0
- sabre/uri: ^2.3 || ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.64
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.11
- phpstan/phpstan-phpunit: ^1.4
- phpstan/phpstan-strict-rules: ^1.6
- phpunit/phpunit: ^9.6
Suggests
- ext-curl: to make http requests with the Client class
- dev-master
- 7.0.4
- 7.0.3
- 7.0.2
- 7.0.1
- 7.0.0
- 6.0.x-dev
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.1.x-dev
- 5.1.12
- 5.1.11
- 5.1.10
- 5.1.9
- 5.1.8
- 5.1.7
- 5.1.6
- 5.1.5
- 5.1.4
- 5.1.3
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.5
- 5.0.4
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 5.0.0-alpha1
- 4.2.x-dev
- v4.2.4
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.0
- 4.0.0
- 4.0.0-alpha3
- 4.0.0-alpha2
- 4.0.0-alpha1
- 3.0.x-dev
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.1.0-alpha1
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 2.0.0alpha6
- 2.0.0alpha5
- 2.0.0alpha4
- 2.0.0alpha3
- 2.0.0alpha2
- 2.0.0alpha1
- dev-dependabot/composer/phpunit/phpunit-tw-11.3
- dev-require-method-uri
- dev-deprecate-util
- dev-event3
This package is auto-updated.
Last update: 2024-09-06 11:42:44 UTC
README
该库提供了一套工具,用于简化 HTTP 协议的工作。
大多数 PHP 脚本都在 HTTP 请求中运行,但访问 HTTP 请求的信息至少是繁琐的。
存在着不良的实践、不一致和混淆。这个库实际上是对以下 PHP 构造的包装:
输入
$_GET
,$_POST
,$_SERVER
,php://input
或$HTTP_RAW_POST_DATA
。
输出
php://output
或echo
,header()
.
这个库提供的,是一个 Request
对象和一个 Response
对象。
这些对象是可扩展的,并且很容易模拟。
构建状态
安装
确保您已安装 composer。在您的项目目录中,创建或编辑一个 composer.json
文件,并确保它包含以下内容
{ "require" : { "sabre/http" : "~5.0.0" } }
之后,只需运行 composer install
即可。
快速历史
该库于 2009 年诞生,作为 sabre/dav
项目的一部分,该项目大量使用了它。
它被拆分为一个单独的库,以使其更容易管理发布,并希望使其在 sabre/dav
的范围之外也能使用。
虽然完全独立开发,但这个库与 Symfony 的 HttpFoundation
有很多重叠。
上述库执行了很多其他操作,并且非常受欢迎,因此如果您正在寻找满足这一特定需求的东西,我建议您也考虑 HttpFoundation
。
入门
首先最重要的是,这个库包装了超级全局变量。实例化请求对象的最简单方法是以下方法
use Sabre\HTTP; include 'vendor/autoload.php'; $request = HTTP\Sapi::getRequest();
这行代码应仅在整个应用程序中发生一次。在其他地方,您应使用依赖注入传递此请求对象。
您应该始终对其接口进行类型提示
function handleRequest(HTTP\RequestInterface $request) { // Do something with this request :) }
响应对象可以这样创建
use Sabre\HTTP; include 'vendor/autoload.php'; $response = new HTTP\Response(); $response->setStatus(201); // created ! $response->setHeader('X-Foo', 'bar'); $response->setBody( 'success!' );
在您完全构建了响应之后,您必须调用
HTTP\Sapi::sendResponse($response);
这行代码通常也只出现在您的应用程序中(在最后)。
装饰器
如果您希望在应用程序中扩展 Request
和 Response
对象,例如,如果希望它们携带更多关于当前请求的信息,这可能很有用。
例如,您可能想向请求对象添加一个 isLoggedIn
方法。
简单地扩展请求和响应可能存在一些问题
- 您可能希望以不同的方式扩展对象以实现新的行为,在应用程序的不同子系统,
Sapi::getRequest
工厂始终返回一个Request
实例,因此您还必须重写工厂方法,- 通过控制实例化和依赖库或应用程序中的特定
Request
和Response
实例,您使其他应用程序难以使用sabre/http
。
简而言之,这将是糟糕的设计。相反,建议使用装饰器模式来添加所需的新行为。sabre/http
提供了辅助类以快速实现此功能。
示例
use Sabre\HTTP; class MyRequest extends HTTP\RequestDecorator { function isLoggedIn() { return true; } }
我们的应用程序假设真正的Request
对象是在其他地方由其他子系统实例化的。这可以简单地是一个像在应用程序顶部调用$request = Sapi::getRequest()
这样的调用,也可能是在某个单元测试中。
在当前子系统内,我们所知道的就是我们收到了一个$request
,并且它实现了Sabre\HTTP\RequestInterface
接口。要装饰此对象,我们只需要做
$request = new MyRequest($request);
就这样;我们现在有了isLoggedIn
方法,而不必触及核心实例。
客户端
此包还包含一个简单的cURL包装器,这将允许您使用您已经熟悉的Request
和Response
对象编写简单的客户端。
这绝对不是像Guzzle这样的东西的替代品,但它提供了一个简单轻量级的API,用于偶尔的API调用。
用法
use Sabre\HTTP; $request = new HTTP\Request('GET', 'http://example.org/'); $request->setHeader('X-Foo', 'Bar'); $client = new HTTP\Client(); $response = $client->send($request); echo $response->getBodyAsString();
客户端使用sabre/event
发出3个事件:beforeRequest
、afterRequest
和error
。
$client = new HTTP\Client(); $client->on('beforeRequest', function($request) { // You could use beforeRequest to, for example, inject a few extra headers // into the Request object. }); $client->on('afterRequest', function($request, $response) { // The afterRequest event could be a good time to do some logging, or // do some rewriting in the response. }); $client->on('error', function($request, $response, &$retry, $retryCount) { // The error event is triggered for every response with an HTTP code higher // than 399. }); $client->on('error:401', function($request, $response, &$retry, $retryCount) { // You can also listen for specific error codes. This example shows how // to inject HTTP authentication headers if a 401 was returned. if ($retryCount > 1) { // We're only going to retry exactly once. } $request->setHeader('Authorization', 'Basic xxxxxxxxxx'); $retry = true; });
异步请求
Client
也支持异步请求。如果您需要执行多个可以并行执行请求,这特别有用。
此功能的底层系统是简单的cURL多请求处理程序,但它提供了更友好的API来处理此功能。
示例用法
use Sabre\HTTP; $request = new Request('GET', 'http://localhost/'); $client = new Client(); // Executing 1000 requests for ($i = 0; $i < 1000; $i++) { $client->sendAsync( $request, function(ResponseInterface $response) { // Success handler }, function($error) { // Error handler } ); } // Wait for all requests to get a result. $client->wait();
查看examples/asyncclient.php
获取更多信息。
编写反向代理
结合所有这些工具,编写简单的反向HTTP代理变得非常容易。
use Sabre\HTTP\Sapi, Sabre\HTTP\Client; // The url we're proxying to. $remoteUrl = 'http://example.org/'; // The url we're proxying from. Please note that this must be a relative url, // and basically acts as the base url. // // If your $remoteUrl doesn't end with a slash, this one probably shouldn't // either. $myBaseUrl = '/reverseproxy.php'; // $myBaseUrl = '/~evert/sabre/http/examples/reverseproxy.php/'; $request = Sapi::getRequest(); $request->setBaseUrl($myBaseUrl); $subRequest = clone $request; // Removing the Host header. $subRequest->removeHeader('Host'); // Rewriting the url. $subRequest->setUrl($remoteUrl . $request->getPath()); $client = new Client(); // Sends the HTTP request to the server $response = $client->send($subRequest); // Sends the response back to the client that connected to the proxy. Sapi::sendResponse($response);
请求和响应API
请求
/** * Creates the request object * * @param string $method * @param string $url * @param array $headers * @param resource $body */ public function __construct($method = null, $url = null, array $headers = null, $body = null); /** * Returns the current HTTP method * * @return string */ function getMethod(); /** * Sets the HTTP method * * @param string $method * @return void */ function setMethod($method); /** * Returns the request url. * * @return string */ function getUrl(); /** * Sets the request url. * * @param string $url * @return void */ function setUrl($url); /** * Returns the absolute url. * * @return string */ function getAbsoluteUrl(); /** * Sets the absolute url. * * @param string $url * @return void */ function setAbsoluteUrl($url); /** * Returns the current base url. * * @return string */ function getBaseUrl(); /** * Sets a base url. * * This url is used for relative path calculations. * * The base url should default to / * * @param string $url * @return void */ function setBaseUrl($url); /** * Returns the relative path. * * This is being calculated using the base url. This path will not start * with a slash, so it will always return something like * 'example/path.html'. * * If the full path is equal to the base url, this method will return an * empty string. * * This method will also urldecode the path, and if the url was encoded as * ISO-8859-1, it will convert it to UTF-8. * * If the path is outside the base url, a LogicException will be thrown. * * @return string */ function getPath(); /** * Returns the list of query parameters. * * This is equivalent to PHP's $_GET superglobal. * * @return array */ function getQueryParameters(); /** * Returns the POST data. * * This is equivalent to PHP's $_POST superglobal. * * @return array */ function getPostData(); /** * Sets the post data. * * This is equivalent to PHP's $_POST superglobal. * * This would not have been needed if POST data was accessible as * php://input, but unfortunately we need to special-case it. * * @param array $postData * @return void */ function setPostData(array $postData); /** * Returns an item from the _SERVER array. * * If the value does not exist in the array, null is returned. * * @param string $valueName * @return string|null */ function getRawServerValue($valueName); /** * Sets the _SERVER array. * * @param array $data * @return void */ function setRawServerData(array $data); /** * Returns the body as a readable stream resource. * * Note that the stream may not be rewindable, and therefore may only be * read once. * * @return resource */ function getBodyAsStream(); /** * Returns the body as a string. * * Note that because the underlying data may be based on a stream, this * method could only work correctly the first time. * * @return string */ function getBodyAsString(); /** * Returns the message body, as its internal representation. * * This could be either a string or a stream. * * @return resource|string */ function getBody(); /** * Updates the body resource with a new stream. * * @param resource $body * @return void */ function setBody($body); /** * Returns all the HTTP headers as an array. * * @return array */ function getHeaders(); /** * Returns a specific HTTP header, based on its name. * * The name must be treated as case-insensitive. * * If the header does not exist, this method must return null. * * @param string $name * @return string|null */ function getHeader($name); /** * Updates an HTTP header. * * The case-sensitivity of the name value must be retained as-is. * * @param string $name * @param string $value * @return void */ function setHeader($name, $value); /** * Resets HTTP headers * * This method overwrites all existing HTTP headers * * @param array $headers * @return void */ function setHeaders(array $headers); /** * Adds a new set of HTTP headers. * * Any header specified in the array that already exists will be * overwritten, but any other existing headers will be retained. * * @param array $headers * @return void */ function addHeaders(array $headers); /** * Removes an HTTP header. * * The specified header name must be treated as case-insensitive. * This method should return true if the header was successfully deleted, * and false if the header did not exist. * * @return bool */ function removeHeader($name); /** * Sets the HTTP version. * * Should be 1.0, 1.1 or 2.0. * * @param string $version * @return void */ function setHttpVersion($version); /** * Returns the HTTP version. * * @return string */ function getHttpVersion();
响应
/** * Returns the current HTTP status. * * This is the status-code as well as the human-readable string. * * @return string */ function getStatus(); /** * Sets the HTTP status code. * * This can be either the full HTTP status code with human-readable string, * for example, "403 I can't let you do that, Dave". * * Or just the code, in which case the appropriate default message will be * added. * * @param string|int $status * @throws \InvalidArgumentExeption * @return void */ function setStatus($status); /** * Returns the body as a readable stream resource. * * Note that the stream may not be rewindable, and therefore may only be * read once. * * @return resource */ function getBodyAsStream(); /** * Returns the body as a string. * * Note that because the underlying data may be based on a stream, this * method could only work correctly the first time. * * @return string */ function getBodyAsString(); /** * Returns the message body, as its internal representation. * * This could be either a string or a stream. * * @return resource|string */ function getBody(); /** * Updates the body resource with a new stream. * * @param resource $body * @return void */ function setBody($body); /** * Returns all the HTTP headers as an array. * * @return array */ function getHeaders(); /** * Returns a specific HTTP header, based on its name. * * The name must be treated as case-insensitive. * * If the header does not exist, this method must return null. * * @param string $name * @return string|null */ function getHeader($name); /** * Updates an HTTP header. * * The case-sensitivity of the name value must be retained as-is. * * @param string $name * @param string $value * @return void */ function setHeader($name, $value); /** * Resets HTTP headers * * This method overwrites all existing HTTP headers * * @param array $headers * @return void */ function setHeaders(array $headers); /** * Adds a new set of HTTP headers. * * Any header specified in the array that already exists will be * overwritten, but any other existing headers will be retained. * * @param array $headers * @return void */ function addHeaders(array $headers); /** * Removes an HTTP header. * * The specified header name must be treated as case-insensitive. * This method should return true if the header was successfully deleted, * and false if the header did not exist. * * @return bool */ function removeHeader($name); /** * Sets the HTTP version. * * Should be 1.0, 1.1 or 2.0. * * @param string $version * @return void */ function setHttpVersion($version); /** * Returns the HTTP version. * * @return string */ function getHttpVersion();
由fruux制作
此库由fruux开发。如需商业服务或企业支持,请与我们联系。