SlideShare a Scribd company logo
1 of 37
Download to read offline
驗證與訊息
范聖佑 Shengyou Fan
新北市樹林國⼩小 (2015/07/11)
適
⽤用
5.1
版
單元主題
• 資料驗證對網路應⽤用程式的重要性
• 在 Laravel 裡如何實作資料驗證?有哪些⽅方式可供我
們選擇使⽤用?
• 如何透過跳轉處理資料驗證失敗時的動作?以及如
何在⾴頁⾯面上顯⽰示錯誤訊息提供使⽤用者回饋機制?
• ⽰示範如何在專案內實作驗證及跳轉功能
資料驗證
★ 參考⽂文件:http://laravel.com/docs/5.1/validation
千萬別相信任何⼈人!
• 撰寫 PHP 程式來接受輸⼊入並將結果輸出是很容易的,
但卻無法保證所有來源輸⼊入的資料都是安全的
• 常常聽到有網站被惡意攻擊或是不⼩小⼼心將個資洩漏就
是因為沒有做好安全性防護機制
• 因此,為了確保應⽤用程式運作正常且安全,就是絕對
不要相信任何從使⽤用者端取得的資料!
• 網路應⽤用程式安全的三⼤大守則:
- 對輸⼊入消毒
- 驗證資料
- 跳脫輸出內容
為什麼需要驗證資料?
• 由於無法確保使⽤用者送來的資料⼀一定是正確且符合
格式的,甚⾄至無法確定送資料來的使⽤用者都是善良
的使⽤用者
• 驗證的重點在於確認輸⼊入的資料是符合預期,並確
保最終儲存的資料是精確且格式正確的
• 假如接收到的資料是無法通過驗證的,就可以暫停
原訂的動作並將錯誤訊息顯⽰示給使⽤用者
傳統的驗證⽅方式
• 條件組合⼤大法:
- 檢查是不是空值 empty()、is_null()、isset()
- 檢查字串⻑⾧長度 strlen()、mb_strlen()、sizeof()
- 上網找「php email/name/phone validate regex」 然後⽤用
preg_match()、ereg()
//	
  檢查	
  username	
  是否為空值、⻑⾧長度超過	
  3	
  個字元且只有⼤大⼩小寫字⺟母	
  
if(!empty($_POST['username'])	
  &&	
  
	
  	
  	
  	
  strlen($_POST[‘username'])	
  >	
  3	
  &&	
  
	
  	
  	
  	
  preg_match("/^[a-­‐zA-­‐Z]*$/",	
  $_POST['username']))	
  
{	
  
	
   //	
  通過驗證!	
  
}
PHP 內建的驗證函式
• PHP 提供 filter_var() 驗證函式並搭配數個以
FILTER_VALIDATE_* 開頭的指標供我們做資料驗證
• 雖然 filter_var() 提供了數種驗證⽅方式,但它無
法驗證所有東⻄西
//	
  使⽤用	
  filter_var()	
  驗證	
  Email	
  
$email	
  =	
  $_POST['email'];	
  
$isEmail	
  =	
  filter_var($email,	
  FILTER_VALIDATE_EMAIL);	
  
if	
  ($isEmail	
  !==	
  false)	
  {	
  
	
  	
  	
  	
  /*	
  假如驗證通過則會回傳原本的變數內容	
  */	
  
	
  	
  	
  	
  /*	
  假如驗證錯誤則會回傳	
  false	
  */	
  
	
  	
  	
  	
  //	
  通過驗證!	
  
}
Laravel 的驗證機制
• Laravel 內建提供了三種⽅方式供我們驗證資料,可依
不同的需求選擇:
- Validator Facade
- ControllerValidation
- Form RequestValidation
表單驗證流程
驗證
查資料
成功回傳
組合⾴頁⾯面
控制邏輯
通過
輸⼊入資料
表單⾴頁⾯面
失敗返回
錯誤訊息
成功訊息
成功⾴頁⾯面
Validator Facade
• Laravel 內建提供Validator 類別,可直接透過 Facade
呼叫,就可以快速的實作驗證機制
//	
  使⽤用	
  Validator	
  Facade	
  進⾏行驗證	
  
$validator	
  =	
  Validator::make(	
  
	
  	
  	
  	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'username'	
  =>	
  'tester',	
  
	
  	
  	
  	
  	
  	
  	
  	
  'email'	
  =>	
  'tester@example.com'	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'username'	
  =>	
  'required|min:3|max:20',	
  
	
  	
  	
  	
  	
  	
  	
  	
  'email'	
  =>	
  'required|email|unique:users'	
  
	
  	
  	
  	
  ]	
  
);	
  
if	
  ($validator-­‐>fails())	
  
{	
  
	
  	
  	
  	
  //	
  沒有通過驗證,跳轉回前⼀一⾴頁,並把錯誤訊息帶過去	
  
return	
  redirect()-­‐>back()-­‐>withErrors($validator-­‐>errors());	
  
}
ControllerValidation
• Laravel 的 BaseController 已經幫我們加好
ValidatesRequests 的 Trait,只要直接使⽤用 validate ⽅方
法就可以進⾏行驗證
• 若驗證失敗,就會⾃自動跳轉回前⼀一⾴頁,並把錯誤訊
息帶過去,完全⾃自動化!
//	
  在	
  Controller	
  裡儲存資料時驗證資料	
  
public	
  function	
  store(Request	
  $request)	
  
{	
  
	
  	
  	
  	
  $this-­‐>validate($request,	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'username'	
  =>	
  'required|min:3|max:20',	
  
	
  	
  	
  	
  	
  	
  	
  	
  'email'	
  =>	
  'required|email'	
  
	
  	
  	
  	
  ]);	
  
	
  	
  	
  	
  //	
  以下略	
  
}
Form RequestValidation
• 嚴格來說,表單驗證不是 Controller 要做的事,更
好的作法是將其獨⽴立成⼀一個類別來專責處理
• 除了單純的資料驗證外,還需要更複雜的⾝身份驗證
• Laravel 5 提供了新的 Form Request 驗證⽅方式,讓驗
證動作可以完全與 Controller 分開,⽽而流程和動作
⼀一樣⾃自動化完成
• artisan 也新增了 make:request 指令,讓產⽣生
Form Request 類別檔案也能⾃自動化
$	
  [php]	
  artisan	
  make:request	
  	
  
{name}
產⽣生	
  form	
  request	
  檔案
artisan	
  make:request
• 透過 artisan 產⽣生 Form Request 類別
- artisan	
  會依照給予的名稱,產⽣生類別檔案
• 範例:
$	
  php	
  artisan	
  make:request	
  PostRequest
產⽣生 Form Request 檔案
使⽤用 artisan 產⽣生 Form Request 檔案
命名與指令慣例
• ⼀一般慣例會將 Form Request 以 {⼤大駝峰資源單
數}Request 來命名,如 PostRequest
• 預設 Form Request 檔案會放置在 app/Http/Requests/
資料夾底下
Form Request 檔結構
• ⼀一個 Form Request 檔裡⼀一定實作兩個 method:
- authorize (授權):在這個 method 裡要回傳 true
或 false,⾄至於如何判定回傳值為何?就可以在這
個 method 裡實作
- rules (驗證規則):在這個 method 裡回傳⼀一個陣
列,這個陣列就跟 Validator::make 的第⼆二個參
數⼀一樣,把想要驗證的規則寫在其中即可
Form Request 檔範例
authorize() 實作⽅方式
• 可以在 method 內實作⾃自⼰己的授權邏輯,確認使⽤用者
取得授權才能再執⾏行 validate
• 預設為 false,若暫時不需要⾝身份認證,可以強制
回傳 true
//	
  在	
  form	
  request	
  裡驗證⾝身份	
  
public	
  function	
  authorize()	
  
{	
  
	
  	
  	
  	
  //	
  假設	
  app/Http/routes.php	
  裡寫	
  
	
  	
  	
  	
  //	
  Route::post('comment/{id}');	
  
	
  	
  	
  	
  //	
  則可從	
  route	
  拿到	
  comment	
  id	
  的值	
  
	
  	
  	
  	
  $id	
  =	
  $this-­‐>route('id');	
  
	
  	
  	
  	
  //	
  檢查這個	
  comment	
  是不是該	
  user	
  新增的?	
  
	
  	
  	
  	
  return	
  Comment::where('id',	
  $id)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>where('user_id',	
  Auth::id())-­‐>exists();	
  
}
rules() 實作⽅方式
• 在 rules() 裡依照 Laravel 提供的內建驗證規則設定
//	
  在	
  form	
  request	
  裡設定規則	
  
public	
  function	
  rules()	
  
{	
  
	
  	
  	
  	
  return	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'username'	
  =>	
  'required|min:3|max:20',	
  
	
  	
  	
  	
  	
  	
  	
  	
  'email'	
  =>	
  'required|email'	
  
	
  	
  	
  	
  	
  	
  	
  	
  'title'	
  =>	
  'required|max:255',	
  
	
  	
  	
  	
  	
  	
  	
  	
  'body'	
  =>	
  'required',	
  
	
  	
  	
  	
  ];	
  
}
Laravel 提供的驗證規則
• Laravel 提供了為數不少的內建驗證規則,以下列出
常使⽤用的數個範例:
- required, accepted, same
- string, boolean, integer, numeric, array, date
- min, max, between
- email, url, ip
- unique, exists
Controller 內的實作
• 由於表單驗證的事情全部由 Form Requet 類別處理,
因此在 Controller 裡只需要透過 type-hinting 把對應
的 Form Request 呼叫進來,剩下的事全⾃自動化!
//	
  在	
  Controller	
  裡呼叫	
  Form	
  Request	
  
<?php	
  namespace	
  AppHttpControllers;	
  
use	
  AppHttpRequestsPostRequest;	
  
public	
  function	
  store(PostRequest	
  $request)	
  
{	
  
	
  	
  	
  	
  //	
  只要能夠執⾏行到這⼀一⾏行就表⽰示通過驗證了!	
  
}
表單錯誤訊息
Laravel 的表單錯誤訊息
• 在 Laravel 的預設動作裡,執⾏行完驗證後,只要沒有
通過,Laravel 就會返回上⼀一個⾴頁⾯面,並把錯誤訊息
⽤用 Session 傳遞過去
• ⽽而在任⼀一⾴頁⾯面載⼊入的時候,Laravel 會⾃自動的去檢查
Session 裡有沒有錯誤訊息?只要有錯誤訊息,
Laravel 會⾃自動把錯誤訊息放在 $errors 這個變數裡
給 View 使⽤用 (也就是說不⽤用⼿手動在 Controller 裡把錯誤訊息從 Session
拿出來再送到View 去)
• $errors 這個變數是 MessageBag 類別的實體,只
要呼叫這個類別對應的⽅方法,就可以將錯誤訊息印
出來
查詢是否有錯誤訊息?
• 查詢⺫⽬目前的⾴頁⾯面是否有錯誤訊息?有的話就印
Bootstrap 的 Alert Component
//	
  resources/views/*.blade.php	
  
//	
  在	
  View	
  裡確認是否有錯誤訊息?	
  
@if	
  ($errors-­‐>any())	
  
<div	
  class="alert	
  alert-­‐danger	
  alert-­‐dismissible"	
  role="alert">	
  
	
  	
  	
  	
  <button	
  type="button"	
  class="close"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  data-­‐dismiss="alert"	
  aria-­‐label="Close">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <span	
  aria-­‐hidden="true">&times;</span>	
  
	
  	
  	
  	
  </button>	
  
	
  	
  	
  	
  <strong>錯誤!</strong>	
  請修正您輸⼊入的資料	
  
</div>	
  
@endif
取得欄位的錯誤訊息
• 取得欄位的所有錯誤訊息
• 取得欄位的第⼀一個錯誤訊息
//	
  resources/views/*.blade.php	
  
//	
  印出	
  email	
  的第⼀一個錯誤訊息	
  
{{	
  $errors-­‐>first('email')	
  }}	
  
//	
  印出	
  email	
  的第⼀一個錯誤訊息,並依格式輸出	
  
{!!	
  $errors-­‐>first('email',	
  '<p>:message</p>')	
  !!}
//	
  resources/views/*.blade.php	
  
//	
  取得	
  email	
  的錯誤訊息	
  
{{	
  $errors-­‐>get('email')	
  }}
將錯誤訊息印出來
• 把欄位所有的錯誤訊息印出來
• 把表單所有的錯誤訊息印出來
//	
  resources/views/*.blade.php	
  
//	
  印出表單的所有錯誤訊息	
  
@foreach($errors-­‐>all()	
  as	
  $error)	
  
	
  	
  	
  	
  {{	
  $error	
  }}	
  
@endforeach
//	
  resources/views/*.blade.php	
  
//	
  印出	
  email	
  的所有錯誤訊息	
  
@foreach($errors-­‐>get('email')	
  as	
  $error)	
  
	
  	
  	
  	
  {{	
  $error	
  }}	
  
@endforeach
Model	
  錯誤處理
回傳 404
• 先檢查資料存不存在?假如不存在的話就顯⽰示 404
Page not found
//	
  app/Http/Controllers/PostsController.php	
  
public	
  function	
  show($id)	
  
{	
  
	
   $post	
  =	
  AppPost::find($id);	
  
	
   	
  
	
   if	
  (is_null($post))	
  
	
   {	
  
	
   	
   abort(404);	
  
	
   }	
  
	
  	
  	
  	
  //	
  以下略	
  
}
使⽤用 findOrFail()
• Eloquent 有⼀一個⽅方法叫 findOrFail,若 Eloquent 找
不到對應的資料的話,會拋出
ModelNotFoundException
//	
  app/Http/Controllers/PostsController.php	
  
public	
  function	
  show($id)	
  
{	
  
	
   $post	
  =	
  AppPost::findOrFail($id);	
  
	
  	
  	
  	
  //	
  以下略	
  
}
使⽤用 Session
• 也可以⾃自⾏行處理該錯誤發⽣生時的動作,增加額外的
提⽰示給使⽤用者
//	
  app/Http/Controllers/PostsController.php	
  
public	
  function	
  show($id)	
  
{	
  
	
   $post	
  =	
  AppPost::find($id);	
  
	
   	
  
	
   if	
  (is_null($post))	
  
	
   {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  redirect()-­‐>route('posts.index')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>with('message',	
  '找不到該⽂文章');	
  
	
   }	
  
	
  	
  	
  	
  //	
  以下略	
  
}
在View 裡顯⽰示 Session 訊息
• 在 Controller 裡定義好要放⼊入 Session 的訊息內容
後,就可以在View 裡將其取回並顯⽰示在⾴頁⾯面上
//	
  resources/views/*.blade.php	
  
@if	
  (session('message'))	
  
<div	
  class="alert	
  alert-­‐danger	
  alert-­‐dismissible"	
  
role="alert">	
  
	
  	
  	
  	
  <button	
  type="button"	
  class="close"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  data-­‐dismiss="alert"	
  aria-­‐label="Close">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <span	
  aria-­‐hidden="true">&times;</span>	
  
	
  	
  	
  	
  </button>	
  
	
  	
  	
  	
  <strong>錯誤!</strong>	
  {{	
  session('message')	
  }}	
  
</div>	
  
@endif
實作專案驗證機制
建⽴立 Form Request
• 依照專案實作需求,透過 make:request 建⽴立兩個
Form Request 類別
• 在這兩個 Form Request 類別內
- 強制將 authorize() 設為 true
- 設定 rules() 裡對應的規則
• 設定 Controller 引⼊入對應的 Form Request
設定⾴頁⾯面顯⽰示訊息
• 將以下兩種結果的訊息顯⽰示在對應的⾴頁⾯面上:
- 表單驗證失敗
- 資料儲存成功
- 資料更新成功
單元總結
• 在這個單元裡我們學到了些什麼?
- 透過三種⽅方式在 Laravel 裡實作資料驗證
- 運⽤用跳轉機制來重導⾴頁⾯面,並在⾴頁⾯面顯⽰示錯誤訊息
提⽰示使⽤用者
- 完成專案應⽤用程式內的驗證及跳轉機制
Q & A
歡迎提問討論

More Related Content

What's hot

What's hot (20)

使用者認證
使用者認證使用者認證
使用者認證
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
工作坊簡介
工作坊簡介工作坊簡介
工作坊簡介
 
給你一個使用 Laravel 的理由
給你一個使用 Laravel 的理由給你一個使用 Laravel 的理由
給你一個使用 Laravel 的理由
 
應用程式佈署
應用程式佈署應用程式佈署
應用程式佈署
 
使用 Controller
使用 Controller使用 Controller
使用 Controller
 
CRUD 綜合運用
CRUD 綜合運用CRUD 綜合運用
CRUD 綜合運用
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向
 
Eloquent ORM
Eloquent ORMEloquent ORM
Eloquent ORM
 
開發環境建置
開發環境建置開發環境建置
開發環境建置
 
專案啟動與環境設定
專案啟動與環境設定專案啟動與環境設定
專案啟動與環境設定
 
課程簡介
課程簡介課程簡介
課程簡介
 
LaravelConf Taiwan 2017 單頁面應用與前後端分離開發
LaravelConf Taiwan 2017 單頁面應用與前後端分離開發LaravelConf Taiwan 2017 單頁面應用與前後端分離開發
LaravelConf Taiwan 2017 單頁面應用與前後端分離開發
 
Route路由控制
Route路由控制Route路由控制
Route路由控制
 
COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南
 
CRUD 綜合運用
CRUD 綜合運用CRUD 綜合運用
CRUD 綜合運用
 
整合 Open ID
整合 Open ID整合 Open ID
整合 Open ID
 
Package安裝與使用
Package安裝與使用Package安裝與使用
Package安裝與使用
 
使用者認證
使用者認證使用者認證
使用者認證
 
Route 路由控制
Route 路由控制Route 路由控制
Route 路由控制
 

Viewers also liked

Viewers also liked (10)

Migrations 與 Schema 操作
Migrations 與 Schema 操作Migrations 與 Schema 操作
Migrations 與 Schema 操作
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理
 
工作坊總結
工作坊總結工作坊總結
工作坊總結
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
Eloquent ORM
Eloquent ORMEloquent ORM
Eloquent ORM
 
工作坊簡介
工作坊簡介工作坊簡介
工作坊簡介
 
工作坊總結
工作坊總結工作坊總結
工作坊總結
 
使用 Eloquent ORM
使用 Eloquent ORM使用 Eloquent ORM
使用 Eloquent ORM
 
Route 機制
Route 機制Route 機制
Route 機制
 
CRUD 綜合應用
CRUD 綜合應用CRUD 綜合應用
CRUD 綜合應用
 

Similar to 驗證與訊息

OpenWebSchool - 11 - CodeIgniter
OpenWebSchool - 11 - CodeIgniterOpenWebSchool - 11 - CodeIgniter
OpenWebSchool - 11 - CodeIgniter
Hung-yu Lin
 
Introduction to ASP.NET MVC and MVC 5 Features
Introduction to ASP.NET MVC and MVC 5 FeaturesIntroduction to ASP.NET MVC and MVC 5 Features
Introduction to ASP.NET MVC and MVC 5 Features
Jeff Chu
 
1, workflow intro
1, workflow intro1, workflow intro
1, workflow intro
ted-xu
 
跟我一起學 CakePHP
跟我一起學 CakePHP跟我一起學 CakePHP
跟我一起學 CakePHP
Ray Wei
 

Similar to 驗證與訊息 (20)

How to ASP.NET MVC4
How to ASP.NET MVC4How to ASP.NET MVC4
How to ASP.NET MVC4
 
Schema & Migration操作
Schema & Migration操作Schema & Migration操作
Schema & Migration操作
 
Model & Seeding整合
Model & Seeding整合Model & Seeding整合
Model & Seeding整合
 
Laradebut #7 - Laravel AUTH
Laradebut #7 - Laravel AUTHLaradebut #7 - Laravel AUTH
Laradebut #7 - Laravel AUTH
 
OpenWebSchool - 11 - CodeIgniter
OpenWebSchool - 11 - CodeIgniterOpenWebSchool - 11 - CodeIgniter
OpenWebSchool - 11 - CodeIgniter
 
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
 
Introduction to ASP.NET MVC and MVC 5 Features
Introduction to ASP.NET MVC and MVC 5 FeaturesIntroduction to ASP.NET MVC and MVC 5 Features
Introduction to ASP.NET MVC and MVC 5 Features
 
1, workflow intro
1, workflow intro1, workflow intro
1, workflow intro
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0
 
API技术讲解
API技术讲解API技术讲解
API技术讲解
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
使用 laravel 的前與後
使用 laravel 的前與後使用 laravel 的前與後
使用 laravel 的前與後
 
網頁安全 Web security 入門 @ Study-Area
網頁安全 Web security 入門 @ Study-Area網頁安全 Web security 入門 @ Study-Area
網頁安全 Web security 入門 @ Study-Area
 
How to choose web framework
How to choose web frameworkHow to choose web framework
How to choose web framework
 
HITCON GIRLS 資安萌芽推廣 2017: 你知道你連線的網站黑黑的嗎
HITCON GIRLS 資安萌芽推廣 2017: 你知道你連線的網站黑黑的嗎HITCON GIRLS 資安萌芽推廣 2017: 你知道你連線的網站黑黑的嗎
HITCON GIRLS 資安萌芽推廣 2017: 你知道你連線的網站黑黑的嗎
 
跟我一起學 CakePHP
跟我一起學 CakePHP跟我一起學 CakePHP
跟我一起學 CakePHP
 
ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享
 
北護大/FHIR 開發簡介與應用
北護大/FHIR 開發簡介與應用北護大/FHIR 開發簡介與應用
北護大/FHIR 開發簡介與應用
 
Laravel 5.2 教學
Laravel 5.2 教學Laravel 5.2 教學
Laravel 5.2 教學
 

More from Shengyou Fan

[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
Shengyou Fan
 

More from Shengyou Fan (20)

[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
初探 Kotlin Multiplatform
初探 Kotlin Multiplatform初探 Kotlin Multiplatform
初探 Kotlin Multiplatform
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
 
Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
 

驗證與訊息

  • 2. 單元主題 • 資料驗證對網路應⽤用程式的重要性 • 在 Laravel 裡如何實作資料驗證?有哪些⽅方式可供我 們選擇使⽤用? • 如何透過跳轉處理資料驗證失敗時的動作?以及如 何在⾴頁⾯面上顯⽰示錯誤訊息提供使⽤用者回饋機制? • ⽰示範如何在專案內實作驗證及跳轉功能
  • 4. 千萬別相信任何⼈人! • 撰寫 PHP 程式來接受輸⼊入並將結果輸出是很容易的, 但卻無法保證所有來源輸⼊入的資料都是安全的 • 常常聽到有網站被惡意攻擊或是不⼩小⼼心將個資洩漏就 是因為沒有做好安全性防護機制 • 因此,為了確保應⽤用程式運作正常且安全,就是絕對 不要相信任何從使⽤用者端取得的資料! • 網路應⽤用程式安全的三⼤大守則: - 對輸⼊入消毒 - 驗證資料 - 跳脫輸出內容
  • 6. 傳統的驗證⽅方式 • 條件組合⼤大法: - 檢查是不是空值 empty()、is_null()、isset() - 檢查字串⻑⾧長度 strlen()、mb_strlen()、sizeof() - 上網找「php email/name/phone validate regex」 然後⽤用 preg_match()、ereg() //  檢查  username  是否為空值、⻑⾧長度超過  3  個字元且只有⼤大⼩小寫字⺟母   if(!empty($_POST['username'])  &&          strlen($_POST[‘username'])  >  3  &&          preg_match("/^[a-­‐zA-­‐Z]*$/",  $_POST['username']))   {     //  通過驗證!   }
  • 7. PHP 內建的驗證函式 • PHP 提供 filter_var() 驗證函式並搭配數個以 FILTER_VALIDATE_* 開頭的指標供我們做資料驗證 • 雖然 filter_var() 提供了數種驗證⽅方式,但它無 法驗證所有東⻄西 //  使⽤用  filter_var()  驗證  Email   $email  =  $_POST['email'];   $isEmail  =  filter_var($email,  FILTER_VALIDATE_EMAIL);   if  ($isEmail  !==  false)  {          /*  假如驗證通過則會回傳原本的變數內容  */          /*  假如驗證錯誤則會回傳  false  */          //  通過驗證!   }
  • 8. Laravel 的驗證機制 • Laravel 內建提供了三種⽅方式供我們驗證資料,可依 不同的需求選擇: - Validator Facade - ControllerValidation - Form RequestValidation
  • 10. Validator Facade • Laravel 內建提供Validator 類別,可直接透過 Facade 呼叫,就可以快速的實作驗證機制 //  使⽤用  Validator  Facade  進⾏行驗證   $validator  =  Validator::make(          [                  'username'  =>  'tester',                  'email'  =>  'tester@example.com'          ],          [                  'username'  =>  'required|min:3|max:20',                  'email'  =>  'required|email|unique:users'          ]   );   if  ($validator-­‐>fails())   {          //  沒有通過驗證,跳轉回前⼀一⾴頁,並把錯誤訊息帶過去   return  redirect()-­‐>back()-­‐>withErrors($validator-­‐>errors());   }
  • 11. ControllerValidation • Laravel 的 BaseController 已經幫我們加好 ValidatesRequests 的 Trait,只要直接使⽤用 validate ⽅方 法就可以進⾏行驗證 • 若驗證失敗,就會⾃自動跳轉回前⼀一⾴頁,並把錯誤訊 息帶過去,完全⾃自動化! //  在  Controller  裡儲存資料時驗證資料   public  function  store(Request  $request)   {          $this-­‐>validate($request,  [                  'username'  =>  'required|min:3|max:20',                  'email'  =>  'required|email'          ]);          //  以下略   }
  • 12. Form RequestValidation • 嚴格來說,表單驗證不是 Controller 要做的事,更 好的作法是將其獨⽴立成⼀一個類別來專責處理 • 除了單純的資料驗證外,還需要更複雜的⾝身份驗證 • Laravel 5 提供了新的 Form Request 驗證⽅方式,讓驗 證動作可以完全與 Controller 分開,⽽而流程和動作 ⼀一樣⾃自動化完成 • artisan 也新增了 make:request 指令,讓產⽣生 Form Request 類別檔案也能⾃自動化
  • 13. $  [php]  artisan  make:request     {name} 產⽣生  form  request  檔案
  • 14. artisan  make:request • 透過 artisan 產⽣生 Form Request 類別 - artisan  會依照給予的名稱,產⽣生類別檔案 • 範例: $  php  artisan  make:request  PostRequest
  • 15. 產⽣生 Form Request 檔案 使⽤用 artisan 產⽣生 Form Request 檔案
  • 16. 命名與指令慣例 • ⼀一般慣例會將 Form Request 以 {⼤大駝峰資源單 數}Request 來命名,如 PostRequest • 預設 Form Request 檔案會放置在 app/Http/Requests/ 資料夾底下
  • 17. Form Request 檔結構 • ⼀一個 Form Request 檔裡⼀一定實作兩個 method: - authorize (授權):在這個 method 裡要回傳 true 或 false,⾄至於如何判定回傳值為何?就可以在這 個 method 裡實作 - rules (驗證規則):在這個 method 裡回傳⼀一個陣 列,這個陣列就跟 Validator::make 的第⼆二個參 數⼀一樣,把想要驗證的規則寫在其中即可
  • 19. authorize() 實作⽅方式 • 可以在 method 內實作⾃自⼰己的授權邏輯,確認使⽤用者 取得授權才能再執⾏行 validate • 預設為 false,若暫時不需要⾝身份認證,可以強制 回傳 true //  在  form  request  裡驗證⾝身份   public  function  authorize()   {          //  假設  app/Http/routes.php  裡寫          //  Route::post('comment/{id}');          //  則可從  route  拿到  comment  id  的值          $id  =  $this-­‐>route('id');          //  檢查這個  comment  是不是該  user  新增的?          return  Comment::where('id',  $id)                                      -­‐>where('user_id',  Auth::id())-­‐>exists();   }
  • 20. rules() 實作⽅方式 • 在 rules() 裡依照 Laravel 提供的內建驗證規則設定 //  在  form  request  裡設定規則   public  function  rules()   {          return  [                  'username'  =>  'required|min:3|max:20',                  'email'  =>  'required|email'                  'title'  =>  'required|max:255',                  'body'  =>  'required',          ];   }
  • 21. Laravel 提供的驗證規則 • Laravel 提供了為數不少的內建驗證規則,以下列出 常使⽤用的數個範例: - required, accepted, same - string, boolean, integer, numeric, array, date - min, max, between - email, url, ip - unique, exists
  • 22. Controller 內的實作 • 由於表單驗證的事情全部由 Form Requet 類別處理, 因此在 Controller 裡只需要透過 type-hinting 把對應 的 Form Request 呼叫進來,剩下的事全⾃自動化! //  在  Controller  裡呼叫  Form  Request   <?php  namespace  AppHttpControllers;   use  AppHttpRequestsPostRequest;   public  function  store(PostRequest  $request)   {          //  只要能夠執⾏行到這⼀一⾏行就表⽰示通過驗證了!   }
  • 24. Laravel 的表單錯誤訊息 • 在 Laravel 的預設動作裡,執⾏行完驗證後,只要沒有 通過,Laravel 就會返回上⼀一個⾴頁⾯面,並把錯誤訊息 ⽤用 Session 傳遞過去 • ⽽而在任⼀一⾴頁⾯面載⼊入的時候,Laravel 會⾃自動的去檢查 Session 裡有沒有錯誤訊息?只要有錯誤訊息, Laravel 會⾃自動把錯誤訊息放在 $errors 這個變數裡 給 View 使⽤用 (也就是說不⽤用⼿手動在 Controller 裡把錯誤訊息從 Session 拿出來再送到View 去) • $errors 這個變數是 MessageBag 類別的實體,只 要呼叫這個類別對應的⽅方法,就可以將錯誤訊息印 出來
  • 25. 查詢是否有錯誤訊息? • 查詢⺫⽬目前的⾴頁⾯面是否有錯誤訊息?有的話就印 Bootstrap 的 Alert Component //  resources/views/*.blade.php   //  在  View  裡確認是否有錯誤訊息?   @if  ($errors-­‐>any())   <div  class="alert  alert-­‐danger  alert-­‐dismissible"  role="alert">          <button  type="button"  class="close"                          data-­‐dismiss="alert"  aria-­‐label="Close">                  <span  aria-­‐hidden="true">&times;</span>          </button>          <strong>錯誤!</strong>  請修正您輸⼊入的資料   </div>   @endif
  • 26. 取得欄位的錯誤訊息 • 取得欄位的所有錯誤訊息 • 取得欄位的第⼀一個錯誤訊息 //  resources/views/*.blade.php   //  印出  email  的第⼀一個錯誤訊息   {{  $errors-­‐>first('email')  }}   //  印出  email  的第⼀一個錯誤訊息,並依格式輸出   {!!  $errors-­‐>first('email',  '<p>:message</p>')  !!} //  resources/views/*.blade.php   //  取得  email  的錯誤訊息   {{  $errors-­‐>get('email')  }}
  • 27. 將錯誤訊息印出來 • 把欄位所有的錯誤訊息印出來 • 把表單所有的錯誤訊息印出來 //  resources/views/*.blade.php   //  印出表單的所有錯誤訊息   @foreach($errors-­‐>all()  as  $error)          {{  $error  }}   @endforeach //  resources/views/*.blade.php   //  印出  email  的所有錯誤訊息   @foreach($errors-­‐>get('email')  as  $error)          {{  $error  }}   @endforeach
  • 29. 回傳 404 • 先檢查資料存不存在?假如不存在的話就顯⽰示 404 Page not found //  app/Http/Controllers/PostsController.php   public  function  show($id)   {     $post  =  AppPost::find($id);         if  (is_null($post))     {       abort(404);     }          //  以下略   }
  • 30. 使⽤用 findOrFail() • Eloquent 有⼀一個⽅方法叫 findOrFail,若 Eloquent 找 不到對應的資料的話,會拋出 ModelNotFoundException //  app/Http/Controllers/PostsController.php   public  function  show($id)   {     $post  =  AppPost::findOrFail($id);          //  以下略   }
  • 31. 使⽤用 Session • 也可以⾃自⾏行處理該錯誤發⽣生時的動作,增加額外的 提⽰示給使⽤用者 //  app/Http/Controllers/PostsController.php   public  function  show($id)   {     $post  =  AppPost::find($id);         if  (is_null($post))     {                  return  redirect()-­‐>route('posts.index')                                                    -­‐>with('message',  '找不到該⽂文章');     }          //  以下略   }
  • 32. 在View 裡顯⽰示 Session 訊息 • 在 Controller 裡定義好要放⼊入 Session 的訊息內容 後,就可以在View 裡將其取回並顯⽰示在⾴頁⾯面上 //  resources/views/*.blade.php   @if  (session('message'))   <div  class="alert  alert-­‐danger  alert-­‐dismissible"   role="alert">          <button  type="button"  class="close"                          data-­‐dismiss="alert"  aria-­‐label="Close">                  <span  aria-­‐hidden="true">&times;</span>          </button>          <strong>錯誤!</strong>  {{  session('message')  }}   </div>   @endif
  • 34. 建⽴立 Form Request • 依照專案實作需求,透過 make:request 建⽴立兩個 Form Request 類別 • 在這兩個 Form Request 類別內 - 強制將 authorize() 設為 true - 設定 rules() 裡對應的規則 • 設定 Controller 引⼊入對應的 Form Request
  • 36. 單元總結 • 在這個單元裡我們學到了些什麼? - 透過三種⽅方式在 Laravel 裡實作資料驗證 - 運⽤用跳轉機制來重導⾴頁⾯面,並在⾴頁⾯面顯⽰示錯誤訊息 提⽰示使⽤用者 - 完成專案應⽤用程式內的驗證及跳轉機制