chroma-x/basic-http-client

这是一个基本的、可扩展的HTTP客户端库,提供多种认证方法,由PHP编写。

4.0.1 2024-08-02 09:26 UTC

README

Build Status SensioLabs Insight Code Climate Codacy Badge Latest Stable Version Total Downloads License

这是一个基本的、可扩展的HTTP客户端库,提供多种认证方法,由PHP编写。

关于PSR-7怎么办?

PHP Basic HTTP Client 是一个替代其他非常好实现的库,如遵循 PSR-7 规范Guzzle

这个项目出于不同的原因不遵循这些规范。

  1. PSR-7 由于也要匹配复杂的边缘情况,因此过度设计。
  2. 实现 PSR-7 接口的对象必须是不可变的,这从PHP开发者的角度来看导致了一个不寻常的API,并导致对性能的不必要需求增加。

更多详情请参考PHP-FIG成员Evert Pot 的博客文章“PSR-7 即将到来,这是我的一些问题”和Stackoverflow上的讨论

安装

{
   	"require": {
        "chroma-x/basic-http-client": "~4.0"
    }
}

用法

自动加载和命名空间

require_once('path/to/vendor/autoload.php');

简单用法

准备HTTP客户端

use ChromaX\BasicHttpClient;
use ChromaX\BasicHttpClient\Request\Authentication;
use ChromaX\BasicHttpClient\Request\Message;

// Instantiating a basic HTTP client with the endpoints URL
// If the endpoint uses the `HTTPS` schema a `HttpsTransport` instance will be used automatically.
$client = new BasicHttpClient\BasicHttpClient('http://requestb.in/1aipzl31');

// Adding an authentication method
$client
	->getRequest()
	->addAuthentication(new Authentication\BasicAuthentication('username', 'password'));

// Adding custom HTTP request headers and a session cookie
$client
	->getRequest()
	->getMessage()
	->addHeader(new Message\Header\Header('Content-Type', array('application/x-www-form-urlencoded')))
	->addHeader(new Message\Header\Header('Accept', array('text/html', 'text/*')))
	->addCookie(new Message\Cookie\Cookie('PHPSESSID', '<MY_SESSION_ID>'));

执行请求并读取响应

无体请求(GET、HEAD 和 DELETE)

执行以下带有附加查询参数的 GET 请求

$response = $client->get(array(
	'paramName1' => 'paramValue1',
	'paramName2' => 'paramValue2'
));

将生成以下HTTP请求。

GET /1aipzl31?paramName1=paramValue1&paramName2=paramValue2 HTTP/1.1
Host: requestb.in
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: PHP Basic HTTP Client 1.0
Cookie: PHPSESSID=<MY_SESSION_ID>
Content-Type: application/x-www-form-urlencoded
Accept: text/html, text/*

提供相同的机制来执行 HEADDELETE 请求,它们都是无体的。

有体请求(POST、PUT、PATCH)

执行以下带有正文数据的 POST 请求

$response = $client->post(array(
	'paramName1' => 'paramValue1',
	'paramName2' => 'paramValue2',
	'paramName3' => array(
		'key1' => 'value1',
		'key2' => 'value2'
	)
));

将生成以下HTTP请求。

POST /1aipzl31?paramName1=paramValue1&paramName2=paramValue2 HTTP/1.1
Host: requestb.in
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: PHP Basic HTTP Client 1.0
Cookie: PHPSESSID=<MY_SESSION_ID>
Content-Type: application/x-www-form-urlencoded
Accept: text/html, text/*
Content-Length: 101

paramName1=paramValue1&paramName2=paramValue2&paramName3%5Bkey1%5D=value1&paramName3%5Bkey2%5D=value2

提供相同的机制来执行 PUTPATCH 请求,它们都是有体的。

详细用法

以下示例展示了更详细的配置用法。

配置HTTP传输实例

use ChromaX\BasicHttpClient\Request\Transport\HttpTransport;

// Configuring a Transport instance
$transport = new HttpTransport();
$transport
	->setHttpVersion(HttpsTransport::HTTP_VERSION_1_1)
	->setTimeout(5)
	->setReuseConnection(true)
	->setAllowCaching(true)
	->setFollowRedirects(true)
	->setMaxRedirects(10);

配置HTTPS传输实例

use ChromaX\BasicHttpClient\Request\Transport\HttpsTransport;

// Configuring a Transport instance
$transport = new HttpsTransport();
$transport
	->setHttpVersion(HttpsTransport::HTTP_VERSION_1_1)
	->setTimeout(5)
	->setReuseConnection(true)
	->setAllowCaching(true)
	->setFollowRedirects(true)
	->setMaxRedirects(10)
	->setVerifyHost(true)
	->setVerifyPeer(true);

配置带有正文的Message实例

use ChromaX\BasicHttpClient\Request\Message\Body\Body;
use ChromaX\BasicHttpClient\Request\Message\Cookie\Cookie;
use ChromaX\BasicHttpClient\Request\Message\Header\Header;
use ChromaX\BasicHttpClient\Request\Message\Message;

// Configuring a message Body instance
$messageBody = new Body();
$messageBody->setBodyText(
	json_encode(
		array(
			'paramName1' => 'paramValue1',
			'paramName2' => 'paramValue2',
			'paramName3' => array(
				'key1' => 'value1',
				'key2' => 'value2'
			)
		)
	)
);

// Configuring a Message instance
$message = new Message();
$message
	->addHeader(new Header('Content-Type', array('application/json')))
	->addHeader(new Header('Accept', array('application/json', 'text/*')))
	->addHeader(new Header('Runscope-Bucket-Auth', array('7a64dde7-74d5-4eed-b170-a2ab406eff08')))
	->addCookie(new Cookie('PHPSESSID', '<MY_SESSION_ID>'))
	->setBody($messageBody);
Message和请求头实例

请注意,头有一些不寻常的行为。 头名称有一个统一的命名方式,因此以下三个getter调用会产生相同的结果。

$header1 = $message->getHeaderByName('Content-Type');
$header2 = $message->getHeaderByName('content-type');
$header3 = $message->getHeaderByName('CONTENT-Type');

为了允许使用相同名称的多个请求头,addAdditionalHeader 方法提供了这种逻辑。

// Add or replace a request header
$message->addHeader(new Header('Custom-Header', array('CustomHeaderValue')));
// Add a request header and keep the existing one untouched
$message->addAdditionalHeader(new Header('Custom-Header', array('AnotherCustomHeaderValue')));

配置端点URL,构建Request实例并执行HTTP请求

有关URL对象的更多使用信息,请参阅PHP URL Util项目。

use ChromaX\BasicHttpClient\Request\Authentication\BasicAuthentication;
use ChromaX\BasicHttpClient\Request\Request;
use ChromaX\UrlUtil\Url;

// Setting up the endpoints URL
$url = new Url('https://john:secret@yourapihere-com-98yq3775xff0.runscope.net:443/path/to/resource?arg1=123#fragment');

// Configuring and performing a Request
$request = new Request();
$request
	->setUserAgent('PHP Basic HTTP Client Test 1.0')
	->setUrl($url)
	->addAuthentication(new BasicAuthentication('username', 'password'))
	->setQueryParameters(
		array(
			'paramName1' => 'paramValue1',
			'paramName2' => 'paramValue2'
		)
	)
	->setMethod(Request::REQUEST_METHOD_POST)
	->setTransport($transport)
	->setMessage($message)
	->perform();

生成的HTTP请求如下。

POST /?arg1=123#fragment HTTP/1.1
Host: yourapihere-com-98yq3775xff0.runscope.net
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: PHP Basic HTTP Client Test 1.0
Cookie: PHPSESSID=<MY_SESSION_ID>
Content-Type: application/json
Accept: application/json, text/*
Runscope-Bucket-Auth: 7a64dde7-74d5-4eed-b170-a2ab406eff08
Custom-Header: CustomHeaderValue
Custom-Header: AnotherCustomHeaderValue
Content-Length: 102

{"paramName1":"paramValue1","paramName2":"paramValue2","paramName3":{"key1":"value1","key2":"value2"}}

认证方法的使用

您可以为每个Request实例添加一个或多个Authentication实例。目前,该项目提供了HTTP基本认证SSL客户端证书认证的类。

HTTP基本认证

所需的凭据是一个 用户名 和一个 密码,它们作为参数传递给类构造函数。

use ChromaX\BasicHttpClient\Request\Authentication\BasicAuthentication;
use ChromaX\BasicHttpClient\Request\Request;

// Configuring the authentication
$basicAuthentication = new BasicAuthentication('username', 'password');

// Adding the authentication instance to the Request
$request = new Request();
$request->addAuthentication($basicAuthentication);

SSL客户端证书认证

所需的凭证包括一个证书颁发机构证书、一个客户端证书以及用于解密提供给类构造函数的客户端证书的密码。

use ChromaX\BasicHttpClient\Request\Authentication\ClientCertificateAuthentication;
use ChromaX\BasicHttpClient\Request\Request;

// Configuring the authentication
$clientCertificateAuthentication = new ClientCertificateAuthentication(
	'/var/www/project/clientCert/ca.crt',
	'/var/www/project/clientCert/client.crt',
	'clientCertPassword'
);

// Adding the authentication instance to the Request
$request = new Request();
$request->addAuthentication($clientCertificateAuthentication);

从结果响应对象中读取

获取响应对象

如果使用BasicHttpClient,则上述终止方法会返回响应对象。如果直接使用请求实例,您可以通过getter获取响应对象。

// Getting the response ChromaX\BasicHttpClient\Response\Response object
$response = $request->getResponse();

// Reading the HTTP status code as integer; will return `200`
echo print_r($response->getStatusCode(), true) . PHP_EOL;

// Reading the HTTP status text as string; will return `HTTP/1.1 200 OK`
echo print_r($response->getStatusText(), true) . PHP_EOL;

// Reading the HTTP response headers as array of ChromaX\BasicHttpClient\Response\Header\Header objects
echo print_r($response->getHeaders(), true) . PHP_EOL;

// Reading the HTTP response body as string
echo print_r($response->getBody(), true) . PHP_EOL;

获取有效的请求信息

请求成功执行后,有效的请求信息会被跟踪回请求对象。可以通过以下方式访问它们。

// Getting the effective endpoint URL including the query parameters
echo print_r($request->getEffectiveEndpoint(), true) . PHP_EOL;

// Getting the effective HTTP status, f.e. `POST /?paramName1=paramValue1&paramName2=paramValue2&paramName3=1&paramName4=42 HTTP/1.1`
echo print_r($request->getEffectiveStatus(), true) . PHP_EOL;

// Getting the effective raw request headers as string
echo print_r($request->getEffectiveRawHeader(), true) . PHP_EOL;

// Getting the effective request headers as array of `ChromaX\BasicHttpClient\Request\Message\Header\Header` objects
echo print_r($request->getEffectiveHeaders(), true) . PHP_EOL.PHP_EOL;

获取一些事务统计信息

// Getting the statistics ChromaX\BasicHttpClient\Response\Statistics\Statistics object
$statistics = $request->getResponse()->getStatistics();

// Reading the redirection URL if the server responds with an redirect HTTP header and 
// followRedirects is set to false
echo print_r($statistics->getRedirectEndpoint(), true).PHP_EOL;

// Reading the numbers of redirection as integer
echo print_r($statistics->getRedirectCount(), true).PHP_EOL;

// Getting the time in seconds the redirect utilized as float
echo print_r($statistics->getRedirectTime(), true).PHP_EOL;

// Getting the time in seconds that was utilized until the connection was established
echo print_r($statistics->getConnectionEstablishTime(), true).PHP_EOL;

// Getting the time in seconds that was utilized until the DNS hostname lookup was done
echo print_r($statistics->getHostLookupTime(), true).PHP_EOL;

// Getting the time in seconds that was utilized before the first data was sent
echo print_r($statistics->getPreTransferTime(), true).PHP_EOL;

// Getting the time in seconds that was utilized before the first data was received
echo print_r($statistics->getStartTransferTime(), true).PHP_EOL;

// Getting the time in seconds that was utilized to perfom the request an read the response
echo print_r($statistics->getTotalTime(), true).PHP_EOL;

扩展基本HTTP客户端

客户端的每个部分都基于合适的接口。大多数类实例都可以注入到客户端本身。如果您想扩展客户端,只需编写一些实现相应接口的类即可。

请参阅PHP JSON HTTP客户端,它是PHP基本HTTP客户端的扩展。

异常处理

PHP基本HTTP客户端提供了不同的异常——也由PHP公共异常项目提供——以进行适当的处理。
您可以在GitHub上的PHP公共异常中找到更多信息。

预期的异常

通常,您应该预期任何setter方法可能会抛出\InvalidArgumentException。在使用PHP基本HTTP客户端时,可能会抛出以下异常。

  • 在配置ClientCertificateAuthentication实例时抛出ChromaX\CommonException\IoException\FileNotFoundException
  • 在配置ClientCertificateAuthentication实例时抛出ChromaX\CommonException\IoException\FileReadableException
  • 在执行请求时抛出ChromaX\BasicHttpClient\Exception\HttpRequestAuthenticationException
  • 在执行请求时抛出ChromaX\BasicHttpClient\Exception\HttpRequestException
  • 在执行请求时抛出ChromaX\CommonException\NetworkException\ConnectionTimeoutException
  • 在执行请求时抛出ChromaX\CommonException\NetworkException\CurlException

贡献

对我们的项目做出贡献总是非常受欢迎的。
但是:请遵循CONTRIBUTING.md文档中写明的贡献指南。

许可证

PHP基本HTTP客户端受MIT许可证的约束。