【问题标题】:Laravel extend Eloquent and 3rd party classLaravel 扩展 Eloquent 和 3rd 方类
【发布时间】:2015-02-23 22:14:18
【问题描述】:

我目前正在开发我的第一个 PHP/Laravel 4 项目,我正在开发一个存储类以将 Eloquent 支持添加到第三方库。

我的 EloquentStorage 类从库中扩展了 AbstractStorage 类,并且我使用了大部分 AbstractStorage 方法。现在我想为我的新 EloquentStorage 类添加 Eloquent 支持,我遇到了 PHP 不支持多重继承的事实。

是否有合适的方法来定义 Eloquent 模型而不将其扩展为:

class MyClass extends Eloquent {}

如果没有,当我需要扩展 3rd 方类并扩展 Eloquent 时,如何处理这种情况?也许使用 Laravel 的 IoC?

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    我认为您的模型应该从Eloquent 扩展,而是通过repository 访问。您的存储库可以有一个$storage 属性,并负责在您的AbstractStorage 实现上调用适当的方法。下面是伪代码而不是实际代码,但说明了您可以在哪里插入您的实现以进行更新操作。

    class MyClass extends Eloquent 
    {
        /* Normal Eloquent model implementation */
    }
    
    class MyRepository
    {
        protected $storage;
        protected $myClass;
    
        public function __construct(MyClass $myClass, AbstractStorage $storage)
        {
            $this->myClass = $myClass;
            $this->storage = $storage;
        }
    
        public function update($id, $data)
        {
            // This is just an example operation, basically here's your chance to call 
            // the 3rd-party implementation. Here is pre-eloquent update, but can be 
            // after
            $this->storage->update($id, $data);
    
            // Use the empty Eloquent class property instance to obtain an instance of 
            // the requested model
            $instance = $this->myClass->find($id);
            // set instance properties
            $instance->save();
    
            // Example post-eloquent update
            $this->storage->update($id, $data);
        }
    }
    
    class MyStorage extends AbstractStorage { /* Your Storage Implementation */ }
    
    $repo = new MyRepository(new MyClass, new MyStorage);
    // Update item id 42's foo property
    $repo->update(42, [ 'foo' => 'bar' ]);
    

    这种方法的一个好处是,存储库本身的构建可以通过服务提供者卸载到 IoC,并注入到控制器/表单验证器等内部,这意味着执行将变得自动并隐藏底层系统其余部分的第 3 方库的复杂性(存储库有助于保持您的第 3 方抽象来自 leaking)。

    另一个好处是,您的 eloquent 模型中不需要任何与您完全不相关的第 3 方代码有关的特殊代码。所有逻辑都封装在一个位置,甚至可以在多个模型之间共享。想要更换第三方供应商?编写AbstractStorage 的新实现,更新服务提供者即可。

    另一个好处是提高了可测试性。而不是直接静态地使用一个雄辩的模型(例如$user = User::find($id)),您将改为操作您的存储库对象($user = $this->repo->find($id))。由于可以简单地模拟您的存储库并对其自身进行测试(无需同时测试 Eloquent 或访问数据库),您可以在所有控制器路由上编写集成测试,并了解对代码库的更改破坏您的业务规则的时刻。

    【讨论】:

    • 这是很棒的方法,现在将尝试并返回结果。谢谢@Watcher
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多