# laravel validator 驗證相關 https://hackmd.io/@javck/ByJgF8HRP/%2FO6PetMaXQr-BNdhBbvzZfQ 詳細 https://medium.com/learn-or-die/laravel-the-basics-validation-%E5%AE%98%E6%96%B9%E6%96%87%E4%BB%B6%E5%8E%9F%E5%AD%90%E5%8C%96%E7%BF%BB%E8%AD%AF%E7%AD%86%E8%A8%98-6540bbb190db whereIn 在array https://stackoverflow.com/questions/42662579/validate-an-array-of-integers ## 布林轉換 https://echebaby.com/blog/2021-12-30-laravel-validate-true-and-false-as-booleans/ ## request 的驗證 ![](https://i.imgur.com/LbH42gC.png) 這跟 $request->validated不一樣 一個叫做驗證器 validator 所以是顯示origin data 一個是驗證完成有ed ## 底層 建立 ![](https://i.imgur.com/dbCE6wF.png) 如果沒有validate 建立 ![](https://i.imgur.com/U4iBl06.png) 這邊就基本的手動建立 第一參數是要驗證資料 第二是驗證方法 第三是錯誤訊息 第四是驗證對應的名稱 ![](https://i.imgur.com/Wm2wPRy.png) ![](https://i.imgur.com/JNh2n8m.png) request類可以直接用 ->route() 對應的參數 如果你有隱綁定會直接幫你去做where ## 直接獲取model ![](https://i.imgur.com/vpWL1I5.png) ## 密碼至少一個 大寫 小寫 字母 https://www.youtube.com/watch?v=f-g3P9imPZs ![](https://i.imgur.com/WMejUfn.png) ## 數字長度 https://stackoverflow.com/questions/39539436/validating-a-numeric-inputs-length-in-laravel-5/39539840 digits規則還驗證給定值是否為數字。 ## 小數點 或數字大小驗證 小心長度是string 要先驗證數字 https://stackoverflow.com/questions/29734046/laravel-validate-decimal-0-99-99 ## 軟刪除驗證 軟刪除驗證會有問題 他不會管你有沒有軟刪除欄位 8.65新增方法 ![](https://i.imgur.com/tk7YkHU.png) 如果 軟刪除欄位不叫delete_at 括號內能自訂 8.65之前用 whereNotNull(delete_at) ## 郵政 密碼強度驗證 法定年齡 這種比較難的介紹 https://dev.to/lukapg/3-custom-laravel-validation-rules-to-reuse-and-make-your-code-cleaner-mf5 ## 自訂規則 https://www.youtube.com/watch?v=K-uvIn-4Ug0 ## present 欄位要出來 但可以不填 ## prepareForValidation https://laravelexamples.com/example/melcus-parking-system/custom-validation-rules 第一種 開始結束時間 他會把他合起來判斷 有沒有符合 或Slug那種換算 ``` <?php use Illuminate\Support\Str; protected function prepareForValidation() { $this->merge([ 'slug' => Str::slug($this->slug), ]); } ``` Answer: Form request 中的 prepareForValidation 可以讓 Request 在 validate 之前先被處理過, 如上 example, 將 slug input 的 value 跑過 Str::slug(), 假如 input value 為 ‘a b c d’, 到了 validation 那則會變成 ‘a-b-c-d’ https://castion2293.medium.com/laravel-request%E7%9A%84%E5%BB%B6%E4%BC%B8%E5%8A%9F%E8%83%BD-77ee6eb9d7d7 可以在validate規則前,做input value的修改,或建立指定的新欄位 ``` public function prepareForValidation() { $this->merge([ 'raw_withdraw' => strip_tags($this->withdraw), 'raw_bankbook' => strip_tags($this->bankbook), 'raw_deposit' => strip_tags($this->deposit), 'raw_rule' => strip_tags($this->rule), 'raw_service' => strip_tags($this->service), ]); } ``` ## 當有才驗證 現在只能sometime 加上nullable 但 8.5之後有Rule:when https://www.youtube.com/watch?v=j8HmPsord9s ## 可以寫一個 自訂分頁會用到的底層 向公司 一樣你要設定頁數 request就一樣要驗證 還沒試過不用驗證 但可能比較嚴謹 ``` class BaseRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; } /** * Get the validation rules that apply to the request. */ public function rules(): array { return $this->paginateRules(); } protected function paginateRules(): array { return [ 'page' => 'nullable|integer', 'per_page' => 'nullable|integer', ]; } } ``` ## request 的validator不能看 這是驗證規則的感覺 跟你$request->vaildated的不一樣(這是結果)($request的比較像是你傳去驗證的) ## update user驗證唯一值 強制唯一規則忽略給定 ID: 有時,您可能希望在唯一驗證期間忽略給定的 ID。例如,考慮包含用戶姓名、電子郵件地址和位置的“更新配置文件”屏幕。您可能想要驗證電子郵件地址是否唯一。但是,如果用戶只更改姓名字段而不是電子郵件字段,您不希望拋出驗證錯誤,因為用戶已經是相關電子郵件地址的所有者。 為了指示驗證器忽略用戶 ID,我們將使用Rule該類來流暢地定義規則。在這個例子中,我們還將驗證規則指定為一個數組,而不是使用|字符來分隔規則: ``` use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; Validator::make($data, [ 'email' => [ 'required', Rule::unique('users')->ignore($user->id), ], ]); ``` ## 8.5新功能 如果用軟刪除 帳號又唯一的話 看這影片就懂了 https://www.youtube.com/watch?v=kc8Ks3ElGmM ## store 跟 update一樣 https://www.youtube.com/watch?v=YK8GZmuf8_0 可以跟公司一樣用繼陳的 然後有不一樣在用routeIs去判斷 ![](https://i.imgur.com/elPl07G.png) 去判斷是不是sometime 跟 reqeuire 對於像email這樣唯一的話 unique有一個ignore可以忽略 ![](https://i.imgur.com/XE2E9CR.png) ## request驗證 **驗證不用重複寫 相關的能用繼承的方法減少重複性** ``` public function rules(): array { return parent::rules() + [ 'title' => 'sometimes|nullable|string', 'category_id' => 'sometimes|nullable|exists:f_a_q_categories,id', ]; } ``` ## max 跟 min 遇到interger https://learnku.com/laravel/t/2695/laravel-form-validation-request-in-max-min 如果要數字又要長度 就前端改number就好 後端驗證長度 ## Validator 中文叫驗證器 用在make ``` $validator = Validator::make( ['name' => 'Dayle'], ['name' => ['required', 'min:5']] ); ``` ## Validate 證實(當作驗證) 來原在底層的controller 控制器驗證 ``` $request->validate([ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]); ``` ## request 驗證 Validated 如果要取得驗證過後的 記得要加上d 驗證過後跟 all()的差別 ![](https://i.imgur.com/V6X3K6P.png) ## X-CSRF-Token 除了檢查 POST 參數中的 CSRF 口令之外, VerifyCsrfToken 中介層還會檢查 X-CSRF-TOKEN Header。你應該將口令保存在 HTML meta 標籤當中,如下例: `<meta name="csrf-token" content="{{ csrf_token() }}">` 接著一旦你創建了 meta 標籤,就可以指示像 jQuery 這樣的函式庫自動將口令添加到所有請求的Header當中。這為基於 AJAX 的應用提供簡單,方便的 CSRF 保護。如下: ``` $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); ``` ## X-XSRF-Token Laravel 將當前的 CSRF 口令保存在一個 XSRF-TOKEN cookie 中,該 cookie 包含在框架生成的每個回應當中。你可以使用 cookie 值來設置 X-XSRF-TOKEN Header 這個 cookie 主要是作為一種方便使用者的方式發送的,因為一些 JavaScript 框架和函式庫,例如 Angular 和 Axios ,會自動將它的值放入 X-XSRF-TOKEN Header 裡頭 技巧:預設情況下,resources/js/bootstrap.js 文件包含的 Axios HTTP 函式庫,會自動為你發送 CSRF 口令 Header。 ## 驗證規則補充 https://www.youtube.com/watch?v=ckhllNh79gM ###### $request->query 您可以query不帶任何參數地調用該方法,以便以關聯數組的形式檢索所有查詢字符串值: `$query = $request->query();` ###### 透過動態屬性來取得輸入 你也可以在 Illuminate\Http\Request 實例上使用動態屬性來存取使用者輸入。例如,如果一個應用程式表單有一個 name 輸入欄位,你可以像這樣存取該欄位的值: `$name = $request->name;` ###### 檢索JSON輸入值 將JSON請求發送到您的應用程序時,input只要Content-Type將請求的標頭正確設置為,您就可以通過方法訪問JSON數據application/json。您甚至可以使用“點”語法來挖掘JSON數組: `$name = $request->input('user.name');` ## 容易用到冷門的驗證規則 **sometimes** 有使用到在驗證 **exists** 去資料庫驗證 ex exists:f_a_q_categories,id 去f_a_q_categories驗證id ## 圖像驗證 驗證上傳的圖像時,您可以指定所需的尺寸 `['photo' => 'dimensions:max_width=4096,max_height=4096']` ## 使用“現在”或“昨天”字樣驗證日期 您可以通過之前/之後的規則驗證日期並將各種字符串作為參數傳遞,例如:`tomorrow`, `now`, `yesterday`。例子:`'start_date' => 'after:now'`。它在幕後使用 `strtotime()` 。 ``` $ rules = [ 'start_date' => 'after:tomorrow' , 'end_date' => 'after:start_date' ]; ``` ## 驗證第一個停止 bail ``` $request->validate([ 'title' => 'bail|required|unique:posts|max:255', 'body' => 'required', ]); ``` ## 常用的驗證 驗正在不再array裡面 ``` 'name' => 'sometimes|nullable|string|max:255', 'prize_type' => 'sometimes|nullable|in:' . implode(',', array_keys(Task::PRIZE_TYPE)), ``` array裡面的有沒有在規定的數字內(whereIn) ``` 'status' => 'sometimes|nullable|array', 'status.*' => 'sometimes|nullable|in:' . implode(',', array_keys(Task::STATUS)), ``` ``` 有沒有在資料庫裏面 'select' => 'sometimes|exists:tasks,status', ``` 時間 ` 'activity_start' => 'required|date_format:Y-m-d H:i',` ###### tags: `Laravel`