Laravel 的表單驗證 , 如何做到驗證並改變 ( 轉換 ) 資料 ?( 使用中介軟體 )

Lvsi-China發表於2018-04-05

在回答社群中,我提問了這個問題 :Laravel 的表單驗證 , 如何做到驗證並改變 ( 轉換 ) 資料 ?

最終,我找到了一種使用中介軟體的方法 ,這種方法比驗證的同時並轉換更好 。

注意 :所針對的是非路由引數 。

首先,先看看 Laravel 的 2 箇中介軟體 :TrimStringsConvertEmptyStringsToNull

use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;

// 此中介軟體繼承了 TrimStrings 中介軟體基類
class TrimStrings extends Middleware
{
    protected $except = [
        'password',
        'password_confirmation',
    ];
}

// 找到 TrimStrings 中介軟體基類
namespace Illuminate\Foundation\Http\Middleware;

class TrimStrings extends TransformsRequest
{
    protected $except = [
        //
    ];

    // 重要方法
    protected function transform($key, $value)
    {
        if (in_array($key, $this->except, true)) {
            return $value;
        }
        // 這裡已經寫的很清楚了
        return is_string($value) ? trim($value) : $value;
    }
}

ConvertEmptyStringsToNull 中介軟體同理,就不上程式碼了 。

我們完全可以模仿這個中介軟體的寫法,構造我們自己的中介軟體,去做一些引數的 “ 預轉換 ” ,下面上程式碼 :

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') {

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

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

            // 引數為 *Id
            $transform = true;
        }

        if ($transform) {

            if (!is_numeric($value)) {

                // 我自己做的處理,會直接丟擲異常,不會再向下進行
                return responseJsonOfFailure([], 4444, $key . '引數必須是整數');
            }

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

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

我在這個中介軟體中處理所有名稱中有 id 的引數 ,如果引數符合並且不是數字就丟擲異常 ,如果引數符合並且是數字( 此時還是字串 ) 就強轉為 int 型別 ,之後程式中就不用做任何強轉了。

同理很多情況下,我們如果想對引數做任何的預處理,都可以使用這種方法 ,我們可以根據實際情況,決定如何設定這些 “ 引數預轉換中介軟體 ” 的作用域範圍 。

相關文章