Die Regeln von Yii2 werden verwendet, um Modellattribute zu überprüfen. Der folgende Artikel stellt hauptsächlich relevante Informationen zu Szenarien (Szenarien) und Verifizierungsregeln (Regeln) in Yii2 vor. Der Artikel stellt es anhand eines Beispielcodes ausführlich vor, Freunde in Not können darauf verweisen.
Vorwort
Szene ist, wie der Name schon sagt, eine Szene, eine Szene. Es gibt auch Szenen in yii2, die eine ähnliche Bedeutung haben wie die Szenen, die Sie verstehen.
Zu den wesentlichen Funktionen eines Systems, das mit Benutzern interagiert, gehören das Sammeln von Benutzerdaten, die Überprüfung und die Verarbeitung. Im tatsächlichen Geschäftsleben müssen Daten häufig dauerhaft gespeichert werden. Aus Sicherheitsgründen sollten sich Entwickler den Grundsatz bewusst sein, dass „die Eingaben des Clients nicht vertrauenswürdig sind“. Die vom Client übergebenen Daten werden gefiltert und bereinigt, bevor sie gespeichert oder an das interne System übertragen werden.
Yii2 empfiehlt die Verwendung der Model-Klasse zum Sammeln und Überprüfen von Benutzerdaten, und die persistente ActiveRecord-Klasse ist ihre Unterklasse. Die Lade- und Validierungsmethoden der Model-Klasse werden zum Sammeln bzw. Überprüfen von Clientdaten verwendet. Welche Daten gesammelt werden sollen und welche Daten in welchen Szenarien überprüft werden müssen, sind die Themen dieses Artikels: Szenarien und Überprüfungsregeln.
Im Folgenden gibt es nicht viel zu sagen. Folgen wir dem Herausgeber und werfen wir einen Blick auf die ausführliche Einführung.
Systemstruktur
Stellen Sie zunächst ein einfaches Geschäftssystem vor: Es gibt zwei Rollen von Schülern und Lehrern im System, nämlich Wird in der Datenbank verwendet. Zum Speichern von Rolleninformationen werden drei Tabellen erstellt:
Benutzer: [ID, Benutzername, Passwort, Status, andere allgemeine Attribute]
Student: [ID, Benutzer-ID, Studenten-Nr., Note , Klasse, andere Schülerattribute]
Lehrer: [ID, Benutzer-ID, Arbeitsnummer, Titel, Telefon, andere Lehrerattribute]
Das eigentliche Geschäft ist nicht auf das Hinzufügen, Löschen, Abfragen usw. beschränkt Änderungsoperationen dieser drei Tabellen. Um das Problem zu vereinfachen, werden später nur die Datenänderungen in den Benutzer- und Schülertabellen besprochen (die Lehrertabelle wird angegeben, damit die Leser nicht denken, dass die Person, die die Datenbank entworfen hat, dumm ist: Sie kann in einer Tabelle zusammengefasst werden , warum sollte es getrennt werden!).
Studentenregistrierung
Die Studentenregistrierung ist ein typischer Vorgang zum Hinzufügen, Löschen, Überprüfen und Ändern, und Unterfragen werden gesendet . Ein kurzes Codebeispiel für die Studentenregistrierung lautet wie folgt:
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 }
Ich glaube, dass jeder, der Erfahrung mit Yii2 hat, schnell die Regeln der Benutzer- und Studentenklassen festlegen kann zu den Feldeinschränkungen der Datenbank. Notieren Sie die Methode. Der Inhalt der Benutzerklassendatei kann beispielsweise wie folgt lauten:
namespace app\models; class User extends \yii\db\ActiveRecord { public function rules() { return [ [["username", "password", "status",], "required"], ["username", "unique"], // other rules ]; } // other method }
Definieren Sie die Validierungsregeln für Daten. Dies ist der erste Eindruck, den die meisten Menschen haben Regeln, und es ist ein guter Eindruck: Es bekämpft illegale Daten und lässt normale Daten in das System gelangen. Sicherheitspraktiken sollten versuchen, vollständige Regeln zu definieren und Daten vollständig zu überprüfen. Es wird außerdem empfohlen, dass sich jeder Yii2-Entwickler mit den integrierten Kernvalidatoren vertraut macht.
Informationen ändern
Das Ändern von Informationen ist ebenfalls ein typischer Vorgang zum Hinzufügen, Löschen, Überprüfen und Ändern. Es gibt keinen großen Unterschied zwischen dem Implementierungscode und der Registrierung. Hier werden nur zwei Punkte besprochen:
1. Überprüfung des Benutzerpassworts
Bei der Registrierung wird es überprüft Unabhängig davon, ob das Benutzerkennwort 8–16 Ziffern umfasst, könnte die Kennwortregel lauten: ["password", "string", "length" => [8, 16]]
. Es ist nicht ratsam, Passwörter im Klartext zu speichern. Beim Einfügen in die Datenbank wird mindestens eine MD5-Verschlüsselung durchgeführt und das Passwort wird 32 Bit lang. Gehen Sie davon aus, dass der Benutzer das Passwort beim Ändern der Informationen nicht ändert. Beim erneuten Speichern tritt ein Fehler bei der Überprüfung der Passwortregel auf (die Länge stimmt nicht überein) und kann nicht gespeichert werden!
Wie kann dieses Problem gelöst werden? Beim Durchsehen der Yii-Dokumentation habe ich festgestellt, dass das when-Attribut in den Regeln Abhilfe schaffen kann. Eine mögliche Validierungsregel ist:
public function rules() { return [ ["password", "string", "length" => [8, 16], 'when' => function ($model) { return $model->isNewRecord; }], // other rules ];
Verifizieren Sie das Passwortfeld nur bei der Registrierung (neue Daten). Problem gelöst, perfekt!
2. Verhindern Sie, dass Benutzer ihre Passwörter privat ändern
Angenommen, es gibt einen klugen Kerl (wie Tom), der herausfindet, dass das System mit dem Yii-Framework erstellt wurde möchte etwas Schaden anrichten. Beim Absenden des Formulars zum Ändern der Informationen fügt Tom &password=12345678 hinzu. Das System verwendet $user->load($data)
, um Benutzereingaben zu sammeln und das Passwortfeld zu aktualisieren, was folgende Konsequenzen hat: Das Passwortfeld wird bei der Aktualisierung der Regeleinstellungen nicht überprüft und 12345678 wird direkt in der Datenbank als Passwortwert gespeichert. Dieser Vorgang löste eine Kettenreaktion aus: Als sich der Benutzer erneut anmeldete, stimmte das verschlüsselte Passwort nicht mit dem Klartext-Passwort in der Datenbank überein, was dazu führte, dass Tom sich nicht beim System anmelden konnte. Das Ärgerliche ist, dass Tom ein Dorn im Auge ist, nachdem er sich nicht einloggen konnte und den Kundenservice den ganzen Tag belästigt, worüber man sich keine Sorgen machen muss.
Wie kann man verhindern, dass diese Situation eintritt? Eine Lösung besteht darin, Passwortänderungen zu verhindern:
unset($data["password"]); $user->load($data); // 或者 $password = $user->password; $user->load($data); $user->password = $password;
Filtern Sie die von Benutzern eingegebenen Passwörter heraus, und das Problem der privaten Passwortänderung ist gelöst.
Aber das Problem ist noch nicht gelöst: Tom kann andere Felder wie Geschlecht, Personalausweis usw. ändern. Eine ernstere Situation besteht darin, dass Sie durch Ändern der Benutzer-ID im Schüler die Informationen jedes Schülers ändern können. Die Angelegenheit ist ernst und die Schwachstelle muss sofort behoben werden.
可以按照密码的方法,逐个屏蔽受保护属性,但显得啰嗦难看(虽然好使)。如果受保护属性多,可以仅允许白名单进入,具体操作为:新增一个UpdateInfoForm类继承Model,属性是白名单属性合计。用UpdateInfoForm类过滤用户数据,校验通过后再更新到user和student中:
$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字段:
public function rules() { return [ ["!user_od", "required"], ["!user_id", "integer"], ["!user_od", "unique"], // other rules ]; }
user_id是活跃属性,在写入数据库时会被校验。但它不是安全属性,不能通过load方法进行赋值,解决了安全隐患。
再看rules方法按场景区分校验器规则的做法:定义校验器时on属性指定规则在哪些场景下生效,except属性则排除一些场景(如果不指定on和except,规则对所有场景生效)。例如:
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表的可能实现如下:
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
MixPHP、Yii和CodeIgniter的并发压力测试的小结
PHP基于非递归算法实现先序、中序及后序遍历二叉树操作的示例
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Szenarien und Verifizierungsregeln in Yii2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!