jlorente / yii2-activerecord-inheritance
ActiveRecord Inheritance 是一个工具,用于为 Yii2 框架提供类表继承模式。它模拟两个 ActiveRecord 类之间的继承。
1.0.8
2023-11-15 19:04 UTC
Requires
- yiisoft/yii2: *
README
ActiveRecord Inheritance 是一个工具,用于为 Yii2 框架提供类表继承模式。它的动机是模拟两个 ActiveRecord 类之间的继承。
安装
在 bower.json 文件中将包作为依赖项包含。
要安装,可以运行
$ php composer.phar require jlorente/yii2-activerecord-inheritance "*"
或者将以下内容添加到你的 composer.json
文件的 require
部分:
... "require": { ... "jlorente/yii2-activerecord-inheritance": "*" }
使用方法
使用示例可能如下:
假设你有以下架构。
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `created_at` int(11) NOT NULL, `updated_at` int(11) NOT NULL, PRIMARY KEY (`id`) ); CREATE TABLE `admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `level` INT NOT NULL, `banned_users` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), CONSTRAINT `FK_Admin_Id` FOREIGN KEY (`id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, );
要模拟两个表之间的继承,你的代码应该看起来像这样。
use jlorente\db\ActiveRecordInheritanceTrait, jlorente\db\ActiveRecordInheritanceInterface; use yii\db\ActiveRecord; class User extends ActiveRecord { public function tableName() { return 'user'; } public function doSomething() { echo 'User does something'; } } class Admin extends ActiveRecord implements ActiveRecordInheritanceInterface { use ActiveRecordInheritanceTrait; public function tableName() { return 'admin'; } public static function extendsFrom() { return User::className(); } public function doSomething() { echo 'Admin does something'; } }
你将能够像使用继承自 User 对象的 Admin 对象一样使用 Admin 对象。
$admin = new Admin(); $admin->username = 'al-acran'; $admin->email = 'al_acran@gmail.com'; $admin->name = 'Al'; $admin->last_name = 'Acran'; $admin->level = 1; $admin->save();
你可以通过使用父关系属性来调用父方法和方法属性。
$admin->doSomething() //Admin does something $admin->parent->doSomething() //User does something
这个特性在模拟继承时非常有用,但是应该在对父关系应用查询过滤器。
$admin = Admin::find() ->joinWith('parent', function($query) { $query->andWhere(['username' => 'al-acran']); $query->andWhere(['name' => 'Al']); }) ->andWhere(['level' => 1]) ->one();
注意事项
为了正确使用特性,你必须考虑以下要点
通用
- 默认情况下,假设的子类的主键被用作父模型的外键,如果你想使用其他属性作为外键,你应该重写 parentAttribute() 方法。
- 该特性不适用于多个主键和外键。
ActiveRecord 方法
- 在此特性中重写的来自 ActiveRecord 的方法(如 save、validate 等)不应在使用特性的类上重写,否则功能将丢失。
- 要正确地重写这些方法,可以扩展使用特性的类,并在那里重写方法,确保所有方法都调用其父实现。
继承调用层次结构
- 自然调用层次结构被保留,因此如果方法或属性存在于被调用的类或其祖先中,则调用该方法或属性。
- 如果方法或属性不在自然调用层次结构中,将调用适当的魔术方法(__get、__set、__isset、__unset、__call),并使用 yii2 调用层次结构。如果方法或属性未在此调用层次结构中找到,则执行下一步。
- 上述过程将重复用于模拟的父对象。
- 当找到方法或属性或没有更多父对象时,调用层次结构将停止。在这种情况下,将引发 UnknownPropertyException 或 UnknownMethodException。
- 你可以将模拟的父类连接起来,仅限于 php 调用堆栈的限制。
许可证
版权 © 2015 José Lorente Martín jose.lorente.martin@gmail.com。许可协议为 MIT。有关详细信息,请参阅 LICENSE.txt。