Laravel4 / PHP模型(或任何东西)扩展了多个类

时间:2014-02-20 20:21:36

标签: php oop laravel laravel-4

我找到了一些扩展Eloquent功能的有用软件包,例如:Sentry,Revisionable。 现在我明白你不能扩展多个类,并且有些方法可以作为代理,或者只是以某种方式使用另一个类作为属性。

创建受益于多个包的模型的最佳做法是什么?

1 个答案:

答案 0 :(得分:5)

我们有一些选择:

依赖注入:

use ExternalClass;

class Model extends Eloquent {

    private $external;

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

    public function doWhatever() 
    {
        return $this->external->do();
    }

    public function __call($name, $arguments)
    {
        return call_user_func_array(array($this->external,$name), $arguments);
    }
}

您不必将类传递给模型,Laravel将尝试实例化并为您注入该类。

修改

你不必重写所有方法,看看这个神奇的方法__call?每次在您的类中找不到方法时,它将由PHP自动触发,因此您可以使用它将该调用转发给您的外部类。

<强>最终修改

特征:(这是PHP 5.4 +)

class Model extends Eloquent {

    use MyTraits;

    public function doWhatever() 
    {
        return $this->do();
    }
}

trait MyTraits {

    public function do()
    {
        /// this metho will be available in your class 
    }

}

您还可以使用存储库模式:

class DataRepository {

    private $user;

    private $external;

    public function __construct(User $user, ExternalClass $external)
    {
        $this->user = $user;

        $this->external = $external;
    }

    public function allUsers() 
    {
        return $this->user->all();
    }

    public function doWhatever() 
    {
        return $this->external->do($this->user);
    }
}

还有一些其他人,但你的项目真正告诉你什么是最好的。

修改

请注意,您必须了解__call魔术方法,因为Laravel还使用它来提供动态方法,例如whereColumnname(),并且您可能会因使用它而面临破坏。但这也是你可以通过更多代码来规避的事情:

public function __call($name, $arguments)
{
    // If the method is not one of your package ones, try execute an Eloquent (parent) one

    if ( ! in_array($name, ['methodA', 'methodB', 'methodC']))
    {
        return parent::__call($name, $arguments);
    }
    else
    {
        return call_user_func_array(array($this->external,$name), $arguments);
    }
}