laminas-api-tools / api-tools-content-negotiation
Laminas 模块,提供内容协商功能
Requires
- php: ~8.0.0 || ~8.1.0 || ~8.2.0
- laminas-api-tools/api-tools-api-problem: ^1.4.0
- laminas/laminas-eventmanager: ^2.6.3 || ^3.0.1
- laminas/laminas-filter: ^2.7.1
- laminas/laminas-http: ^2.5.4
- laminas/laminas-json: ^2.6.1 || ^3.0
- laminas/laminas-mvc: ^2.7.15 || ^3.0.2
- laminas/laminas-servicemanager: ^2.7.6 || ^3.1
- laminas/laminas-stdlib: ^2.7.8 || ^3.2.1
- laminas/laminas-validator: ^2.8.1
- laminas/laminas-view: ^2.8.1
- laminas/laminas-zendframework-bridge: ^1.0
Requires (Dev)
- laminas-api-tools/api-tools-hal: ^1.10
- laminas/laminas-coding-standard: ~2.3.0
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^9.5.27
- psalm/plugin-phpunit: ^0.16.1
- vimeo/psalm: ^4.30
Replaces
- zfcampus/zf-content-negotiation: ^1.4.0
This package is auto-updated.
Last update: 2024-09-10 23:24:21 UTC
README
🇷🇺 俄罗斯公民
我们是来自不同国家的 Laminas 参与者。我们中的许多人都有在俄罗斯和乌克兰的朋友、亲戚和同事。我们中的一些人出生在俄罗斯。我们中的一些人目前住在俄罗斯。我们中的一些人的祖父母在二战中与法西斯作战。在这里,没有人支持法西斯主义。
我们其中一个人有一个乌克兰亲戚,她和儿子一起从家中逃出。由于前方道路上的轰炸,火车延误了。我们有一些朋友躲在防空洞里。在空袭后,我们焦急地等待他们的消息,空袭无差别地攻击医院、学校、幼儿园和住宅。我们不从任何媒体上得知这些,我们是直接看到的。
您足够信任我们使用我们的程序,我们请求您再次信任我们。我们需要帮助。走出家门,抗议这场毫无意义的战争。停止杀戮。说“停止战争!”
🇺🇸 致俄罗斯公民
我们来自世界各地。我们中的许多人都在俄罗斯和乌克兰有朋友、家人和同事。我们中的一些人出生在俄罗斯。我们中的一些人目前住在俄罗斯。我们中的一些人的祖父母在二战中与纳粹作战。在这里,没有人支持法西斯主义。
团队成员之一有一个乌克兰亲戚,她和儿子一起从家中逃出。由于前方道路上的轰炸,火车延误了。我们有一些朋友躲在防空洞里。在空袭后,我们焦急地等待他们的消息,空袭无差别地攻击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些,这是我们亲身体验的。
您足够信任我们使用我们的软件。我们要求您信任我们说出真相。我们需要您的帮助。走出家门,抗议这场不必要的战争。停止杀戮。说“停止战争!”
简介
api-tools-content-negotiation
是一个模块,用于在 Laminas 框架应用程序中自动执行内容协商任务。
提供以下功能
- 将
Accept
头的媒体类型映射到特定的视图模型类型,并将控制器结果自动转换为这些视图模型类型。 - 定义
Accept
头的媒体类型白名单;具有不在白名单中的Accept
媒体类型的请求将被立即拒绝,返回406 Not Acceptable
响应。 - 定义
Content-Type
头的媒体类型白名单;发送具有不在白名单中的Content-Type
媒体类型的内容体的请求将被立即拒绝,返回415 Unsupported Media Type
响应。
需求
请参阅 composer.json 文件。
安装
运行以下 composer
命令
$ composer require laminas-api-tools/api-tools-content-negotiation
或者,手动将以下内容添加到您的 composer.json
文件中的 require
部分
"require": { "laminas-api-tools/api-tools-content-negotiation": "^1.2" }
然后运行 composer update
以确保已安装模块。
最后,将模块名称添加到项目的 config/application.config.php
文件下的 modules
键中。
return [ /* ... */ 'modules' => [ /* ... */ 'Laminas\ApiTools\ContentNegotiation', ], /* ... */ ];
laminas-component-installer
如果您使用 laminas-component-installer,该插件将自动将 api-tools-content-negotiation 作为模块安装。
配置
用户配置
此模块用户配置的最高级键是 api-tools-content-negotiation
。
键:controllers
controllers
键用于将内容协商策略映射到特定的控制器服务名称(从顶级 controllers
部分)。控制器数组的值部分可以是 命名选择器(见下文 selectors
),或者选择器定义。
选择器定义由一个数组组成,数组的键是视图模型名称,值是该视图模型匹配时将选择的媒体类型索引数组。
示例
'controllers' => [ // Named selector: 'Application\Controller\HelloWorld1' => 'Json', // Selector definition: 'Application\Controller\HelloWorld2' => [ 'Laminas\ApiTools\ContentNegotiation\JsonModel' => [ 'application/json', 'application/*+json', ], ], ],
键:selectors
selectors
键用于创建用于多个不同控制器之间重用的命名选择器定义。选择器数组的键部分将是一个用于关联选择器定义(使用在 controllers 键中描述的格式)的名称。
示例
'selectors' => [ 'Json' => [ 'Laminas\ApiTools\ContentNegotiation\JsonModel' => [ 'application/json', 'application/*+json', ], ], ],
选择器可以包含多个视图模型,每个视图模型与不同的媒体类型相关联,允许您提供多个表示形式。例如,以下选择器将允许给定的控制器返回 JSON 或 HTML 输出:
'selectors' => [ 'HTML-Json' => [ 'Laminas\ApiTools\ContentNegotiation\JsonModel' => [ 'application/json', 'application/*+json', ], 'Laminas\ApiTools\ContentNegotiation\ViewModel' => [ 'text/html', ], ], ],
键:accept_whitelist
accept_whitelist
键用于指示内容协商模块对于给定的控制器服务名称哪些媒体类型是可接受的。当在键中配置控制器服务名称以及匹配的媒体类型索引数组时,只有与给定请求的 Accept
头匹配的媒体类型将被允许进行调度。不匹配的媒体类型将收到 406 Cannot honor Accept type specified
响应。
每个控制器服务名称键的值可以是字符串或字符串数组。
示例
'accept_whitelist' => [ 'Application\\Controller\\HelloApiController' => [ 'application/vnd.application-hello+json', 'application/hal+json', 'application/json', ], ],
键:content_type_whitelist
content_type_whitelist
键用于指示内容协商模块对于请求的 Content-Type
哪些媒体类型是有效的。当在键中配置控制器服务名称以及匹配的媒体类型索引数组时,只有与给定请求的 Content-Type
头匹配的媒体类型将被允许进行调度。不匹配的媒体类型将收到 415 Invalid content-type specified
响应。
每个控制器服务名称键的值可以是字符串或字符串数组。
示例
'content_type_whitelist' => [ 'Application\\Controller\\HelloWorldController' => [ 'application/vnd.application-hello-world+json', 'application/json', ], ],
键:x_http_method_override_enabled
- 自 1.3.0 版本以来
此布尔标志确定是否默认启用 HttpMethodOverrideListener
。
键:http_override_methods
- 自 1.3.0 版本以来
http_override_methods
键用于向 HttpMethodOverrideListener
提供一个映射,该映射指定了给定 HTTP 方法允许的重写方法,通过 X-HTTP-Method-Override
头部指定。本质上,值是
'Incoming HTTP request method' => $arrayOfAllowedOverrideMethods,
例如,如果您想允许 X-HTTP-Method-Override
头部允许用备用方法覆盖 HTTP GET
请求,您可能定义如下:
'x_http_method_override_enabled' => true, 'http_override_methods' => [ 'GET' => [ 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH', ], ];
然后,要发出请求,您可以执行以下操作:
GET /foo HTTP/1.1 Host: example.com X-HTTP-Method-Override: PATCH some=content&more=content
上述操作将被解释为 PATCH
请求。如果使用 HTTP POST
发出相同的请求,或者使用包含 OPTIONS
重写值的 GET
请求,监听器将引发问题,因为在前一种情况下,没有为 POST
定义映射,而在后一种情况下,OPTIONS
不在 GET
的映射中。
系统配置
以下配置在 config/module.config.php
中提供,以启用模块的功能
'filters' => [ 'aliases' => [ 'Laminas\Filter\File\RenameUpload' => 'filerenameupload', ], 'factories' => [ 'filerenameupload' => Factory\RenameUploadFilterFactory::class, ], ], 'validators' => [ 'aliases' => [ 'Laminas\Validator\File\UploadFile' => 'fileuploadfile', ], 'factories' => [ 'fileuploadfile' => Factory\UploadFileValidatorFactory::class, ], ], 'service_manager' => [ 'factories' => [ ContentTypeListener::class => InvokableFactory::class, AcceptListener::class => Factory\AcceptListenerFactory::class, AcceptFilterListener::class => Factory\AcceptFilterListenerFactory::class, ContentTypeFilterListener::class => Factory\ContentTypeFilterListenerFactory::class, ContentNegotiationOptions::class => Factory\ContentNegotiationOptionsFactory::class, HttpMethodOverrideListener::class => Factory\HttpMethodOverrideListenerFactory::class, ], ], 'controller_plugins' => [ 'aliases' => [ 'routeParam' => ControllerPlugin\RouteParam::class, 'queryParam' => ControllerPlugin\QueryParam::class, 'bodyParam' => ControllerPlugin\BodyParam::class, 'routeParams' => ControllerPlugin\RouteParams::class, 'queryParams' => ControllerPlugin\QueryParams::class, 'bodyParams' => ControllerPlugin\BodyParams::class, ], 'factories' => [ ControllerPlugin\RouteParam::class => InvokableFactory::class, ControllerPlugin\QueryParam::class => InvokableFactory::class, ControllerPlugin\BodyParam::class => InvokableFactory::class, ControllerPlugin\RouteParams::class => InvokableFactory::class, ControllerPlugin\QueryParams::class => InvokableFactory::class, ControllerPlugin\BodyParams::class => InvokableFactory::class, ], ],
层压事件
监听器
Laminas\ApiTools\ContentNegotiation\AcceptListener
此监听器连接到MvcEvent::EVENT_DISPATCH
事件,优先级为-10
。它负责根据内容协商配置执行控制器视图模型的实际选择和转换。
Laminas\ApiTools\ContentNegotiation\ContentTypeListener
此监听器连接到MvcEvent::EVENT_ROUTE
事件,优先级为-625
。它负责检查Content-Type
头,以确定内容主体应该如何反序列化。然后,这些值将被保存在ParameterDataContainer
中,并存储在MvcEvent
对象的LaminasContentNegotiationParameterData
键中。
Laminas\ApiTools\ContentNegotiation\AcceptFilterListener
此监听器连接到MvcEvent::EVENT_ROUTE
事件,优先级为-625
。它负责确保路由选择的控制器配置为响应对当前请求的Accept
头中指定的特定媒体类型。如果不能,它将通过返回一个406 Cannot honor Accept type specified
响应来短路MVC调度过程。
Laminas\ApiTools\ContentNegotiation\ContentTypeFilterListener
此监听器连接到MvcEvent::EVENT_ROUTE
事件,优先级为-625
。它负责确保匹配到的路由控制器可以接受请求体中由当前请求的Content-Type
头中指定的媒体类型指定的内容。如果不能,它将通过返回一个415 Invalid content-type specified
响应来短路MVC调度过程。
Laminas\ApiTools\ContentNegotiation\HttpMethodOverrideListener
- 自 1.3.0 版本以来
此监听器连接到MvcEvent::EVENT_ROUTE
事件,优先级为-40
,但仅当x_http_method_override_enabled
配置标志被切换开时。它负责检查是否存在X-HTTP-Method-Override
头,如果存在,则它是否包含当前HTTP请求方法调用的允许集合中的值。如果是,则重置HTTP请求方法到头值。
层压服务
控制器插件
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\RouteParam (也称为 "routeParam")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回路由匹配中的单个具有特定名称的参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->routeParam('id', 'someDefaultValue'); } }
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\QueryParam (也称为 "queryParam")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回当前请求查询字符串中的单个参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->queryParam('foo', 'someDefaultValue'); } }
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\BodyParam (也称为 "bodyParam")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回内容协商内容主体中的单个参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->bodyParam('foo', 'someDefaultValue'); } }
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\RouteParams (也称为 "routeParams")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回所有路由参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->routeParams() } }
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\QueryParams (也称为 "queryParams")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回所有查询参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->queryParams() } }
Laminas\ApiTools\ContentNegotiation\ControllerPlugin\BodyParams (也称为 "bodyParams")
一个控制器插件(Laminas\Mvc\Controller\AbstractActionController
可调用)将返回所有内容协商主体参数。
use Laminas\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return $this->bodyParams() } }