使用 Dingo\API 中的 FormRequest 时,422 错误提示的 message 自定义,以及提示汉化。
使用
FormRequest
,会让Controller
看起来更为整洁。因为项目需求,我们项目中使用的是Dingo\Api\Http\FormRequest
。本文主要解决的是,在该种情况下 422 错误提示的汉化以及message 的自定义。
这只是我个人的解决办法,如有好的解决方法可以指出,但不要喷我,会受不了鸟~~
一、问题状况阐述
原始代码如下:
<?php
namespace App\Http\Requests;
use Dingo\Api\Http\FormRequest;
class PostRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
switch ($this->method()) {
case 'PUT':
return [
'title' => 'required'
];
case 'POST':
return [
'title' => 'required'
];
default:
return [];
}
}
}
默认错误提示如下:
{
"message": "422 Unprocessable Entity.",
"status_code": 422,
"errors": {
"title": [
"The title field is required."
]
}
}
需要优化点:
1、提示为中文提示
2、422错误时,message 默认为errors 中的第一条
期望出现的提示如下:
{
"message": "必须指定:标题",
"status_code": 422,
"errors": {
"title": [
"必须指定:标题"
]
}
}
二、解决问题
第一步:首先将项目中的语言汉化(若已汉化,请跳过次步骤)
1、 在 resources/lang
下目录下,建立一个与 en
对应的文件夹 zh
在zh
文件夹下新建如下四个文件:
auth.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => '当前凭证与我们的记录不相符',
'throttle' => '登录操作太频繁,请等待 :seconds 秒后重试。',
];
pagination.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '« 上一页',
'next' => '下一页 »',
];
passwords.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
'password' => '密码必须最少为 6 个字符并与确认密码相同。',
'reset' => '您的密码已重置!',
'sent' => '我们已将密码重置链接发送到您的邮箱!',
'token' => '重置密码的令牌无效。',
'user' => "未找到使用此邮箱的用户。",
];
validation.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => ':attribute 必须为已接受',
'active_url' => ':attribute 不是有效的 URL',
'after' => ':attribute 必须大于 :date',
'after_or_equal' => ':attribute 必须大于或等于 :date',
'alpha' => ':attribute 可接受类型:字母',
'alpha_dash' => ':attribute 可接受类型:字母、数字、短划线和下划线',
'alpha_num' => ':attribute 可接受类型:字母、数字',
'array' => ':attribute 可接受类型:数组',
'before' => ':attribute 必须小于 :date',
'before_or_equal' => ':attribute 必须小于或等于 :date',
'between' => [
'numeric' => ':attribute 必须介于 [:min - :max] 之间',
'file' => ':attribute 最小::min KB,最大::max KB',
'string' => ':attribute 最少::min 个字符,最多::max 个字符',
'array' => ':attribute 最少::min 项,最多::max 项',
],
'boolean' => ':attribute 可接受类型:是 或 否',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => ':attribute 不是有效的日期',
'date_format' => ':attribute 格式错误,格式::format.',
'different' => ':attribute 不能等于 :other',
'digits' => ':attribute 必须是 :digits 位数',
'digits_between' => ':attribute 最少 :min 位数,最多::max 位数',
'dimensions' => ':attribute 图片尺寸不匹配',
'distinct' => ':attribute 已存在相同的选项',
'email' => ':attribute 不是有效的邮箱地址',
'exists' => '不存在的选项::attribute',
'file' => ':attribute 必须是一个有效的文件',
'filled' => ':attribute 必须填写',
'gt' => [
'numeric' => ':attribute 必须大于 :value.',
'file' => ':attribute 必须大于 :value KB',
'string' => ':attribute 必须大于 :value 个字符',
'array' => ':attribute 必须大于 :value 项',
],
'gte' => [
'numeric' => ':attribute 必须大于或等于 :value',
'file' => ':attribute 必须大于或等于 :value KB',
'string' => ':attribute 必须大于或等于 :value 个字符',
'array' => ':attribute 必须大于或等于 :value 项',
],
'image' => ':attribute 必须是一个图像',
'in' => ':attribute 不是一个有效的值',
'in_array' => ':other 不包含 :attribute',
'integer' => ':attribute 必须是整数',
'ip' => ':attribute 无效的 IP 地址',
'ipv4' => ':attribute 无效的 IPv4 地址',
'ipv6' => ':attribute 无效的 IPv6 地址',
'json' => ':attribute 无效的 JSON 字符串',
'lt' => [
'numeric' => ':attribute 必须小于 :value.',
'file' => ':attribute 必须小于 :value KB',
'string' => ':attribute 必须小于 :value 个字符',
'array' => ':attribute 必须小于 :value 项',
],
'lte' => [
'numeric' => ':attribute 必须小于或等于 :value',
'file' => ':attribute 必须小于或等于 :value KB',
'string' => ':attribute 必须小于或等于 :value 个字符',
'array' => ':attribute 必须小于或等于 :value 项',
],
'max' => [
'numeric' => ':attribute 不能大于 :max',
'file' => ':attribute 不能大于 :max KB',
'string' => ':attribute 不能大于 :max 个字符',
'array' => ':attribute 不能多于 :max 项',
],
'mimes' => ':attribute 的文件类型必须是: :values.',
'mimetypes' => ':attribute 的文件类型必须是: :values.',
'min' => [
'numeric' => ':attribute 最小值::min.',
'file' => ':attribute 不能小于 :min KB',
'string' => ':attribute 最少 :min 个字符',
'array' => ':attribute 最少包含 :min 项',
],
'not_in' => '当前选项 :attribute 无效',
'not_regex' => ':attribute 格式错误',
'numeric' => ':attribute 必须是数值',
'present' => ':attribute 必须存在',
'regex' => ':attribute 格式错误',
'required' => '必须指定::attribute',
'required_if' => '当 :other 等于 :value 时,必须指定::attribute',
'required_unless' => '除非 :values 包含 :other,否则必须指定::attribute',
'required_with' => '当 :values 存在时,必须指定::attribute',
'required_with_all' => '当 :values 存在时,必须指定::attribute',
'required_without' => '当 :values 不存在时,必须指定::attribute',
'required_without_all' => '当 :values 未指定时,必须指定::attribute',
'same' => ':attribute 必须与 :other 相匹配',
'size' => [
'numeric' => ':attribute 必须是 :size',
'file' => ':attribute 必须是 :size KB',
'string' => ':attribute 必须是 :size 个字符',
'array' => ':attribute 必须是 :size 项',
],
'string' => ':attribute 必须是字符串',
'timezone' => ':attribute 必须是有效的时区',
'unique' => ':attribute 不能与已存在的项相同',
'uploaded' => ':attribute 上传失败',
'url' => ':attribute 格式错误',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => [],
];
2 、指定默认语言为中文
修改 config/app.php
文件 中的 locale
值
'locale' => 'zh',
第二步:指定 request 文件中对应的属性中文名
修改对应的 request
文件,添加attributes
方法。指定对应的属性中文名
<?php
namespace App\Http\Requests;
use Dingo\Api\Http\FormRequest;
class PostRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function attributes()
{
return [
'title' => "标题",
];
}
public function rules()
{
switch ($this->method()) {
case 'PUT':
return [
'title' => 'required'
];
case 'POST':
return [
'title' => 'required'
];
default:
return [];
}
}
}
此时、422 提示信息如下
{
"message": "422 Unprocessable Entity.",
"status_code": 422,
"errors": {
"title": [
"必须指定:标题"
]
}
}
第三步:修改 message 提示内容
重写 FormRequest
中的 failedValidation
方法即可
protected function failedValidation(Validator $validator)
{
if ($this->container['request'] instanceof \Illuminate\Http\Request) {
throw new ResourceException($validator->errors()->first(), $validator->errors());
}
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
由于 failedValidation
与 authorize
方法在所有的 request 中都一样,SO 我们提出一个基类出来。代码文件如下:
App\Http\Requests 中 Request 基类文件:
<?php
namespace App\Http\Requests;
use Dingo\Api\Exception\ResourceException;
use Illuminate\Contracts\Validation\Validator;
use Dingo\Api\Http\FormRequest;
use Illuminate\Validation\ValidationException;
class Request extends FormRequest
{
public function authorize()
{
return true;
}
protected function failedValidation(Validator $validator)
{
if ($this->container['request'] instanceof \Illuminate\Http\Request) {
throw new ResourceException($validator->errors()->first(), $validator->errors());
}
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
}
其他所有的 request 文件都继承该基类
<?php
namespace App\Http\Requests;
class PostRequest extends Request
{
public function attributes()
{
return [
'title' => "标题",
];
}
public function rules()
{
switch ($this->method()) {
case 'PUT':
return [
'title' => 'required'
];
case 'POST':
return [
'title' => 'required'
];
default:
return [];
}
}
}
最后出现的422提示格式
{
"message": "必须指定:标题",
"status_code": 422,
"errors": {
"title": [
"必须指定:标题"
]
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
https://github.com/overtrue/laravel-lang
这个包你可以看一下
谢谢,422提示的处理帮大忙了 :see_no_evil: