让我们谈谈表单请求

发布于 作者

Let's talk about Form Requests image

表单请求最出名的是将您的验证逻辑从 Web 控制器移到一个类中,该类会为您预先进行验证。它们很棒,我经常依靠它们。但是,我们还能对表单请求做些什么呢?

除了添加您的方法并在控制器中调用它们之外,还有一些方法通常不会在您的表单请求中使用,您可以依靠这些方法为您的应用程序添加额外的超级能力。

准备您的输入以进行验证

当您必须在验证器开始之前转换或添加到请求中时,此方法非常棒。文档显示了将 slug 合并到某事物的示例,这很有用,但另一个示例呢?

protected function prepareForValidation(): void
{
$this->merge([
'locale' => $this->user()->locale,
]);
}

我们正在将经过身份验证的用户的区域设置合并到请求中 - 因此我们可能会根据用户的区域设置执行动态验证。假设我们现在在应用程序中设置了限制,这意味着来自威尔士(我住的地方)的用户必须以特定格式添加内容。随机的,但我作为开发人员已经看到了几个可能有用的用例。

我们甚至可以在此方法中动态替换内容。

protected function prepareInputForValidation(): void
{
$replace = match ($this->user()->locale) {
'en_GB' => 17.5,
'en_US' => 10.0,
'de_DE' => 12.5,
};
 
$this->replace([
'tax_percentage' => $replace,
]);
}

在这里,我们根据用户的区域设置动态更改税率。如果您作为分销商将特定税率作为进口税的一部分,这将很有用。

通过验证

与准备验证非常相似,我们可以利用验证后的传递、标准化或格式化请求数据以特定格式。作为每天处理数据的人,这非常有用。

protected function passedValidation(): void
{
$this->replace([
'name' => Str::uppercase($this->name),
]);
}

同样,这些并不是最有用的例子 - 但如果您愿意,您可以做很多事情,从将属性转换为用于处理金钱的 Value Objects 到检查内容以查找垃圾邮件。

授权失败

通常,当您的表单请求授权失败时,框架会抛出一个AuthorizationException。对于 99% 的用例来说,这就是您所需要的。但是,在一些更模糊的情况下,您可能希望避免抛出这样的异常。假设您正在从第三方 API 捕获 Webhook,并且抛出 Authorization Exception 会在这个第三方中产生奇怪的、不可控的行为。相反,您可以通过在表单请求中覆盖此方法来静默失败。

protected function failedAuthorization(): void
{
Log::info('Failed authorization for webhook capture ....');
}

这些只是表单请求上可用的一些方法,更不用说使用 Laravel Precognition 可用的所有方法了。但正如我之前提到的,我们可以添加我们的方法 - 使我们能够更进一步地扩展表单请求的功能。一个完美的例子是 Laravel Breeze 源代码,其中在LoginRequest中添加了一个authenticate方法,以便可以进一步简化控制器代码。

让我们看一个我可能通常编写的控制器的示例

final class StoreController
{
public function __construct(
private readonly StoreCommand $command,
) {}
 
public function __invoke(StoreRequest $request): Responsable
{
try {
$this->command->handle(
instance: new Instance(
name: $request->string('name')->toString(),
),
);
} catch (Throwable $exception) {
throw new FailedToCreateInstance(
message: 'Failed to create a new instance.',
previous: $exception,
);
}
 
return new CreatedResponse();
}
}

这是一个简化的控制器,我在其中使用一个创意类来发送一个数据对象,以使我的代码保持一致并清理我喜欢的代码。我们可以通过依靠表单请求来进一步简化我们的代码。

final class StoreController
{
public function __construct(
private readonly StoreCommand $command,
) {}
 
public function __invoke(StoreRequest $request): Responsable
{
try {
$this->command->handle(
instance: $request->dto(),
);
} catch (Throwable $exception) {
throw new FailedToCreateInstance(
message: 'Failed to create a new instance.',
previous: $exception,
);
}
 
return new CreatedResponse();
}
}

这看起来很相似,但想象一下,我们正在构建一个复杂十倍的东西,有更多需要映射到数据对象的请求字段 - 我们的控制器很快就会变得又大又乱。我们在这里所做的只是将数据对象的创建移到表单请求上的一个方法中 - 根本没有什么技术性可言。

您可以在表单请求中做的事情的限制只受您的想象力限制,但请确保您明智地使用它们。请记住,它们不是用来代替您的应用程序逻辑的!确保您的应用程序逻辑始终可访问且可读,并且不会丢失在框架逻辑或请求验证的海洋中,这一点至关重要。

Steve McDougall photo

Laravel 新闻 的技术作家,Treblle 的开发者倡导者。API 专家,经验丰富的 PHP/Laravel 工程师。 YouTube 直播主

Cube

Laravel 新闻稿

加入 40,000 多名其他开发者,永远不要错过新的技巧、教程等等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动补全和对本地和生产环境的即时反馈进行调试。

Tinkerwell
No Compromises logo

无妥协

Joel 和 Aaron,来自 No Compromises 播客的两名经验丰富的开发者,现在可以为您的 Laravel 项目聘用。 ⬧ 每月 7500 美元的固定费用。 ⬧ 没有冗长的销售流程。 ⬧ 没有合同。 ⬧ 100% 退款保证。

无妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜。

Shift
Bacancy logo

Bacancy

只需每月 2500 美元,即可利用经验丰富的 Laravel 开发人员(拥有 4-6 年经验)为您的项目增光添彩。获得 160 小时的专业知识和 15 天的无风险试用。立即安排通话!

Bacancy
Lucky Media logo

Lucky Media

立即获得幸运 - Laravel 开发的理想选择,拥有超过十年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel 电子商务

Laravel 的电子商务。一个开源软件包,为 Laravel 带来了现代无头电子商务功能的力量。

Lunar: Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 职位板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动套件

SaaSykit 是一个 Laravel SaaS 启动套件,它包含运行现代 SaaS 所需的所有功能。支付、漂亮的结帐、管理面板、用户仪表板、身份验证、现成组件、统计信息、博客、文档等等。

SaaSykit:Laravel SaaS 启动套件
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,助力成功企业

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解灵活、现代的 MongoDB 数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入遮罩库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的站点搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为您的 Laravel 应用程序添加评论

阅读文章