webignition / encapsulating-request-resolver-bundle
Symfony控制器操作参数解析器,用于扩展Symfony\Component\HttpFoundation\Request的类型
Requires
- php: ^8.1
- ext-json: *
- symfony/config: ^6.0
- symfony/dependency-injection: ^6.0
- symfony/http-kernel: ^6.0
- symfony/yaml: ^6.0
Requires (Dev)
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.4
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.6
README
轻松将您自己的请求封装对象注入到控制器操作中。
厌倦了将当前请求注入到您的控制器操作中,然后不得不在 $request->query
或 $request->request
中寻找相关数据吗?
是否曾发现自己想要通过封装当前请求并调用特定领域的方法来以更特定领域的方式模拟入站请求以获取有关请求的信息?
这可以帮助你做到这一点。
平台要求
- PHP
>=8.0.2
- Symfony
5.4.* || 6.0.*
安装
作为composer依赖项添加
composer require webignition/encapsulating-request-resolver-bundle
注册bundle(如果未使用Symfony Flex)
# config/bundles.php return [ //... webignition\EncapsulatingRequestResolverBundle\EncapsulatingRequestResolverBundle::class => ['all' => true], ];
使用方法
任何实现 EncapsulatingRequestInterface
的对象都可以作为控制器操作参数注入。
EncapsulatingRequestInterface
有一个单例的 create()
方法,该方法接受当前请求。你可以对请求做任何你想做的事情。
示例用户创建场景
场景
考虑一个创建应用程序用户的API端点。该端点期望一个具有电子邮件和密码字段的负载的POST
请求。控制器最终负责访问请求的相关方面并将这些信息提供给相关服务。
不使用此bundle
我们可以将当前请求注入到控制器操作中并在请求有效负载中进行检查。
# src/Controller/UserController namespace App\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class UserController { public function create(Request $request): Response { $email = (string) $request->request->get('email'); $password = (string) $request->request->get('password'); // ... pass $email and $password to relevant services, build and return a response } }
这是一个非常简化的例子。在实践中,我们可能想要检查$email
和$password
是否都不为空。
对于更复杂的请求,在处理请求数据之前可能需要验证请求数据。很容易开始进入请求访问逻辑超出控制器职责的领域。
即使是更简单的例子,控制器也需要了解请求有效负载的形状。可以争辩说,即使是这样一点信息也可能超出了控制器的职责。
使用此bundle
我们可以为处理和理解创建用户请求中存在的数据创建一个自定义请求类。处理Symfony请求的逻辑封装在自定义请求类中。自定义请求类被注入到控制器操作中。
你的请求处理逻辑越复杂或越复杂,将此逻辑保留在其自己的类下的责任可能就越有意义。
# src/Request/CreateUserRequest.php namespace App\Request; use Symfony\Component\HttpFoundation\Request; use webignition\EncapsulatingRequestResolverBundle\Model\EncapsulatingRequestInterface; class CreateUserRequest implements EncapsulatingRequestInterface { public function __construct(private string $email, private string $password) { } public static function create(Request $request): CreateUserRequest { return new CreateUserRequest( (string) $request->request->get('email'), (string) $request->request->get('password') ); } public function getEmail(): string { return $this->email; } public function getPassword(): string { return $this->password; } }
# src/Controller/UserController namespace App\Controller; use App\Request\CreateUserRequest; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class UserController { public function create(CreateUserRequest $request): Response { $email = $request->getEmail(); $password = $request->getPassword()); // ... pass $email and $password to relevant services, build and return a response } }