1 我们想像有这样的需求
1.1 应用中有两个类。其一是 荣誉(Honour)其一是 档案(Archive)Honour 和 Arhcive 是多态关联。即拥有档案属性的不只荣誉类,还有更多的类去关联,如:新闻、人物等,一个应用类拥有一个档案类。
1.2 为了代码的复用,我们建立一个 Trait, HasArchive
1.3 功能预期:模型删除时,在 Trait 中,将其所关联的 archive 一并删除。同时,不能影响模型中删除事件的其他逻辑「可能还有权限判断,下级关联删除等相关处理工作」。
2 事件测试
2.1 Traits/HasArchive.php
/** * The boot method. */ public static function bootHasArchive() { /** * Handle the "deleting" event. */ static::deleting(function ($model) { $class = get_class($model); info("HasArchive Trait deleting {$class} {$model->id}"); if ($archive = $model->archive) { $archive->delete(); } }); static::created(function ($model) { info(__CLASS__ . __METHOD__); }); }
2.2 Honour.php
use HasArchive;
protected static function boot() { parent::boot(); static::created(function ($honour) { info(__CLASS__ . __METHOD__); }); }
2.3 HonourObserver.php
/** * Handle the honour "created" event. * * @param AppHonour $honour * @return void */ public function created(Honour $honour) { info(__CLASS__ . __METHOD__); }
2.4 Archive.php
protected static function boot() { parent::boot(); static::created(function ($archive) { info(__CLASS__ . __METHOD__); }); }
2.5 ArchiveObserver.php
/** * Handle the archive "created" event. * * @param AppArchive $archive * @return void */ public function created(Archive $archive) { info(__CLASS__. __METHOD__); }
2.6 在 tinker 中执行测试语句
>>> Honour::create()->archive()->create()
日志输出如下:
[2019-06-06 09:41:17] local.INFO: AppHonourAppTraits{closure}
[2019-06-06 09:41:17] local.INFO: AppHonourApp{closure}
[2019-06-06 09:41:17] local.INFO: AppObserversHonourObserverAppObserversHonourObserver::created
[2019-06-06 09:41:17] local.INFO: AppArchiveApp{closure}
[2019-06-06 09:41:17] local.INFO: AppObserversArchiveObserverAppObserversArchiveObserver::created
2.7 测试结论
2.7.1 「Trait, Model, Observer」三个地方的事件侦听互不影响
2.7.1 事件执行的顺利: Trait => Model => Observer