ThinkPHP: モデル用の 3 つの強力なツールのうちの 2 番目 (修飾子)

爱喝马黛茶的安东尼
リリース: 2019-12-16 17:01:07
転載
2697 人が閲覧しました

ThinkPHP: モデル用の 3 つの強力なツールのうちの 2 番目 (修飾子)

モディファイアはモデルの三大「ツール」の一つですが、今回はモディファイアの使い方と注意点をまとめます。

モディファイアの定義

モディファイアの機能は、モデル オブジェクト データがデータベースに書き込まれる前に、必要なデータ処理を実行することです。モディファイアの標準定義は、

public function setFieldNameAttr($value, $data)
{
    // 对value值进行处理 data参数是当前全部数据
    // 返回值就是实际要写入数据库的值
    return $value;
}
ログイン後にコピー

FieldName は、データテーブルの field_name フィールドに対応します (データテーブルのフィールドの仕様と修飾子メソッドの定義仕様に注意してください。エラーが発生します)。

原則として、各修飾子は対応するフィールドのデータのみを処理する必要がありますが、必要に応じて複数のフィールドを同時に処理することもできます。

以下は例です

public function setBirthdayAttr($value, $data)
{
    // 格式化生日数据
    $birthday = strtotime($value);
    // 根据生日判断年龄
    $age = getAgeByBirthday($birthday);
    // 赋值年龄数据
    $this->setAttr('age', $age);
    return $birthday;
}
public function setAgeAttr($value,$data)
{
    return floor($value);
}
ログイン後にコピー

setAttr メソッドが使用される理由は、年齢割り当て操作が別の修飾子を通過できるようにするためです。追加の修飾子がない場合は、

public function setBirthdayAttr($value, $data)
{
    // 格式化生日数据
    $birthday = strtotime($value);
    // 根据生日判断年龄
    $age = getAgeByBirthday($birthday);
    // 赋值年龄数据
    $this->data['age'] = $age;
    return $birthday;
}
ログイン後にコピー

として記述することもできます。モデル内でデータ オブジェクトを割り当てると、次のような非効率が生じるため、

$this->age = $age;
ログイン後にコピー

として記述しないでください。モデルの内部属性との混同、予見される結果。

特定のモディファイアの他のフィールドを変更する可能性がある場合は、追加で変更する必要があるフィールド モディファイアが割り当てられている (またはそのモディファイアがトリガーされている) 必要があることに注意してください。

呼び出し方法

修飾子メソッドは、定義仕様に従って定義されると、手動で呼び出す必要はなく、システムが自動的に呼び出します。次の状況:

·モデル オブジェクトの割り当て;

·データ メソッドを呼び出します。モデル、2 番目のパラメーターは true で渡されます;

# ·モデルの save メソッドを呼び出し、配列データを渡します;

·モデルの setAttr メソッドを明示的に呼び出します。

· このフィールドの自動補完を定義します。

たとえば、User モデルは setPasswordAttr 変更デバイス メソッドを定義します。

public function setPasswordAttr($value, $data)
{
    return md5($value);
}
ログイン後にコピー

次のように使用すると、データベースに保存されるパスワードフィールドの値は、md5('think') 以降の値になります。

$user = User::get(1);
$user->password = 'think';
$user->save();
ログイン後にコピー

修飾子を使用したくないが、場合によってはデータを手動で制御したい場合は、次の方法を試すことができます。

$user = User::get(1);
$user->data('password', md5('think'));
$user->save();
ログイン後にコピー

現時点ではモディファイアによって処理されません。

競合の回避#​​##多くの開発者は、修飾子のオートコンプリート auto (挿入と更新を含む) を定義することを好みます。

protected $auto = ['password'];
ログイン後にコピー

これは、一見賢いように見えますが、V5.1.27 より前の非常に致命的な間違いです。以前に指定したモディファイアのトリガー条件に従って、モディファイアが 2 回実行されることになるため、これを避けるようにしてください。これは致命的なエラーとなり、すべてのユーザーが登録後に正常にログインできなくなります。

解決策値が割り当てられるたびに修飾子が自動的にトリガーされるため、パスワード フィールドの自動補完設定をキャンセルします。割り当てがない場合は、パスワードが変更されていないことを意味します。自動完了はありません。

オートコンプリート フィールドは通常、フォームにないフィールドであり、通常はシステムによって自動的に処理されるフィールドです。

V5.1.27 バージョンではこの問題が改善され、すべてのモディファイアは 1 回のみ実行できるようになり、上記の問題はなくなりました。しかし、これにより新たな問題が発生したようです。モデルのイベントでデータを変更する必要が生じることがよくあります。

User::beforeUpdate(function($user) {
    $user->password = md5('think');
});
ログイン後にコピー

モデルの beforeUpdate イベントでは、データの値を変更できないことがわかります。その理由は、モデルのモディファイアが最初の割り当て中に実行され、2 番目の割り当て中に実行されているためです。無効です (再度実行されません)。

解決策は、前に述べたように、データ割り当て操作の修飾子を呼び出さずに data メソッドを使用することです。

User::beforeUpdate(function($user) {
    $user->data('password', md5('think'));
});
ログイン後にコピー

もちろん、より良い提案は、修飾子、オートコンプリート、およびモデル イベントのデータ処理メカニズムを計画することです。フィールドのデータを同時に変更するために複数のメカニズムを使用しないでください。データ変更操作は、このメソッドを通じて実行されます。

型の自動変換

修飾子がデータの型変換のみを実行する場合は、修飾子を定義する必要はなく、フィールドの型を直接定義するだけです。

public function setScoreAttr($value, $data)
{
    return (float) $score;
}
ログイン後にコピー

上記の修飾子メソッドは、

protected $type = [
    'score'    =>    'float',
];
ログイン後にコピー

に直接変更できます。修飾子とフィールドの型を同時に定義した場合、修飾子が優先されます。

型定義は単純なデータ型を定義するだけでなく、追加の用途もあります。たとえば、json 型、配列型、オブジェクト型は JSON シリアル化され、シリアル化型はデータをシリアル化します。

PHP 中国語 Web サイトには、無料の

ThinkPHP 入門チュートリアル

が多数あり、誰でも学習することができます。 この記事は https://blog.thinkphp.cn/817548

から転載しています。

以上がThinkPHP: モデル用の 3 つの強力なツールのうちの 2 番目 (修飾子)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:thinkphp.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート