October CMS Partial代码重构咨询:重复代码的合理存放位置
解决October CMS Partial中onStart()重复代码的方案
这是个很典型的代码复用场景,在October CMS里完全不用动vendor目录就能优雅解决,给你几个靠谱的方案,适配不同的场景需求:
方案一:自定义Partial基类(推荐,适合强关联的Partial组)
October允许你创建自己的Partial基类,让需要复用逻辑的Partial继承它,完全不需要修改vendor里的核心代码。
步骤1:创建通用基类
在你的插件目录下(比如plugins/yourvendor/yourplugin/classes)新建BasePartial.php,把重复的逻辑封装进去,通过抽象方法让子类提供对应的模型类:
<?php namespace YourVendor\YourPlugin\Classes; use October\Rain\Element\Partial; abstract class BasePartial extends Partial { // 要求子类必须返回对应的模型类名 abstract protected function getModelClass(); public function onStart() { // 获取子类指定的模型类 $modelClass = $this->getModelClass(); // 通用查询逻辑 $x = $modelClass::where('myColumn', 'myValue')->first(); // 这里放你那一大段重复的$x处理逻辑 // ... // 统一赋值视图数据 $this['viewData'] = $x->getViewData(); } }
步骤2:改造现有Partial
让你的Partial继承这个自定义基类,只需要实现getModelClass方法返回对应模型即可:
Partial 1 的代码:
<?php namespace YourVendor\YourPlugin\Partials; use YourVendor\YourPlugin\Classes\BasePartial; use YourVendor\YourPlugin\Models\MyModel1; class Partial1 extends BasePartial { protected function getModelClass() { return MyModel1::class; } }
Partial 2 的代码:
<?php namespace YourVendor\YourPlugin\Partials; use YourVendor\YourPlugin\Classes\BasePartial; use YourVendor\YourPlugin\Models\MyModel2; class Partial2 extends BasePartial { protected function getModelClass() { return MyModel2::class; } }
方案二:使用Trait(灵活,适合零散Partial复用)
如果你的Partial不需要统一继承某个基类,用Trait来封装重复逻辑会更灵活,Trait可以被多个类引入而不影响继承链。
步骤1:创建通用Trait
在插件目录下(比如plugins/yourvendor/yourplugin/traits)新建PartialCommonLogic.php:
<?php namespace YourVendor\YourPlugin\Traits; trait PartialCommonLogic { public function onStart() { $modelClass = $this->getModelClass(); $x = $modelClass::where('myColumn', 'myValue')->first(); // 重复的$x处理逻辑 // ... $this['viewData'] = $x->getViewData(); } // 同样要求引入Trait的类实现这个方法 abstract protected function getModelClass(); }
步骤2:在Partial中引入Trait
修改Partial的代码,引入Trait并实现getModelClass:
Partial 1 的代码:
<?php namespace YourVendor\YourPlugin\Partials; use October\Rain\Element\Partial; use YourVendor\YourPlugin\Traits\PartialCommonLogic; use YourVendor\YourPlugin\Models\MyModel1; class Partial1 extends Partial { use PartialCommonLogic; protected function getModelClass() { return MyModel1::class; } }
额外优化点
- 如果
where条件不是固定的,你可以在基类/Trait中定义可配置的属性,比如protected $filterColumn = 'myColumn';,子类可以重写这些属性来适配不同的查询需求; - 因为你的模型都实现了同一接口,完全不用担心
getViewData()等方法的兼容性,这种设计本身就很适合复用逻辑。
内容的提问来源于stack exchange,提问作者Jon Abaca
相关产品推荐
相关产品推荐

