modethirteen / hyperplug
一个用于连接HTTP套接字的PHP库
dev-main
2021-09-12 03:35 UTC
Requires
- php: ~7.4.12
- ext-curl: *
- ext-fileinfo: *
- ext-json: *
- modethirteen/type-ex: dev-main
- modethirteen/xarray: dev-main
Requires (Dev)
- phpstan/phpstan: ~0.12.57
- phpunit/phpunit: ~9.4.3
This package is auto-updated.
Last update: 2024-09-14 10:13:42 UTC
README
一个用于连接HTTP套接字的PHP库。
- PHP 7.4 (主要,2.x)
安装
使用 Composer。有两种方法可以将此库添加到您的项目中。
从Composer CLI
./composer.phar require modethirteen/hyperplug
或在项目的composer.json中添加modethirteen/hyperplug
{ "require": { "modethirteen/hyperplug": "dev-main" } }
dev-main
是主要开发分支。如果您在生产环境中使用此库,建议您使用稳定版本。
假设您已设置Composer的自动加载器,库可以在 modethirteen\Http\
命名空间中找到。
入门
快速示例
$plug = new Plug(XUri::newFromString('https://api.example.com/v2')) ->withResultParser(new JsonParser()); $result = $plug->at('users', 'bob') ->get(); if($result->isSuccess()) { // great job! echo $result->getVal('body/name'); }
用法
// the library allows for programmatic URL construction and parsing $uri = XUri::newFromString('http://api.example.com/v3') // every step in a URL builder returns an immutable XUri object ->withScheme('https') ->at('widgets') ->withQueryParam('xyzzy', 'plugh') ->withQueryParams(QueryParams::newFromArray([ 'bar' => 'qux', 'baz' => 'fred' ])) ->withoutQueryParam('bar'); // QueryParams objects are normally immutable $params = $uri->getQueryParams(); // we can change the data structure of a QueryParams object if we must $params = $params->toMutableQueryParams(); $params->set('baz', 'abc'); // QueryParams are also iterable foreach($params as $param => $value) { $uri = $uri->withReplacedQueryParam($param, $value); } // what does our URL look like now? $result = $uri->toString(); // https://api.example.com/v3/widgets?xyzzy=plugh&baz=abc // we can give our XUri object to a Plug to create a client $plug = new Plug($uri); // like every object in this library, attaching new values or behaviors to plugs is by default immutable // ...and returns a new object reference // add credentials for authorization $plug->withCredentials('franz', 'beckenbauer'); // or a bearer token $plug->withHeader('Authorization', 'Bearer 12345'); // we can add some additional URL path segments and query parameters that weren't part of the constructing URL $plug = $plug->at('another', 'additional', 'endpoint', 'segment')->with('more', 'params'); // how many redirects will we follow? $plug = $plug->withAutoRedirects(2); // HTTP requests often need HTTP headers $plug = $plug->withHeader('X-FcStPauli', 'hells') ->withAddedHeader('X-FcStPauli', 'bells') ->withHeader('X-HSV', 'you\'ll never walk again'); // ...or not $plug = $plug->withoutHeader('X-HSV'); // the Headers object, like XUri and QueryParams, is normally immutable $headers = $plug->getHeaders(); $result = $headers->getHeader('X-FcStPauli'); // ['hells', 'bells'] $result = $headers->getHeaderLine('X-FcStPauli'); // X-HSV: hells, bells // but if you really want to... $mutableHeaders = $headers->toMutableHeaders(); $mutableHeaders->set('X-HSV', 'keiner mag den hsv'); // a Headers object is iterable foreach($mutableHeaders as $header => $values) { foreach($values as $value) { // HTTP headers can have multiple stored values // ...though normally sent via an HTTP client as comma separated on a single HTTP header line echo "{$header}: {$value}"; } } // also we can merge the two sets of Headers (the original and the mutated one) // ...to create a brand new object containing the values of both $mergedHeaders = $headers->toMergedHeaders($mutableHeaders); // we've built out a pretty complex HTTP client now // ...but what if we want a client with a different URL but everything else the same? $alternateApiPlug = $plug->withUri(XUri::newFromString('https://db.example.com/graph')); // we are going to invoke an HTTP request // ...pre and post invocation callbacks can attach special logic and handlers // ...intended to be executed whenever or wherever this HTTP client is used // ...maybe there is some logic we want to always perform at the moment the HTTP request is about to be sent? $plug = $plug->withPreInvokeCallback(function(XUri $uri, IHeaders $headers) { // last chance to change the URL or HTTP headers before the request is made // ...URL and HTTP headers for the single request invocation can be mutated // ...this will not affect the URL or HTTP headers configured in the plug $headers->toMutableHeaders()->addHeader('something', 'contextual'); }); // multiple callbacks can be attached (they are executed in the order they are attached) $plug = $plug->withPreInvokeCallback(function(XUri $uri, IHeaders $headers) { }); // maybe we want to attach some special handlin that always executes when we receive an HTTP response? $plug = $plug->withPostInvokeCallback(function(Result $result) { // perhaps there is special behavior to always trigger based on the HTTP response status code? if($result->is(403)) { } }); // HTTP responses can be parsed from text into traversable data structures by attaching one or more ResultParser objects // ...parsing can be possibly memory intensive, so limits can be put on the allowed size of a response to parse $plug = $plug->withResultParser((new JsonParser())->withMaxContentLength(640000)); // fetching resources is handled via HTTP GET $result = $plug->get(); // deleting resources is handled via HTTP $result = $plug->delete(); // POST or PUT can optionally send data, in a several different content types as needed $result = $plug->post( (new MultiPartFormDataContent([ 'a' => 'b', 'c' => 'd' ])) ->withFileContent(new FileContent('/path/to/file')) ); $result = $plug->put(new FileContent('/path/to/file')); $result = $plug->post(new UrlEncodedFormDataContent([ 'e' => 'f', 'g' => 'h' ])); $result = $plug->post(JsonContent::newFromArray([ 'a' => [ 'multi-dimensional' => [ 'data', 'structure' ] ] ])); $result = $plug->post(XmlContent::newFromArray([ 'another' => [ 'multi-dimensional' => [ 'data', 'structure' ], 'formatted' => 'as xml' ] ])); $result = $plug->put(new TextContent('good old text!'));
开发和测试
社区贡献始终受到欢迎(存在需要解决的问题和改进)。
该库通过结合 PHPUnit、MockPlug
(一个匹配 HyperPlug
调用并返回模拟响应的拦截器)以及实际的 cURL-驱动的HTTP请求到本地托管的服务器 httpbin 进行测试。进一步使用 PHPStan(PHP静态分析工具)检查代码质量。
# fork and clone the HyperPlug repository git clone git@github.com:{username}/HyperPlug.git # install dependencies composer install # start the httpbin container docker-compose up -d # run static analysis checks vendor/bin/phpstan analyse # run tests export HTTPBIN_BASEURI=https://:8080 vendor/bin/phpunit --configuration phpunit.xml.dist