目次
您可能感兴趣的文章:
ホームページ バックエンド開発 PHPチュートリアル Yii2のシナリオと検証ルールの詳細説明

Yii2のシナリオと検証ルールの詳細説明

Jun 30, 2018 pm 06:04 PM
yii2 作成する

Yii2 のルールは、モデルの属性を検証するために使用されます。シナリオ ユーザーは、さまざまなシナリオで検証する必要があるモデルを定義します。以下の記事では、Yii2 のシナリオ (シナリオ) と検証ルール (ルール) に関する関連情報を主に紹介します。この記事ではサンプルコードを通して詳しく紹介していますので、困っている友人は参考にしてください。

序文

シーンとは、その名の通り、状況、場面のことです。 yii2 にも、あなたが理解しているシーンと同様の意味を持つシーンがあります。

ユーザーと対話するシステムの重要な機能には、ユーザー データの収集、検証、処理が含まれます。実際のビジネスでは、データを永続的に保存する必要があることがよくあります。セキュリティ上の理由から、開発者は「クライアントからの入力は信頼できない」という原則をしっかりと理解し、クライアントから送信されたデータは、内部システムに保存または転送される前にフィルタリングおよびクリーニングされる必要があります。

Yii2 では、ユーザー データの収集と検証に Model クラスを使用することを推奨しており、永続的な ActiveRecord クラスはそのサブクラスです。 Model クラスのロード メソッドと検証メソッドは、それぞれクライアント データの収集と検証に使用されます。どのデータを収集し、どのシナリオでどのデータを検証する必要があるかが、この記事のテーマです。シナリオと検証ルールです。

以下では多くを語る必要はありません。編集者に従って詳細な紹介を見てみましょう。

#システム構造

#最初に簡単なビジネス システムを紹介します。システム内には生徒と教師の 2 つの役割があり、使用されます。データベース内にロール情報を保存するために 3 つのテーブルが作成されます:

user: [id、username、password、status、その他の共通属性]

student: [id、user_id、student_no、grade、クラス、他の生徒の属性]

Teacher: [id、user_id、work_no、役職、電話番号、その他の教師の属性]

実際の業務は追加、削除、クエリ、変更に限定されません。これら 3 つのテーブルの操作を説明します。問題を単純化するために、ユーザー テーブルと学生テーブルのデータ変更についてのみ後で説明します (教師テーブルは、データベースを設計した人が愚かであると読者が思わないように指定されています。テーブルは 1 つのテーブルにまとめることができます) 、なぜ分離する必要があるのですか!)。

生徒登録

生徒登録は、ポイントの追加、削除、確認・修正、送信といった一般的な操作です。学生登録の簡単なコード例は次のとおりです:

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 クラス ベースのルールをすぐに設定できると思います。データベースのフィールド制約に関する方法を書き留めます。たとえば、User クラス ファイルの内容は次のようになります:

namespace app\models;
class User extends \yii\db\ActiveRecord
{
 public function rules()
 {
  return [   [["username", "password", "status",], "required"],
   ["username", "unique"],
   // other rules
  ];
 }
 // other method
}
ログイン後にコピー

データの検証ルールを定義します。これは、ほとんどの人がこのファイルに対して抱く第一印象です。印象: 不正なデータを撃退し、通常のデータがシステムに入るのを許可します。セキュリティ対策では、完全なルールを定義し、データを完全に検証するように努める必要があります。また、すべての Yii2 開発者が組み込みのコアバリデーターに精通することをお勧めします。

情報の変更

情報の変更も、一般的な追加、削除、確認、および変更操作です。実装コードと登録には大きな違いはなく、ここでは 2 点だけ説明します:

1. ユーザー パスワードの検証

登録時にユーザー パスワードが検証されます。ユーザーのパスワードが 8 ~ 16 桁であるかどうかに関係なく、パスワード ルールは

["password", "string", "length" => [8, 16]] になります。パスワードを平文で保存することはお勧めできません。データベースに挿入する際には、少なくとも MD5 暗号化が実行され、パスワードは 32 ビットになります。ユーザーが情報を変更する際にパスワードを変更しなかったと仮定し、再度保存すると、パスワード規則の検証エラー(長さが一致しない)が発生し、保存できません。

この問題を解決するにはどうすればよいですか? Yii のドキュメントを調べてみると、ルール内の when 属性が役に立つことがわかりました。考えられる検証ルールの 1 つは次のとおりです。

public function rules()
{
 return [
   ["password", "string", "length" => [8, 16], 'when' => function ($model) {
    return $model->isNewRecord;
   }],
   // other rules
  ];
ログイン後にコピー

登録時のみパスワード フィールドを検証します (新しいデータ)。問題は解決しました、完璧です!

2. ユーザーが個人的にパスワードを変更できないようにする

システムが Yii フレームワークを使用して作られていることを発見した賢い人 (トムなど) がいると仮定します。ダメージを与えたいのでスキルを見せつけてください。情報を変更するためにフォームを送信するときに、トムは &password=12345678 を追加します。システムは、

$user->load($data) を使用してユーザー入力を収集し、パスワード フィールドを更新します。これにより、次の結果が生じます: ルール設定の更新時にパスワード フィールドが検証されず、12345678はパスワード値としてデータベースに直接保存されます。この操作により連鎖反応が発生しました。ユーザーが再度ログインすると、暗号化されたパスワードがデータベース内の平文パスワードと一致せず、トムはシステムにログインできなくなりました。厄介なのは、トムが厄介者で、ログインできなくなった後は一日中カスタマー サービスに嫌がらせをするので、心配するのは簡単ではありません。

この状況を防ぐにはどうすればよいでしょうか?解決策の 1 つは、パスワードの変更を防ぐことです。

unset($data["password"]); 
$user->load($data);
// 或者
$password = $user->password;
$user->load($data);
$user->password = $password;
ログイン後にコピー

ユーザーが入力したパスワードをフィルターで除外すると、パスワードを非公開で変更する問題は解決されます。

しかし、問題はまだ終わっていません。トムは性別や ID カードなどの他のフィールドを変更することができます。さらに深刻な状況は、student の user_id を変更することで、任意の学生の情報を変更できることです。問題は深刻であり、脆弱性は直ちに修正される必要があります。

可以按照密码的方法,逐个屏蔽受保护属性,但显得啰嗦难看(虽然好使)。如果受保护属性多,可以仅允许白名单进入,具体操作为:新增一个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基于非递归算法实现先序、中序及后序遍历二叉树操作的示例

PHP使用两个栈实现队列功能的方法的讲解

以上がYii2のシナリオと検証ルールの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Python で累積曲線グラフを作成するにはどうすればよいですか? Python で累積曲線グラフを作成するにはどうすればよいですか? Aug 23, 2023 pm 08:33 PM

オジブ グラフは、一連のデータの累積分布関数 (CDF) をグラフで表し、累積度数曲線とも呼ばれます。データの分布を調査し、パターンと傾向を発見するために使用されます。 Matplotlib、Pandas、Numpy は、Python が提供するグラフィックスを作成するためのライブラリとツールの一部です。このチュートリアルでは、Matplotlib を使用して Python でオギブ グラフィックを生成する方法を見ていきます。累積曲線チャートを作成するには、必要なライブラリをインポートする必要があります。この例では、Matplotlib、Pandas、Numpy を使用します。 Matplotlib は、Python で作成するための人気のあるデータ視覚化ライブラリです。

Pythonで定数を作成するにはどうすればよいですか? Pythonで定数を作成するにはどうすればよいですか? Aug 29, 2023 pm 05:17 PM

定数と変数は、プログラミングでデータ値を保存するために使用されます。変数は通常、時間の経過とともに変化する値を指します。定数は、プログラムの実行中に値を変更できない変数の一種です。 Python で使用できる組み込み定数は 6 つだけです。False、True、None、NotImplemented、Ellipsis(...)、__debug__ です。これらの定数とは別に、Python には定数値を格納するための組み込みデータ型がありません。例 定数の例を以下に示します。False=100 が出力されます。 SyntaxError:cannotassigntoFalseFalse は、ブール値を格納するために使用される Python の組み込み定数です。

最新の iOS 17 で iPhone をカスタマイズする方法 最新の iOS 17 で iPhone をカスタマイズする方法 Sep 21, 2023 am 08:17 AM

iPhone で通話をカスタマイズする方法 Apple の iOS 17 では、iPhone の通話画面の外観をカスタマイズできる連絡先ポスターと呼ばれる新機能が導入されています。この機能を使用すると、選択した写真、色、フォント、ミー文字を連絡先カードとして使用してポスターをデザインできます。そのため、電話をかけると、受信者の iPhone にあなたのカスタム画像が想像どおりに表示されます。独自の連絡先ポスターを保存されているすべての連絡先と共有するか、誰が閲覧できるかを選択できます。同様に、通話交換中に他の人の連絡先ポスターも表示されます。さらに、Apple では、個々の連絡先に特定の連絡先の写真を設定し、それらの連絡先から電話をかけることができます

GIMPでピクセルアートを作成する方法 GIMPでピクセルアートを作成する方法 Feb 19, 2024 pm 03:24 PM

この記事は、Windows でのピクセル アート作成に GIMP を使用することに興味がある場合に役立ちます。 GIMP は、無料でオープンソースであるだけでなく、美しい画像やデザインを簡単に作成できる有名なグラフィック編集ソフトウェアです。 GIMP は、初心者にもプロのデザイナーにも同様に適していることに加えて、描画と作成のための唯一の構成要素としてピクセルを利用するデジタル アートの形式であるピクセル アートの作成にも使用できます。 GIMP でピクセル アートを作成する方法 Windows PC で GIMP を使用してピクセル アートを作成する主な手順は次のとおりです。 GIMP をダウンロードしてインストールし、アプリケーションを起動します。新しいイメージを作成します。幅と高さのサイズを変更します。鉛筆ツールを選択します。ブラシの種類をピクセルに設定します。設定

Realme Phoneでフォルダーを作成するにはどうすればよいですか? Realme Phoneでフォルダーを作成するにはどうすればよいですか? Mar 23, 2024 pm 02:30 PM

タイトル: Realme Phone 初心者ガイド: Realme Phone でフォルダーを作成する方法?今日の社会において、携帯電話は人々の生活に欠かせないツールとなっています。人気のスマートフォン ブランドとして、Realme Phone はそのシンプルで実用的なオペレーティング システムでユーザーに愛されています。 Realme 携帯電話を使用する過程で、多くの人が携帯電話上のファイルやアプリケーションを整理する必要がある状況に遭遇する可能性があり、フォルダーを作成するのが効果的な方法です。この記事では、ユーザーが携帯電話のコンテンツをより適切に管理できるように、Realme 携帯電話にフォルダーを作成する方法を紹介します。いいえ。

Gree+ でファミリーを作成する方法 Gree+ でファミリーを作成する方法 Mar 01, 2024 pm 12:40 PM

「Gree+ ソフトウェアでファミリーを作成する方法を知りたい」という友達がたくさんいました。操作方法は次のとおりです。詳しく知りたい友達は、一緒に見に来てください。まず、携帯電話で Gree+ ソフトウェアを開き、ログインします。次に、ページ下部のオプション バーで、右端の [My] オプションをクリックして、個人アカウント ページに入ります。 2. マイページにアクセスすると、「ファミリー」の下に「ファミリーを作成」という項目があるので、それをクリックして入力します。 3. 次にファミリーを作成するページにジャンプし、表示に従って入力ボックスに設定するファミリー名を入力し、入力後右上の「保存」ボタンをクリックします。 4. 最後に、ページの下部に「正常に保存しました」というプロンプトが表示され、ファミリが正常に作成されたことが示されます。

Python でユーザー インターフェイスを作成するにはどうすればよいですか? Python でユーザー インターフェイスを作成するにはどうすればよいですか? Aug 26, 2023 am 09:17 AM

この記事では、Pythonを使用してユーザーインターフェイスを作成する方法を学びます。グラフィカル ユーザー インターフェイスとは何ですか? 「グラフィカル ユーザー インターフェイス」(または「GUI」) という用語は、情報を表示したり対話したりするためにコンピューター ソフトウェアで対話できる一連の視覚要素項目を指します。人間の入力に応じて、オブジェクトは色、サイズ、可視性などの外観特性を変更する場合があります。アイコン、カーソル、ボタンなどのグラフィカル コンポーネントをオーディオ効果または視覚効果 (透明度など) で強化して、グラフィカル ユーザー インターフェイス (GUI) を作成できます。より多くの人にプラットフォームを使用してもらいたい場合は、優れたユーザー インターフェイスを備えていることを確認する必要があります。これらの要因の組み合わせによって、アプリや Web サイトが提供するサービスの品質に大きな影響を与える可能性があるためです。 Python は、次の機能を備えているため、開発者によって広く使用されています。

ハイチャートを使用してガント チャートを作成する方法 ハイチャートを使用してガント チャートを作成する方法 Dec 17, 2023 pm 07:23 PM

Highcharts を使用してガント チャートを作成する方法には、特定のコード サンプルが必要です。はじめに: ガント チャートは、プロジェクトの進捗状況や時間管理を表示するためによく使用されるチャート形式です。タスクの開始時刻、終了時刻、進捗状況を視覚的に表示できます。 Highcharts は、豊富なチャート タイプと柔軟な構成オプションを提供する強力な JavaScript チャート ライブラリです。この記事では、Highcharts を使用してガント チャートを作成する方法と具体的なコード例を紹介します。 1. ハイチャート

See all articles