鍍金池/ 問答/PHP/ Laravel 的表單驗(yàn)證 , 如何做到驗(yàn)證并改變 ( 轉(zhuǎn)換 ) 數(shù)據(jù) ?

Laravel 的表單驗(yàn)證 , 如何做到驗(yàn)證并改變 ( 轉(zhuǎn)換 ) 數(shù)據(jù) ?

$validator = Validator::make($request->all(), [
            // 如何在這里轉(zhuǎn)換數(shù)據(jù)
            'id' => 'required|integer'
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

需求是這樣的,比如 , id 傳來的是 5,雖然可以通過 Laravel 的 integer 驗(yàn)證 , 但是它其實(shí)是一個(gè) string 類型 ,導(dǎo)致我后面如果不強(qiáng)轉(zhuǎn)換為 int , 程序就會出錯(cuò) 。雖然我可以在后面自己強(qiáng)轉(zhuǎn)化 , 但覺得這樣寫不好, 我想在驗(yàn)證的同時(shí)就轉(zhuǎn)換數(shù)據(jù) 。
所以有什么辦法可以做到 在驗(yàn)證的同時(shí)并且轉(zhuǎn)換數(shù)據(jù) 嗎 ?謝謝大家了 。

回答
編輯回答
忘了我

我已用其他方法解決 。找了很久,想了很久,貌似不能直接在驗(yàn)證里面做轉(zhuǎn)化,但是我想到了一個(gè)更好的解決辦法,解決方法如下 :

Laravel 有中間件,我們通常在中間件中做一些過濾 HTTP 請求的操作,但是還能做很多“請求預(yù)處理”操作,如 Laravel 內(nèi)置的 TrimStrings 中間件 和 ConvertEmptyStringsToNull 中間件 ,這兩個(gè)中間件都會把請求來的參數(shù)做些預(yù)處理操作,具體的使用請看源碼 。

所以 , 我的解決方法就是創(chuàng)建一個(gè) ConvertNumericStringsToInt 中間件 :

class ConvertNumericStringsToInt extends TransformsRequest
{
    /**
     * The attributes that should not be trimmed.
     *
     * @var array
     */
    protected $except = [
        //
    ];

    /**
     * Transform the given value.
     *
     * @param  string $key
     * @param  mixed $value
     * @return mixed
     */
    protected function transform($key, $value)
    {

        $transform = false;
        if ($key === 'id') {

            // 參數(shù)為 id
            $transform = true;
        } else if (1 === preg_match('/^[a-zA-Z][0-9a-zA-Z]*_id$/', $key)) {

            // 參數(shù)為 *_id
            $transform = true;
        } else if (1 === preg_match('/^[a-zA-Z][0-9a-zA-Z]*Id$/', $key)) {

            // 參數(shù)為 *Id
            $transform = true;
        }

        if ($transform) {

            if (!is_numeric($value)) {

                // 做你自己想做的處理( 如拋出異常 )
            }

            return is_numeric($value) ? intval($value) : $value;
        }

        // 返回原值
        return $value;
    }
}

這樣,只要我們的傳來的參數(shù)是 id , 或者 _id( user_id ),或者 Id( 如userId ),這個(gè)中間件都能檢測,一旦發(fā)現(xiàn)不是數(shù)字 , 就會被處理( 如拋出異常 ),如果是數(shù)字的話,會被強(qiáng)轉(zhuǎn)為int類型,我們之后的程序中就不用做任何處理了。

根據(jù)自己的使用情況決定是否將此中間件應(yīng)用都全局中 。

2017年10月25日 02:42
編輯回答
舊城人

有辦法,在Laravel 5.6中,有一個(gè)驗(yàn)證結(jié)束的鉤子函數(shù)(after),當(dāng)驗(yàn)證完成后會自動調(diào)用這個(gè)鉤子函數(shù):

$validator = Validator::make(...);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}

官方文檔鏈接:https://laravel.com/docs/5.6/...

還有一個(gè)方法(暫時(shí)想到的,沒具體試過),你可以在id的驗(yàn)證規(guī)則中加一個(gè)numeric的驗(yàn)證規(guī)則:

...
'id' => 'required|integer|numeric',
...
2017年11月11日 07:14