acelaya/ze-content-based-error-handler
这是一个基于内容的错误处理器,允许根据接受的内容类型实现不同的策略。
Requires
- php: ^7.2
- psr/log: ^1.0
- zendframework/zend-expressive: ^3.0
- zendframework/zend-servicemanager: ^3.0
Requires (Dev)
- infection/infection: ^0.13.4
- phpstan/phpstan: ^0.11.15
- phpunit/phpunit: ^8.3
- shlinkio/php-coding-standard: ~1.2.1
- zendframework/zend-diactoros: ^2.1.3
README
如果您需要根据请求接受的内容类型返回不同类型的响应,则可以针对每种类型使用不同的中间件,并在没有生成响应的情况下调用下一个处理器。
Zend Expressive ContentBasedErrorResponseGenerator
这是一个允许根据接受的内容类型实现不同策略来渲染错误响应的Zend Expressive错误响应生成器。
背景
根据这篇文章 https://blog.alejandrocelaya.com/2016/07/29/creating-a-content-based-error-handler-for-zend-expressive/ 创建了此包。
在这篇文章中,我演示了如何实现一个基于策略的系统,通过考虑请求的 Accept
头来生成不同的错误响应。
在写完这篇文章后,我决定创建这个包,以便每个人都可以在自己的项目中安装和使用提供的解决方案。
然后,该包发展到支持Expressive 2,它完全摒弃了错误处理器的概念。从v2开始,它提供了错误响应生成器。
安装
使用composer安装此包
composer require acelaya/ze-content-based-error-handler
使用方法
此包包含一个错误响应生成器,名为 Acelaya\ExpressiveErrorHandler\ErrorHandler\ContentBasedErrorResponseGenerator
,可用于替换默认的Zend Expressive实现。
它组合了一个插件管理器,在运行时根据请求的 Accept
头获取具体的错误响应生成器。因此,您可以使用Expressive的 ErrorResponseGenerator
来分配 text/html 请求错误,Stratiglity的 ErrorResponseGenerator
用于 text/plain 错误等。
您还可以为其他内容类型提供自己的实现,如 application/json 或 text/xml。ContentBasedErrorResponseGenerator将自动使用适当的实现。
提供的配置
为了轻松工作,包含了一个 ConfigProvider
,它自动将所有依赖项注册到服务容器中(包括 Zend\Expressive\Middleware\ErrorResponseGenerator
服务)。
它还预注册了html和纯文本请求的错误处理器(前面提到的 Zend\Expressive\Middleware\ErrorResponseGenerator
和 Zend\Stratigility\Middleware\ErrorResponseGenerator
)。
<?php use Acelaya\ExpressiveErrorHandler\ErrorHandler\Factory\PlainTextResponseGeneratorFactory; use Zend\Expressive\Container\ErrorResponseGeneratorFactory; return [ 'error_handler' => [ 'default_content_type' => 'text/html', 'plugins' => [ 'factories' => [ 'text/plain' => PlainTextResponseGeneratorFactory::class, 'text/html' => ErrorResponseGeneratorFactory::class, ], 'aliases' => [ 'application/xhtml+xml' => 'text/html', ], ], ], ];
plugins 块是插件管理器所使用的。有关插件管理器如何工作的更多信息,请参阅 此。
为了使用内置的ConfigProvider,创建一个包含以下内容的配置文件
<?php return (new Acelaya\ExpressiveErrorHandler\ConfigProvider())->__invoke();
如果您正在使用 zend 配置聚合器,只需将类名传递给它即可,如下所示
return (new Zend\ConfigAggregator\ConfigAggregator([ Acelaya\ExpressiveErrorHandler\ConfigProvider::class, // [...] new Zend\ConfigAggregator\ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'), ], 'data/cache/app_config.php'))->getMergedConfig();
此外,如果您正在使用 zend 组件安装程序 包,安装时会提示您注册 ConfigProvider。
覆盖配置
如果您需要覆盖任何内容类型,只需定义具有不同值的相同插件即可。
例如,您很可能会希望在开发环境中使用 Expressive 的 WhoopsErrorResponseGenerator
。
只需定义一个包含此内容的本地配置文件,从现在开始所有 HTML 请求都将使用它
<?php use Zend\Expressive\Container\WhoopsErrorResponseGeneratorFactory; use Zend\Expressive\Container\WhoopsFactory; use Zend\Expressive\Container\WhoopsPageHandlerFactory; return [ 'dependencies' => [ 'factories' => [ 'Zend\Expressive\Whoops' => WhoopsFactory::class, 'Zend\Expressive\WhoopsPageHandler' => WhoopsPageHandlerFactory::class, ] ], 'error_handler' => [ 'plugins' => [ 'factories' => [ 'text/html' => WhoopsErrorResponseGeneratorFactory::class, ], ], ], ];
您可能需要为不同内容类型定义其他错误处理程序。您可以通过使用相同的结构来完成此操作。
<?php use App\ErrorHandler\Factory\XmlErrorResponseGeneratorFactory; use App\ErrorHandler\JsonErrorResponseGenerator; return [ 'error_handler' => [ 'plugins' => [ 'invokables' => [ 'application/json' => JsonErrorResponseGenerator::class, ], 'factories' => [ 'text/xml' => XmlErrorResponseGeneratorFactory::class, ], 'aliases' => [ 'application/x-json' => 'application/json', 'text/json' => 'application/json', ], ], ], ];
使用此配置,ContentBasedErrorResponseGenerator
将在运行时创建适当的 JsonErrorResponseGenerator
或 XmlErrorResponseGenerator
,以分派 json 或 xml 错误。
类似地,您可能需要通过设置 default_content_type
属性来覆盖默认内容类型。
<?php return [ 'error_handler' => [ 'default_content_type' => 'application/json', ], ];
这样,当客户端没有提供 Accept
标头或没有注册接受的内容类型时,将使用 application/json 内容类型,而不是默认的 text/html。
记录错误
此包允许您向 ContentBasedErrorResponseGenerator
提供一个 psr-3 日志记录器,以便记录错误。
默认情况下使用 Psr\Log\NullLogger
,因此不会记录任何错误,但如果在 Psr\Log\LoggerInterface
服务名称下注册了日志记录器,则将在创建时将其注入到 ContentBasedErrorResponseGenerator
中。
记录的消息也可以自定义。ContentBasedErrorResponseGenerator
期望注入实现 Acelaya\ExpressiveErrorHandler\Log\LogMessageBuilderInterface
的对象。
提供了一个基本实现,即 Acelaya\ExpressiveErrorHandler\Log\BasicLogMessageBuilder
,它基本上记录消息 "在分派请求时发生错误",并在新行上附加错误。
您可以通过创建自己的服务并使用 Acelaya\ExpressiveErrorHandler\Log\LogMessageBuilderInterface
名称注册它来轻松覆盖此实现。