使用
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 協議》,轉載必須註明作者和本文連結