iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
佛心分享-IT 人自學之術

後端小白自學 Laravel系列 第 9

第 9 天:表單處理與請求

  • 分享至 

  • xImage
  •  

在 Laravel 中,處理表單數據涉及創建表單、驗證表單數據,以及顯示驗證錯誤。

文件:表单验证

創建表單


在 Laravel 中,可以使用 Blade 模板來創建表單,以下是如何創建一個簡單的表單,該表單允許用戶提交姓名和電子郵件。

<!-- resources/views/contact.blade.php -->

<!DOCTYPE html>
<html>
<head>
    <title>Contact Form</title>
</head>
<body>

<h1>Contact Us</h1>

<!-- 顯示表單 -->
<form action="{{ route('contact.submit') }}" method="POST">
    @csrf
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" value="{{ old('name') }}">
    @error('name')
        <div style="color: red;">{{ $message }}</div>
    @enderror
    <br><br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" value="{{ old('email') }}">
    @error('email')
        <div style="color: red;">{{ $message }}</div>
    @enderror
    <br><br>
    <button type="submit">Submit</button>
</form>

</body>
</html>

🐘 補充說明:
@csrf 用於生成一個 CSRF 保護令牌,防止跨站請求偽造。
@error('field_name') 用於顯示特定字段的驗證錯誤消息。

表單數據的驗證(使用 Request 類和 Form Request)


參考資料:[Laravel]表單驗證與返回

使用 Request 類進行驗證

  • Step 1 - 創建 Request 類

    • 下指令 php artisan make:request ContactRequest
  • Step 2 - 在 ContactRequest 類中進行驗證

    // app/Http/Requests/ContactRequest.php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class ContactRequest extends FormRequest
    {
        public function authorize()
        {
            return true; // 允許所有用戶進行請求
        }
    
        public function rules()
        {
            return [
                'name' => ['required', 'max:255'],
                'email' => ['required', 'email']
            ];
        }
    }
    
  • Step 3 - 在控制器中使用 Request 類進行驗證

    // app/Http/Controllers/ContactController.php
    
    namespace App\Http\Controllers;
    
    use App\Http\Requests\ContactRequest;
    use Illuminate\Http\Request;
    
    class ContactController extends Controller
    {
        public function showForm()
        {
            return view('contact');
        }
    
        public function submitForm(ContactRequest $request)
        {
            // 表單數據驗證通過後
            $validated = $request->validated();
    
            // 處理表單數據
            return redirect()->back()->with('success', 'Form submitted successfully!');
        }
    }
    
  • Step 4 - 在路由中定義表單顯示和提交的路由

    // routes/web.php
    
    use App\Http\Controllers\ContactController;
    
    Route::get('contact', [ContactController::class, 'showForm'])->name('contact.show');
    Route::post('contact', [ContactController::class, 'submitForm'])->name('contact.submit');
    

使用 Form Request 進行驗證
如果希望進行更複雜的驗證或使用多個驗證規則,Form Request 是一個很好的選擇,它提供了更高級的驗證功能和更清晰的代碼結構。
如果錯誤驗證出現,當發生異常時,Laravel 會調用這個異常處理器中 app/Exceptions/Handler.phprender 方法來處理異常並生成相應的響應。
異常處理器

獨立驗證(Validator::make())


跟上面範例的 controller 邏輯是一樣的,只是現在改成套件的驗證器,用獨立驗證的方式進行。

       public function submitForm(Request $request)
       {
           // 表單數據驗證通過後
           $validated = Validatir::make($request->all(), [
               
               // 欄位名稱 => 規則名稱
               'name'     => ['required', 'max:255'],
               'email'    => ['required', 'email']
           ], [
               // 欄位名稱.規則名稱  => 錯誤語句
               'name.required'    => '使用者名稱不能為空',
               'name.max'         => '使用者名稱最多 255 字元',
               'email.required'   => 'email不能為空',
               'email.email'      => '郵箱格式不正確'
           ]);
           
           // 處理表單數據
           return redirect()->back()->with('success', 'Form submitted successfully!');
       }

顯示驗證錯誤


在表單中,可以使用 Blade 的 @error 指令來顯示驗證錯誤。這些錯誤信息是從 Laravel 的驗證系統返回的,當表單數據不符合驗證規則時,這些錯誤信息將自動顯示在對應的字段下方。

表單視圖(resources/views/contact.blade.php)

<!DOCTYPE html>
<html>
<head>
    <title>Contact Form</title>
</head>
<body>

<h1>Contact Us</h1>

@if(session('success'))
    <div style="color: green;">{{ session('success') }}</div>
@endif

<form action="{{ route('contact.submit') }}" method="POST">
    @csrf
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" value="{{ old('name') }}">
    @error('name')
        <div style="color: red;">{{ $message }}</div>
    @enderror
    <br><br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" value="{{ old('email') }}">
    @error('email')
        <div style="color: red;">{{ $message }}</div>
    @enderror
    <br><br>
    <button type="submit">Submit</button>
</form>

</body>
</html>

ContactRequest 類(app/Http/Requests/ContactRequest.php)

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ContactRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|max:255',
            'email' => 'required|email',
        ];
    }
}

ContactController 類(app/Http/Controllers/ContactController.php)

namespace App\Http\Controllers;

use App\Http\Requests\ContactRequest;
use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function showForm()
    {
        return view('contact');
    }

    public function submitForm(ContactRequest $request)
    {
        $validated = $request->validated();
        return redirect()->back()->with('success', 'Form submitted successfully!');
    }
}

路由(routes/web.php)

use App\Http\Controllers\ContactController;

Route::get('contact', [ContactController::class, 'showForm'])->name('contact.show');
Route::post('contact', [ContactController::class, 'submitForm'])->name('contact.submit');

✍🏻 每日任務:


關於微博文章發佈需要的標題 title 和內容 content 建立表單驗證

step 1 - 設定路由
routes/web.php 檔案中定義一個路由,用於顯示表單和處理表單提交。

// 顯示表單
Route::get('/post/create', [PostController::class, 'create'])->name('post.create');

// 處理表單提交
Route::post('/post/store', [PostController::class, 'store'])->name('post.store');

step 2 - 建立控制器 & 處理表單驗證
下指令 php artisan make:controller PostController 創建一個控制器來處理表單的顯示和提交邏輯。

  • 定義 create 方法來顯示表單
  • 定義 store 方法來處理表單提交和驗證
    分別有 2 種方法可以進行表單驗證:
  1. 把表單驗證邏輯寫在 controller

    <?php
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use Illuminate\Contracts\View\View;
    use Illuminate\Http\RedirectResponse;
    use Illuminate\Support\Facades\Validator;
    
    class PostController extends Controller
    {
        /**
         * 顯示建立部落格文章的表單: 顯示表單
         * Show the form for creating a new resource.
         *
         * @return View
         */
        public function create(): View
        {
            return view('post.create');
        }
    
        /**
         * 儲存一篇新的部落格文章
         * Store a newly created resource in storage.
         *
         * @param Request $request
         * @return RedirectResponse
         */
        public function store(Request $request): RedirectResponse
        {
            // 定義驗證規則
            $rules = [
                'title'   => ['required', 'string', 'max:255'],
                'content' => ['required', 'string', 'min:10']
            ];
    
            // 自定義錯誤訊息(可選)
            $messages = [
                'title.required'   => '標題是必填的',
                'title.string'     => '標題必須是文字',
                'title.max'        => '標題不能超過255個字符',
                'content.required' => '內容是必填的',
                'content.string'   => '內容必須是文字',
                'content.min'      => '內容必須至少包含10個字符',
            ];
    
            // 使用 Validator 驗證器實例,自身有除錯功能可以自行定義錯誤處理
            $validator = Validator::make($request->all(), $rules, $messages);
    
            // 檢查驗證結果
           if ($validator->fails()) {
                return redirect()->route('post.create')
                    ->withErrors($validator)
                    ->withInput();
            }
    
            // 如果驗證通過,要先做建立模型和遷移文件創建表格,再儲存數據到表格中
            // $validatedData = $validator->validated();
            // $post = Post::create($validatedData);
    
            return redirect()->route('post.create')->with('success', '文章發佈成功!');
        }
    }
    
  2. 下指令 php artisan make:request StorePostRequest 創建手動創建表單請求驗證

    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Contracts\Validation\ValidationRule;
    use Illuminate\Foundation\Http\FormRequest;
    
    class StorePostRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         * 確定目前經過身份驗證的使用者是否可以執行請求操作
         * by default it is set to false
         * 預設為 false
         *
         * @return bool
         */
        public function authorize(): bool
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         * 取得應用於該請求的驗證規則: 定義驗證規則
         *
         * @return array<string, ValidationRule|array|string>
         */
        public function rules(): array
        {
            // required -> 必填;nullable -> 選填,所有項目驗證由左到右依序執行,錯誤就會中斷
            return [
                'title'   => ['required', 'string', 'max:255'],
                'content' => ['required', 'string', 'min:10']
            ];
        }
    
        /**
         * Get custom messages for validator errors.
         * 取得已定義驗證規則的錯誤訊息: 自定義錯誤訊息
         *
         * @return array
         */
        public function messages(): array
        {
            return [
                'title.required'   => '標題是必填的',
                'title.string'     => '標題必須是文字',
                'title.max'        => '標題不能超過255個字符',
                'content.required' => '內容是必填的',
                'content.string'   => '內容必須是文字',
                'content.min'      => '內容必須至少包含10個字符'
            ];
        }
    }
    

    之後在控制器中引入

    <?php
    namespace App\Http\Controllers;
    
    use App\Http\Requests\StorePostRequest;
    use Illuminate\Contracts\View\View;
    use Illuminate\Http\RedirectResponse;
    
    class PostController extends Controller
    {
        /**
         * 顯示建立部落格文章的表單: 顯示表單
         * Show the form for creating a new resource.
         *
         * @return View
         */
        public function create(): View
        {
            return view('post.create');
        }
    
        /**
         * 儲存一篇新的部落格文章
         * Store a newly created resource in storage.
         *
         * @param StorePostRequest $request
         * @return RedirectResponse
         */
        public function store(StorePostRequest $request): RedirectResponse
        {
            // 驗證已經在 StorePostRequest 類別中進行處理,所以要改用 ->validated() 會返回經過驗證的數據
            $validatedData = $request->validated();
    
            // 如果驗證通過,儲存數據到表格中
            // $post = Post::create($validatedData);
    
            return redirect()->route('post.create')->with('success', '文章發佈成功!');
        }
    }
    

step 3 - 創建視圖
resources/views 資料夾下,創建一個新的視圖檔案 post/create.blade.php,用於顯示表單。

<!DOCTYPE html>
<html>
<head>
    <title>發佈文章</title>
</head>
<body>
<div class="container">
    <h1 class="fs-4 my-3">發佈文章</h1>

    @if (session('success'))
        <p class="alert alert-success">{{ session('success') }}</p>
    @endif

    <form action="{{ route('post.store') }}" method="POST">
        @csrf
        <div>
            <label for="title" class="form-label">標題:</label>
            <input type="text" class="form-control" id="title" name="title" value="{{ old('title') }}">
            @error('title')
            <div class="text-danger">{{ $message }}</div>
            @enderror
        </div>
        <div>
            <label for="content" class="form-label">內容:</label>
            <textarea id="content" class="form-control" name="content">{{ old('content') }}</textarea>
            @error('content')
            <div class="text-danger">{{ $message }}</div>
            @enderror
        </div>
        <button type="submit" class="btn btn-outline-primary btn-sm mt-3">發佈</button>
    </form>
</div>
</body>
</html>

step 4 - 測試功能
下指令 php artisan serve 啟動伺服器,並前往 /post/create 路由以查看表單。
畫面
提交表單後,Laravel 將會根據你設置的驗證規則來檢查輸入內容,如果有錯誤,將會顯示錯誤訊息。
成功畫面
錯誤畫面


上一篇
第 8 天:集合 - 高級操作
下一篇
第 10 天:文件上傳與存儲
系列文
後端小白自學 Laravel30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言