You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:45:22