如何使用Laravel

时间:2016-04-08 14:02:45

标签: php laravel laravel-5.1

Laravel 5.1

我正在尝试为扩展我的AbstractModel的每个模型注册一个模型观察者(他们正在扩展Illuminate \ Database \ Eloquent \ Model)。

问题是我的GenericModelObserver无法侦听继承AbstractModel的模型触发的事件。

让我展示一下我到目前为止做了什么。

创建了一个服务提供程序,并将其放在config / app.php

中的providers数组的最后一个位置
<?php

// app/Providers/ObserverServiceProvider.php

namespace App\Providers;

use App\Models\Quotation;
use App\Models\AbstractModel;
use App\Observers\QuotationObserver;
use App\Observers\GenericModelObserver;
use Illuminate\Support\ServiceProvider;

class ObserverServiceProvider extends ServiceProvider
{

    public function boot()
    {
        AbstractModel::observe(GenericModelObserver::class);
        Quotation::observe(QuotationObserver::class);
    }

    public function register()
    {

    }
}

然后我有简单的GenericModelObserver

<?php

// app/Observers/GenericModelObserver.php

namespace App\Observers;

use App\Models\AbstractModel;

class GenericModelObserver
{
    public function saving(AbstractModel $model)
    {
        return $model->valid();
    }
}

抽象模型

<?php

// app/Models/AbstractModel.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class AbstractModel extends Model
{
    // ...
}

我的报价模型

<?php

// app/Models/Quotation.php

namespace App\Models;

class Quotation extends AbstractModel
{
    // ...
}

保存报价时,GenericModelObserver无法收听保存事件或任何其他事件。

这同样适用于没有特定模型观察者的其他模型。

这是正确的策略吗?我不想通过引导方法将观察者绑定到每个模型。

5 个答案:

答案 0 :(得分:3)

而不是扩展模型 - 编写自己的特征,作为观察者 下面我写了一些基本特征:

<?php

namespace App\YourPackage\Traits;

use Illuminate\Database\Eloquent\Model;

trait Observable
{
    public static function bootObservable()
    {
        static::updating(function (Model $model) {
            dd('updating');
        });
    }
}

并在模型类中键入use Observable;来使用它。

同样为了您的学习,请记录特征是如何启动的:您必须将boot[TraitClassName]方法置于特征中,才能正确启动。
永远不要在你的特质中写boot方法,这很危险!

答案 1 :(得分:2)

为什么不简单地扩展父类说List

我的缓存系统中有类似内容

BaseObserver

然后在<?php namespace App\Observers; class BaseObserver { public function saving($model) { //do your thing here that apply to all observers, like caching } }

Observers

答案 2 :(得分:0)

在您的父模型中,您可以执行类似的操作

/**
 * If true will attach the observers of the parent class
 * @var bool
 */
protected $shouldAttachParentObservers = true;

public static function boot()
{
    $instance = new static;
    $instance->attachParentObservers();

    parent::boot();
}


public function attachParentObservers() {
    $parentClass = get_parent_class($this);
    if(!empty($parentClass) && $this->shouldAttachParentObservers) {
        $eventObservers = [];
        foreach ($this->getObservableEvents() as $event) {
            $eventObservers[$event] = ($this::$dispatcher->getListeners("eloquent.{$event}: {$parentClass}"));
            foreach ($eventObservers[$event] as $observer) {
                $eventName = "eloquent.{$event}: {$this::getClassName()}";
                $this::$dispatcher->listen($eventName, $observer);
            }
        }
    }
}
/**
 * You may use different way to find the class name
 */
public static function getClassName() {
    return static::class;
}

答案 3 :(得分:0)

boot中的AppServiceProvider方法更新为以下内容:

public function boot()
{
    # Register all model observers
    $filesInFolder = \File::files(app_path('/Observers'));

    foreach($filesInFolder as $path) {
        $observerClassName = pathinfo($path)['filename'];
        $className = str_replace('Observer', '', $observerClassName);
        $observerClassName = 'App\\Observers\\' . $observerClassName;
        $className = 'App\\' . $className;
        $className::observe($observerClassName);
    }
}

模型应遵循以下格式:

App\User

观察者应遵循以下格式:

App\Observers\UserObserver

答案 4 :(得分:0)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Observers\TeamObserver;

class Team extends Model
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        self::observe(TeamObserver::class);
    }
}