国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - Yii2中的場景(scenario)和驗證規則(rule)詳解

Yii2中的場景(scenario)和驗證規則(rule)詳解

2019-10-25 13:20tlanyan PHP教程

Yii2的rule用于對模型屬性進行驗證,scenario用戶定義不同場景下需要驗證的模型,下面這篇文章主要給大家介紹了關于Yii2中場景(scenario)和驗證規則(rule)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。

前言

場景,顧名思義,就是一個情景,一種場面。在yii2中也有場景,這個場景跟你所理解的場景含義差不多。

和用戶有交互的系統必不可少的功能包括收集用戶數據、校驗和處理。實際業務中,往往還需要將數據進行持久化存儲。出于安全考慮,開發人員應當牢牢把握“客戶端的輸入都是不可信”的準則,客戶端傳過來的數據先進行過濾和清洗后再存儲或傳遞到內部系統。

Yii2推薦使用Model類來收集和校驗用戶數據,持久化的ActiveRecord類是其子類。Model類的load和validate兩個方法,分別用來收集和校驗客戶端數據。哪些數據應該被收集,哪些數據需要在什么場景下驗證,便是本文的主題:場景(scenario)和驗證規則(rule)。

下面話不多說了,來隨著小編一起看看詳細的介紹吧。

系統結構

先引入一個簡單的業務系統:系統中存在學生和教師兩種角色,數據庫中使用了三張表保存角色信息:

user: [id, username, password, status, 其他通用屬性]

student: [id, user_id, student_no, grade, class, 其他學生屬性]

teacher: [id, user_id, work_no, title, telphone, 其他教師屬性]

實際業務不限于對這三張表的增刪查改操作。為了簡化問題,后續僅討論user和student兩張表的數據變更(給出teacher表是為了讓讀者不認為設計數據庫的人是腦殘:明明可以放到一張表的,為什么要拆開!)。

學生報名

學生報名是典型的增刪查改操作,送分題。學生報名的簡要代碼示例如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function actionSignup()
{
 $data = Yii::$app->request->post();
 $user = new User();
 $user->load($data);
 if ($user->save()) {
  $student = new Student([
   "user_id" => $user->id,
  ]);
  $student->load($data);
  if ($student->save()) {
   // redirect to success page
  } else {
   $user->delete();
  }
 }
 // render error page
}

相信有Yii2使用經驗的人都能根據數據庫的字段約束快速的把User和Student類的rules方法寫出來。例如User類文件內容可能如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
namespace app\models;
class User extends \yii\db\ActiveRecord
{
 public function rules()
 {
  return [   [["username", "password", "status",], "required"],
   ["username", "unique"],
   // other rules
  ];
 }
 // other method
}

定義數據的驗證規則,這是大多數人對rules的第一印象,并且是一個很好的印象:它打回非法的數據,讓正常的數據進入系統中。安全的實踐應該盡量定義完整的規則,充分驗證數據。也建議每一個Yii2開發人員對內置的核心校驗器熟悉。

修改信息

修改信息,也是典型的增刪查改操作。實現代碼和報名差別不大,這里僅討論兩點:

1、用戶密碼的驗證

注冊時會校驗用戶密碼是否8-16位,密碼的規則可能是: ["password", "string", "length" => [8, 16]] 。明文保存密碼是不可取的,插入數據庫時至少會做MD5加密,password變成32位。假設用戶修改信息時未修改密碼,再次保存時密碼規則校驗出錯(長度不符合),無法保存!

怎么解決這個問題呢?翻閱Yii文檔,發現了規則中的when屬性可以救場。一種可能的驗證規則是:

?
1
2
3
4
5
6
7
8
public function rules()
{
 return [
   ["password", "string", "length" => [8, 16], 'when' => function ($model) {
    return $model->isNewRecord;
   }],
   // other rules
  ];

只有在注冊(新增數據)時才校驗密碼字段。問題解決,完美!

2、防止用戶私自改密碼

假設有個小聰明的家伙(例如湯姆),發現系統是用Yii框架做的,想搞點小破壞炫耀一下水平。在發送修改信息的表單時,湯姆增加&password=12345678這一段數據。系統使用$user->load($data)收集用戶輸入,更新password字段,帶來如下后果:rules設置更新時不校驗密碼字段,12345678直接作為password的值保存到數據庫中。這個操作帶來連鎖反應:用戶再次登錄時,加密過后的密碼與數據庫中的明文密碼不匹配,導致湯姆無法登錄系統。煩人的是湯姆是個刺頭,登錄不上后整天騷擾客服,不省心!

怎么樣防止這種情況出現呢?一種解決的方法是阻止修改密碼:

?
1
2
3
4
5
6
unset($data["password"]);
$user->load($data);
// 或者
$password = $user->password;
$user->load($data);
$user->password = $password;

把用戶輸入的密碼過濾掉,私自修改密碼的問題就解決了。

但是問題還沒有結束:湯姆可以轉向修改其他字段,比如說性別,身份證等。更嚴重情況是修改student中user_id,就可以更改任意學生的信息。事情十分嚴重,需要馬上修復漏洞。

可以按照密碼的方法,逐個屏蔽受保護屬性,但顯得啰嗦難看(雖然好使)。如果受保護屬性多,可以僅允許白名單進入,具體操作為:新增一個UpdateInfoForm類繼承Model,屬性是白名單屬性合計。用UpdateInfoForm類過濾用戶數據,校驗通過后再更新到user和student中:

?
1
2
3
4
5
6
7
$form = new UpdateInfoForm();
$form->load($data);
if ($form->validate()) {
 $user->load($form->attributes);
 $student->load($form->attributes);
 // next biz
}

這種方式更優雅,但仔細一想代價不小:屬性和驗證規則要重復寫一遍;user和student保存時又重復校驗屬性。這種方式看起來優雅,實際上卻冗余又低效。

scenario的登場,完美的解決解決上述問題。

場景(scenario)

分析上面問題,會發現關鍵點是批量賦值(massive assignment)和數據校驗(validate)兩個方法。如果對不同的場景指定賦值字段和檢驗規則,問題就迎刃而解。

Yii中的scenario有 安全屬性 和 活躍屬性 兩個概念。安全屬性用在批量賦值的load方法,只有安全屬性才能被賦值;活躍屬性用在規則校驗的validate方法,在活躍屬性集中并且定義了校驗規則的屬性才會被校驗。活躍屬性和安全屬性的關系是,安全屬性是活躍屬性的子集。

\yii\base\Model類定義了默認場景:SCENARIO_DEFAULT(值為default)。默認場景下,出現在rules方法中的屬性既是活躍屬性,又是安全屬性(這句話基本正確,看后續解釋)。為不同場景指定活躍屬性、安全屬性以及校驗器,可以通過覆蓋senarios或rules兩個方法實現(幾乎每個Model類都會重寫rules方法,senarios用得少)。

rules

先看rules方法。默認的屬性加校驗器定義方式,讓每個屬性既是安全屬性,也是活躍屬性。如果想讓某個屬性不是安全屬性(不能通過load批量賦值),在屬性名前加感嘆號!即可。例如student中的user_id字段:

?
1
2
3
4
5
6
7
8
9
public function rules()
{
 return [
  ["!user_od", "required"],
  ["!user_id", "integer"],
  ["!user_od", "unique"],
  // other rules
 ];
}

user_id是活躍屬性,在寫入數據庫時會被校驗。但它不是安全屬性,不能通過load方法進行賦值,解決了安全隱患。

再看rules方法按場景區分校驗器規則的做法:定義校驗器時on屬性指定規則在哪些場景下生效,except屬性則排除一些場景(如果不指定on和except,規則對所有場景生效)。例如:

?
1
2
3
4
5
6
7
8
public function rules()
{
 return [
  ["password", "string", "length" => [8, 16], "on" => ["signup"]], // 僅在signup場景時才被驗證
  ["status", "integer", "except" => ["signup"], // 除了signup場景,其他情況都校驗
  // other rules
 ];
}

在原來基礎上新增感嘆號和on/except屬性,非常簡便的就定義了非安全屬性以及分場景指定校驗規則。

scenarios

另外一種更清晰定義安全屬性和活躍屬性的做法是重寫scenarios方法。scenarios方法返回一個數組,數組的鍵是場景名稱,值是活躍屬性集合(包飯安全屬性)。例如student表的可能實現如下:

?
1
2
3
4
5
6
7
public function scenarios()
{
 return [
  self::SCENARIO_DEFAULT => ["!user_id", "grade", "class", xxxx],
  "update" => ["grade", "class", xxxx],
 ];
}

默認情形下(學生報名),年級、班級這些信息是安全屬性,但user_id不是,只能在程序內部賦值,并在插入數據時被校驗;在修改信息時,user_id不是活躍屬性,既不能被批量賦值,也不需要校驗(事實上它不應該改變)。

scenarios方法只能定義活躍屬性和安全屬性,無法定義校驗規則,需要和rules配合使用。

總結

金肯定義完善的數據校驗規則

業務復雜時定義多個場景,仔細為每個場景定義安全屬性和校驗規則

優先使用rules;屬性較多、rules復雜時,可以配合scenarios方法迅速理清安全屬性和活躍屬性

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

參考

http://www.yiiframework.com/doc-2.0/guide-input-validation.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩高清国产一区在线 | 亚洲免费在线观看 | 亚洲精品免费播放 | 中文字幕亚洲欧美日韩在线不卡 | 视频一区二区三区在线播放 | 久草视频在线播放 | 欧美三级影院 | 午夜激情视频在线 | 色婷婷一区二区 | 欧美高清一区 | 99热新 | 久久一二三四 | 免费伊人网 | 久久伊人精品网 | 黄色成人在线视频 | 国产精品久久一区二区三区 | 亚洲精品久久久久久下一站 | 中文字字幕一区二区三区四区五区 | 自拍偷拍一区二区三区 | 毛片一级av | 国产免费黄色 | 国产一区二区精品丝袜 | 亚洲精品乱码 | 亚洲精品久久久一区二区三区 | 亚洲黄色在线观看 | 久久99精品久久久久久久青青日本 | 一区二区三区久久久 | 国内精品久久久久久影视8 有码在线 | 精品久久一区二区三区 | 国产人成精品一区二区三 | av在线日韩 | 国产精品一二三区视频 | 三区在线 | 亚洲在线一区 | 天堂在线免费视频 | 欧美另类视频在线 | 亚洲男人av | 欧美一级在线观看 | 九九在线精品视频 | 黄站免费 | 国产综合精品 |