iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0
Software Development

Laravel 隨筆學習札記系列 第 23

Day23 - 什麼時候該讓 Laravel Validation 出馬?

  • 分享至 

  • xImage
  •  

🚨 要如何防止使用者因填錯表單而讓你的應用程式崩潰?

如果有一位隱形的護衛,能在使用者提交資料之前,檢查每一個輸入,確保一切都正確無誤,那該有多好啊!這位無形的英雄就是 Laravel 的 Validation 系統!
今天,讓我們一起深入探討如何利用這位忠實的守護者,讓你的應用程式如同堡壘般堅固,隨時準備好迎接每一位使用者的到來!💪


Laravel Validation 是什麼神奇的東西啊?

Laravel 的 Validation 系統就像應用程式的超級英雄,負責檢查使用者輸入的資料,確保資料是正確的,防止垃圾資料攻擊。


Laravel Validation 很重要?

Laravel 的 Validation 機制對於保護應用程式至關重要。想像一下,如果使用者輸入了不正確或不安全的電子郵件和密碼,這不僅會影響使用者體驗,還可能導致安全問題,例如資料洩漏或攻擊。透過 Validation ,我們可以確保使用者提供的資料是有效和安全的,這樣能有效防止不合格的資料進入系統。

// 這段程式碼確保使用者提供的電子郵件地址是有效的,且密碼長度至少為 8 個字元。
$request->validate([
    'email' => 'required|email',
    'password' => 'required|min:8',
]);

什麼時候該召喚 Laravel Validation?

當需要接收使用者輸入時,例如註冊、登入或任何表單填寫,這時 Validation 就該登場,確保資料符合標準,避免應用混亂。

  • 表單提交:當使用者提交表單時,使用 Validation 可以確保資料的正確性和完整性。
  • API 請求:在處理 API 請求時,Validation 請求資料也非常重要,以確保資料的有效性。
  • 資料庫操作前的驗證:在將資料保存到資料庫之前,進行 Validation 以避免無效資料。

如何使用 Laravel Validation?

Validation 可以在 Laravel 的各個地方使用,確保資料在進入應用的每個環節都得到檢查。

Validation Quickstart

  • Defining the Routes 我們在 routes/web.php 文件中設定以下 Route:

    use App\Http\Controllers\PostController;
    
    // GET 將顯示創建文章的表單
    Route::get('/post/create', [PostController::class, 'create']);
    
    // POST 將把新文章存儲到資料庫中
    Route::post('/post', [PostController::class, 'store']);
    
  • Creating the Controller 處理對這些 Route 的傳入請求,先不填寫 store 方法邏輯:

    class PostController extends Controller
    {
        public function create(): View
        {
            return view('post.create');
        }
    
        public function store(Request $request): RedirectResponse
        {
            // 包含對請求資料的驗證和將新的文章儲存到資料庫的邏輯。
        }
    }
    
  • Writing the Validation Logic 現在我們要在 store 方法中填入驗證邏輯。

    使用 Illuminate\Http\Request 物件提供的 validate 方法。如果驗證通過,程式將正常執行;若失敗,將自動返回錯誤 response。

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);
    
        return redirect('/posts');
    }
    
  • Displaying the Validation Errors 如果驗證失敗,使用者將被 redirect 回之前的頁面,並且所有錯誤訊息和請求資料會自動存入 session 中。$errors 變數將在所有 view 中可用,方便顯示錯誤訊息。

    <!-- /resources/views/post/create.blade.php -->
    
    <h1>Create Post</h1>
    
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
    
    <!-- Create Post Form -->
    
  • Customizing the Error Messages Laravel 的內置驗證規則有預設的錯誤消息,存放在 lang/en/validation.php 文件中。可以根據需要修改這些消息。


Form Request Validation

  • Creating Form Requests 當驗證情況較為複雜時,可以創建一個「表單請求」。這是一種自定義的請求類,包含自己的驗證和授權邏輯。可以使用以下  make:request 命令創建,每個表單請求會生成 authorizerules 兩個方法:

    php artisan make:request StorePostRequest
    

    這將在 app/Http/Requests 目錄下生成表單請求類。如果目錄不存在,系統會自動創建。每個表單請求都有兩個方法:authorizerules

    • authorize 方法用來檢查當前用戶是否有權執行該請求。
    • rules 方法返回應用於請求資料的驗證規則:
    public function rules(): array
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ];
    }
    

    在控制器中使用表單請求只需將請求類作為參數類型提示。這樣,請求會在使用控制器方法之前自動進行驗證,減少了控制器中的驗證邏輯:

    public function store(StorePostRequest $request): RedirectResponse
    {
        $validated = $request->validated();
        // 儲存文章...
        return redirect('/posts');
    }
    

    如果驗證失敗,會自動重定向用戶回到之前的位置,並顯示錯誤消息。如果是 XHR 請求,則會返回包含錯誤的 JSON 響應。

  • Performing Additional Validation 在初始驗證完成後,可以使用 after 方法執行額外的驗證。這個方法返回一個陣列,用於添加進一步的錯誤消息:

    public function after(): array
    {
        return [
            function (Validator $validator) {
                if ($this->somethingElseIsInvalid()) {
                    $validator->errors()->add('field', 'Something is wrong with this field!');
                }
            }
        ];
    }
    
  • Stopping on the First Validation Failure 可以在請求類中設置 stopOnFirstFailure 屬性,讓驗證在首次失敗時停止:

    protected $stopOnFirstFailure = true;
    
  • Customizing the Redirect Location 當驗證失敗時,可以自定義 redirect 的位置,通過設置 $redirect$redirectRoute 屬性來完成:

    protected $redirect = '/dashboard';
    // 或
    protected $redirectRoute = 'dashboard';
    

Authorizing Form Requests

authorize 方法中,可以檢查用戶是否有權更新特定資源。例如:

  • 如果 authorize 返回 false,則會自動返回 403 狀態碼的 response,控制器方法不會執行。
public function authorize(): bool
{
    $comment = Comment::find($this->route('comment'));
    return $comment && $this->user()->can('update', $comment);
}

Customizing the Error Messages

可以通過覆蓋 messages 方法自定義錯誤消息:

public function messages(): array
{
    return [
        'title.required' => 'A title is required',
        'body.required' => 'A message is required',
    ];
}
  • Customizing the Validation Attributes 若要自定義驗證消息中的屬性名稱,可以覆蓋 attributes 方法:

    public function attributes(): array
    {
        return [
            'email' => 'email address',
        ];
    }
    
  • Preparing Input for Validation 在應用驗證規則之前,如果需要準備或清理請求中的數據,可以使用 prepareForValidation 方法:

    protected function prepareForValidation(): void
    {
        $this->merge(['slug' => Str::slug($this->slug)]);
    }
    

    同樣,如果需要在驗證完成後規範化請求數據,可以使用 passedValidation 方法:

    這樣的設計讓表單請求的驗證更加簡潔和強大,能有效管理複雜的驗證邏輯。

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

使用時要小心什麼?

  • 驗證規則:Laravel 提供了許多內建的驗證規則,比如 required(必填)、email(電子郵件格式)、min(最小長度)等等。可以根據需求選擇適合的規則。
  • 自訂錯誤訊息:如果想讓使用者看到更友好的錯誤提示,可以自訂錯誤訊息。在驗證時,可以用 messages 方法來指定。
  • 使用表單請求:可以使用表單請求類別來集中管理驗證邏輯,這樣可以讓控制器更乾淨,並且重複使用驗證規則。
  • 驗證時機:Laravel 在儲存資料時會自動執行驗證。如果資料不符合規則,會自動將使用者導回原頁面並顯示錯誤訊息。
  • 自訂驗證規則:如果內建的規則不夠用,你可以自訂驗證規則,這樣可以針對特定的需求進行驗證。
  • 驗證陣列:對於多個資料項目(比如多個圖片上傳),可以使用陣列的方式來進行驗證,像是 images.*.required
  • 安全性考量:驗證可以防止不合法的資料進入你的應用,減少潛在的安全風險。

參考資料

  1. How to Create and Apply Validation Rules in Laravel
  2. Laravel Validator 介紹與用法
  3. Laravel官方網站:HTTP Validation

踏著身心靈的塔羅腳步,轉向技術與邏輯的工程師之路,就藉由塔羅日抽來紀錄今日的學習與生活吧!

寶劍二:哈!寫完這篇眼睛滿酸的,可能是在跟我說眼睛需要休息溜:)

“Life is full of possibilities. You just need to know where to look. Don't miss out on the joys of life.”

生命充滿了無限可能,你必須用心體會,別錯過生命的

  • 靈魂急轉彎

上一篇
Day22 - HTTP Session 跟 Cookie ?
下一篇
Day24 - 掌握 Laravel 11 Artisan:開發者的最佳夥伴!
系列文
Laravel 隨筆學習札記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言