我一直在研究Guzzle中间件,并对某些事情有些困惑。
我的主要目标:建立自定义的中间件来记录请求和响应。
我正计划使用composer require rtheunissen/guzzle-log-middleware
,因为它似乎使创建我感兴趣的那种中间件变得容易得多-所有其他中间件似乎很麻烦或者也无法满足我的要求太多的魔术,几乎无法控制。
因此,无论如何,我感到困惑的是与中间件相关的整个“处理程序”业务。 Guzzle网站上的所有代码示例都创建一个curl处理程序,如下所示:
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push($middleware);
$client = new Client(['handler' => $stack]);
我需要打{{1}}吗?如果不需要,它会使用默认处理程序吗?仍然是默认处理程序CurlHandler吗?我只是想让guzzle像平常一样做,并使用该中间件软件包来记录请求和响应,我不想告诉Guzzle使用curl或其他任何东西。
答案 0 :(得分:2)
处理程序只是触发和处理请求响应的一种方式。
看看源代码,似乎您仅可以通过中间件传递HandlerStack
,似乎也需要一个处理程序。但是,您可以使用其create
静态方法创建默认的HandlerStack,然后最后推送您自己的中间件。像这样:
$stack = HandlerStack::create();
$stack->push($middleware);
$client = new Client(['handler' => $stack]);
这是如何创建默认HandlerStack的源代码。 Link
/**
* Creates a default handler stack that can be used by clients.
*
* The returned handler will wrap the provided handler or use the most
* appropriate default handler for your system. The returned HandlerStack has
* support for cookies, redirects, HTTP error exceptions, and preparing a body
* before sending.
*
* The returned handler stack can be passed to a client in the "handler"
* option.
*
* @param callable $handler HTTP handler function to use with the stack. If no
* handler is provided, the best handler for your
* system will be utilized.
*
* @return HandlerStack
*/
public static function create(callable $handler = null)
{
$stack = new self($handler ?: choose_handler());
$stack->push(Middleware::httpErrors(), 'http_errors');
$stack->push(Middleware::redirect(), 'allow_redirects');
$stack->push(Middleware::cookies(), 'cookies');
$stack->push(Middleware::prepareBody(), 'prepare_body');
return $stack;
}
$stack = new self($handler ?: choose_handler());
这是choose_handler()
函数,用于确定最佳处理程序。 Link
/**
* Chooses and creates a default handler to use based on the environment.
*
* The returned handler is not wrapped by any default middlewares.
*
* @throws \RuntimeException if no viable Handler is available.
* @return callable Returns the best handler for the given system.
*/
function choose_handler()
{
$handler = null;
if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
$handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
} elseif (function_exists('curl_exec')) {
$handler = new CurlHandler();
} elseif (function_exists('curl_multi_exec')) {
$handler = new CurlMultiHandler();
}
if (ini_get('allow_url_fopen')) {
$handler = $handler
? Proxy::wrapStreaming($handler, new StreamHandler())
: new StreamHandler();
} elseif (!$handler) {
throw new \RuntimeException('GuzzleHttp requires cURL, the '
. 'allow_url_fopen ini setting, or a custom HTTP handler.');
}
return $handler;
}
当涉及到这类小众事物时,耗时的文档可能会有些烦人,不要害怕查看源代码以更好地了解事物。