rebelcode/wp-http

WordPress 的 PSR-18 兼容 HTTP 客户端适配器

0.3 2021-07-26 16:21 UTC

This package is auto-updated.

Last update: 2024-08-29 16:45:24 UTC


README

GitHub Workflow Status Packagist PHP Version Support Packagist Version Packagist License

一个符合 PSR-7 HTTP 消息和 PSR-18 HTTP 客户端标准的 WordPress HTTP 客户端。

注意:此包仅适用于 RebelCode 的 WordPress 产品,作为与其他插件(特别是使用 Guzzle 的插件)冲突的缓解手段;请随意使用此包,但请注意,这样做可能会导致冲突,这与包的目的相悖。

安装

使用 Composer

composer require rebelcode/wp-http

不使用 Composer

  1. src 目录的内容复制到您选择的目录中
  2. 使用自动加载器将 RebelCode\WordPress\Http 命名空间映射到该目录
  3. 建议使用 Composer

使用方法

创建客户端实例

use RebelCode\WordPress\Http\WpClient;
use RebelCode\WordPress\Http\WpHandler;
use RebelCode\WordPress\Http\HandlerStack;
use RebelCode\WordPress\Http\Middleware;

/*-----------------------------------------------------------------------------
 * Default configuration.
 * - Uses the `WpHandler`
 * - Uses the `HttpErrorsToExceptions` middleware
 * - Uses the `PrepareBody` middleware
 */
 
$client = WpClient::createDefault('https://base-url.com/api', [
    'timeout' => 30,
    'redirection' => 3,
]);

/*-----------------------------------------------------------------------------
 * Custom configuration with middleware:
 * - Create the `WpHandler`
 * - Create a `HandlerStack` with the handler and middleware factories
 * - Create the `WpClient` and pass the stack
 */
 
$wpHandler = new WpHandler([
    'timeout' => 30,
    'redirection' => 3,
]);

$handlerStack = new HandlerStack($wpHandler, [
    Middleware::factory(Middleware\PrepareBody::class)
]);

$client = new WpClient($handlerStack, 'https://base-url.com/api');

/*-----------------------------------------------------------------------------
 * For a zero-middleware configuration, you can simply pass the base handler
 */

$client = new WpClient($wpHandler, 'https://base-url.com/api');

发送请求

WpClient 实现 PSR-18 的 ClientInterface。请求通过 sendRequest() 方法发送。

use RebelCode\WordPress\Http\WpHandler;
use RebelCode\Psr7\Request;

$client = new WpClient(new WpHandler(), 'https://base-url.com/api');

$request = new Request('GET', '/users');
$response = $client->sendRequest($request);

架构

此包的设计和架构大致基于 Guzzle

WpClient 类实际上并不使用 WordPress HTTP API 发送请求。相反,它将请求处理委托给一个 HandlerInterface 实例。客户端直接负责的只有使用基本 URI(如果构造函数期间向客户端提供了基本 URI)解析相对请求 URI。

处理程序是对象,它接受一个 RequestInterface 实例并返回一个 ResponseInterface 实例。例如,WpHandler 将请求转换成 wp_remote_request() 函数所需的参数数组,调用该函数,然后将返回的值转换成一个 ResponseInterface 实例。

中间件

中间件是一种特殊的 HandlerInterface:它们接受一个 RequestInterface 并返回一个 ResponseInterface

关键区别是中间件实际上并不发送请求。相反,它们在构造函数期间接收一个 HandlerInterface 实例,并通过调用 $this->next($request) 将请求委托给它。

这允许将多个中间件链在一起,使得第一个中间件将第二个中间件作为参数传递,第二个中间件又将第三个中间件作为参数传递,依此类推。最后一个中间件将基本处理程序(通常是 WpClient 实例)作为参数传递。这种链式操作在 HandlerStack 中实现,它也是一个 HandlerInterface 实现。

中间件类可以接受额外的构造函数参数,只要接受处理程序参数并将其传递给父构造函数。

中间件的示例实现

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use RebelCode\WordPress\Http\Middleware;

class MyMiddleware extends Middleware {
    public function __construct(HandlerInterface $handler, $arg1, $arg2) {
        parent::__construct($handler);
        // ...
    }

    /** @inheritDoc*/
    public function handle(RequestInterface $request) : ResponseInterface{
        // Do something with the request
        $newRequest = $request->withHeader('X-Foo', 'Bar');
        
        // Delegate to the next handler
        $response = $this->next($newRequest);
        
        // Do something with the response and return it
        return $response->withHeader('X-Baz', 'Qux');
    }
}

中间件可以通过一个工厂函数传递给 HandlerStack,该工厂函数接受一个 HandlerInterface 实例并返回中间件实例。

$stack = new HandlerStack($baseHandler, [
    function ($handler) {
        return new MyMiddleware($handler, $arg1, $arg2);
    }
]);

如果中间件构造函数的第一个参数是处理程序,则可以使用 Middleware::factory() 辅助函数来减少样板代码。可以将额外的构造函数参数作为第二个参数传递,为数组形式。

$stack = new HandlerStack($baseHandler, [
    Middleware::factory(MyMiddleware::class, [$arg1, $arg2]),
]);