october/extension

此包已 废弃 且不再维护。没有建议的替代包。

基于扩展的类,例如私有特质


README

此扩展为类提供了具有 私有特质(也称为行为)的能力,类似于原生PHP特质,但具有一些独特的优势

  1. 行为有自己的构造函数。
  2. 行为可以有私有或受保护的函数。
  3. 方法和属性名可以安全地冲突。
  4. 类可以动态地扩展行为。

您可能像这样使用特质

class MyClass
{
    use \October\Rain\UtilityFunctions;
    use \October\Rain\DeferredBinding;
}

行为的使用方式类似

class MyClass extends \October\Rain\Extension\Extendable
{
    public $implement = [
        'October.Rain.UtilityFunctions',
        'October.Rain.DeferredBinding',
    ];
}

您可能像这样定义特质

trait UtilityFunctions
{
    public function sayHello()
    {
        echo "Hello from " . get_class($this);
    }
}

行为是这样定义的

class UtilityFunctions extends \October\Rain\Extension\ExtensionBase
{
    protected $parent;

    public function __construct($parent)
    {
        $this->parent = $parent;
    }

    public function sayHello()
    {
        echo "Hello from " . get_class($this->parent);
    }
}

扩展的对象总是作为第一个参数传递给行为的构造函数。

使用示例

行为/扩展类

<?php namespace MyNamespace\Behaviors;

class FormController extends \October\Rain\Extension\ExtensionBase
{
    /**
     * @var Reference to the extended object.
     */
    protected $controller;

    /**
     * Constructor
     */
    public function __construct($controller)
    {
        $this->controller = $controller;
    }

    public function someMethod()
    {
        return "I come from the FormController Behavior!";
    }

    public function otherMethod()
    {
        return "You might not see me...";
    }
}

扩展类

Controller 类将实现 FormController 行为,然后这些方法将可用(混合)到类中。我们将重写 otherMethod 方法。

<?php namespace MyNamespace;

class Controller extends \October\Rain\Extension\Extendable
{

    /**
     * Implement the FormController behavior
     */
    public $implement = [
        'MyNamespace.Behaviors.FormController'
    ];

    public function otherMethod()
    {
        return "I come from the main Controller!";
    }
}

使用扩展

$controller = new MyNamespace\Controller;

// Prints: I come from the FormController Behavior!
echo $controller->someMethod();

// Prints: I come from the main Controller!
echo $controller->otherMethod();

// Prints: You might not see me...
echo $controller->asExtension('FormController')->otherMethod();

动态使用行为/构造函数扩展

任何使用 ExtendableExtendableTrait 的类都可以通过静态 extend() 方法扩展其构造函数。参数应传递一个闭包,该闭包将在类构造函数的一部分中调用。例如

/**
 * Extend the Pizza Shop to include the Master Splinter behavior too
 */
MyNamespace\Controller::extend(function($controller){

    // Implement the list controller behavior dynamically
    $controller->implement[] = 'MyNamespace.Behaviors.ListController';
});

动态创建方法

可以通过使用 addDynamicMethodModel 添加方法。

Post::extend(function($model) {
    $model->addDynamicMethod('getTagsAttribute', function() use ($model) {
        return $model->tags()->lists('name');
    });
});

软定义

如果行为类不存在,就像特质一样,会抛出 类未找到 错误。在某些情况下,您可能希望抑制此错误,以便在系统中存在模块时进行条件实现。您可以通过在类名开头放置一个 @ 符号来执行此操作。

class User extends \October\Rain\Extension\Extendable
{
    public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
}

如果类名 RainLab\Translate\Behaviors\TranslatableModel 不存在,则不会抛出错误。这相当于以下代码

class User extends \October\Rain\Extension\Extendable
{
    public $implement = [];

    public function __construct()
    {
        if (class_exists('RainLab\Translate\Behaviors\TranslatableModel')) {
            $controller->implement[] = 'RainLab.Translate.Behaviors.TranslatableModel';
        }

        parent::__construct();
    }
}

使用特质而不是基类

在某些情况下,您可能不想扩展 ExtensionBaseExtendable 类,因为其他需求。因此,您可以使用特质,尽管显然行为方法将不可用于父类。

  • 使用 ExtensionTrait 时,应将 ExtensionBase 的方法应用于类。

  • 使用 ExtendableTrait 时,应将 Extendable 的方法应用于类。