在Laravel上使用模型的全局事件

时间:2015-08-25 17:59:53

标签: php laravel events eloquent

基本上我需要的是:如果我项目中的任何模型行已创建已更新已删除,我需要调用一个回调来处理这个模型行。我将使用它来创建其他模型中的更改日志,这不会触发此全局事件以避免循环。

我试过这样设置:

Model::creating($callback);

但它没有奏效。仅当我将其直接设置为我拥有的所有模型时才能工作。这很糟糕,因为我需要逐个具体。如果我创建一个新的,我需要手动指定它。例如:

User::creating($callback);
Company::creating($callback);
...

任何更改都将记录在另一个名为Log的模型上。它不会触发此$callback,因为它会在表logs上注册(由Log管理)其他模型中的每次更改。类似的东西:

$user = new User;
$user->name = "John";
$user->age = 18;
$user->save();

$user->name = "John Doe";
$user->save();

$user->delete();
$user->restore();
$user->forceDelete();

我会注册以下内容:

id | object_type | object_id | event_type | object_data
..   App\User      1           created      { name: John, age: 18 }
..   App\User      1           updated      { name: John Doe }
..   App\User      1           trashed      null
..   App\User      1           restored     null
..   App\User      1           removed      null

2 个答案:

答案 0 :(得分:2)

所有Eloquent模型事件的格式均为eloquent.event:ClassName

您可以订阅eloquent.*个活动。     Event :: listen(' eloquent。*',function($ model){});

然后,您可以检查当前模型是否为日志模型(在这种情况下,您直接从return true出来以避免无限递归),否则,将更改保存到日志模型中。< / p>

答案 1 :(得分:2)

  

Laravel 5.1

基本特征:

public void CollapseTree(Employee employee, int maxSize)
    {
        int size = 0;
        Queue<Employee> queue = new Queue<Employee>();
        queue.Enqueue(employee);
        employee.isVisited = true;
        size++;

        while (queue.Count > 0)
        {
            // Dequeue the employee
            Employee emp = queue.Dequeue();

            foreach (Employee report in emp.Directs)
            {
                // Check if we already visited this node
                if (!report.isVisited)
                {
                    queue.Enqueue(report);
                    report.isVisited = true;
                    size++;

                    // If we reached maximum size, then exit
                    if (size == maxSize)
                    {
                        return;
                    }
                }
            }
        }
    }

    public class Employee
    {
        public HashSet<Employee> Directs { get; set; }

        public string Name { get; set; }

        public int TotalDirects { get; set; }

        public int TotalReports { get; set; }

        public bool isVisited { get; set; }

        public Employee(string name)
        {
            this.Name = name;
            this.Directs = new HashSet<Employee>();
        }
    }
}

基本型号:

traint BaseTraint {
    public static function bootBaseTrait()
    {

        static:creating(function($item){
            ....
        });
        static:updating(function($item){
            ....
        });
    }
    //it binds the events in **bootBaseTrait** to any subclass
    //base run first, then run your subclass's events if you defined on the subclass
}

XXX型号:

use XX\XX\BaseTrait;
use Illuminate\Database\Eloquent\Model;
class Base extends Model {
    use BaseTrait;
}

这是如何运作的?

你可以看到/ vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php

  

protected static function bootTraits()

该方法尝试调用&#34; bootTraitName &#34;当你使用特质时!