主页/PHP笔记/PHP问答/框架Laravel/如何在Eloquent中定义和使用观察者

如何在Eloquent中定义和使用观察者

Bug编译狮

Bug编译狮

在 Laravel 中,观察者模式(Observer Pattern)是一种行为设计模式,用于将对象之间的依赖关系解耦,使得当一个对象的状态发生变化时,所有依赖于它的对象都会自动被通知并更新。Laravel 提供了内置的观察者机制,通过 EventObserver 接口来实现。

定义观察者

首先,你需要创建一个观察者类。这个类可以继承自 IlluminateContractsQueueShouldQueue 接口(如果需要异步处理),或者直接实现 IlluminateContractsSupportHtmlable 接口。

namespace AppObservers;

use IlluminateContractsQueueShouldQueue;
use IlluminateSupportFacadesLog;

class UserObserver implements ShouldQueue
{
    public function created($user)
    {
        Log::info('User created: ' . $user->name);
    }

    public function updated($user)
    {
        Log::info('User updated: ' . $user->name);
    }

    public function deleted($user)
    {
        Log::info('User deleted: ' . $user->name);
    }
}

注册观察者

接下来,你需要注册你的观察者到服务提供器中。你可以使用 EventServiceProvider 来实现这一点。

// app/Providers/EventServiceProvider.php

namespace AppProviders;

use IlluminateFoundationSupportProvidersEventServiceProvider as ServiceProvider;
use AppEventsUserCreated;
use AppEventsUserUpdated;
use AppEventsUserDeleted;
use AppObserversUserObserver;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        UserCreated::class => [
            UserObserver::class,
        ],
        UserUpdated::class => [
            UserObserver::class,
        ],
        UserDeleted::class => [
            UserObserver::class,
        ],
    ];

    protected $subscribe = [];

    public function boot()
    {
        parent::boot();

        // Registering the observer
        Event::subscribe(new UserObserver());
    }
}

使用事件

现在,你可以通过发布事件来触发观察者的回调方法。

// app/Http/Controllers/UserController.php

namespace AppHttpControllers;

use AppModelsUser;
use IlluminateHttpRequest;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $user = User::create([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
        ]);

        // Triggering the event
        event(new UserCreated($user));

        return redirect()->route('users.index');
    }

    public function update(User $user, Request $request)
    {
        $user->update([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
        ]);

        // Triggering the event
        event(new UserUpdated($user));

        return redirect()->route('users.show', $user->id);
    }

    public function destroy(User $user)
    {
        $user->delete();

        // Triggering the event
        event(new UserDeleted($user));

        return redirect()->route('users.index');
    }
}

示例代码

假设我们有一个简单的用户模型 User,并且我们希望在用户创建、更新或删除时记录日志。

// app/Models/User.php

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class User extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'email'];

    public static function boot()
    {
        parent::boot();

        // Registering the observer
        Event::subscribe(new UserObserver());
    }
}

在这个例子中,当我们创建、更新或删除一个用户时,相应的观察者方法会被调用,并在控制台输出日志信息。

通过这种方式,你可以轻松地在 Laravel 中实现观察者模式,从而提高代码的灵活性和可维护性。

黑板Bug讲师

黑板Bug讲师

介绍

在Laravel与Eloquent进行交互时,常常需要在模型生命周期的不同阶段执行某些操作,例如创建、更新或删除记录。Eloquent的观察者类提供了方便的方法来钩入这些生命周期事件,从而让你的代码保持整洁和可维护。本教程将通过一系列示例(从基础到高级)展示如何定义和使用Eloquent的观察者。

《基础篇》

一个Eloquent观察者类允许您定义方法来监听各种Eloquent事件。这些事件使您可以根据操作如创建、更新、保存、删除、恢复等在模型上执行操作。通过使用这些方法,您可以从您的模型中重构重复的代码,并确保应用架构中的关注点分离。

定义一个Eloquent观察者

<?php

namespace AppObservers;

use AppModelsUser;

class UserObserver
{
    public function creating(User $user)
    {
        // Logic before a user record is created
    }

    public function created(User $user)
    {
        // Logic after a user record is created
    }

    // Other model events...
}

注册一个eloquent观察者

为了注册观察者,通常会在你的服务提供程序的 boot 方法内进行操作,通常是 AppServiceProvider。你可以使用 observe 方法来绑定观察者类到模型上。

<?php

namespace AppProviders;

use IlluminateSupportServiceProvider;
use AppModelsUser;
use AppObserversUserObserver;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        User::observe(UserObserver::class);
    }
}

观察者方法

您可以定义观察者方法:

修复了

恢复

删除了。

删除

保存了。

节省

更新了。

更新中

创建成功了。

创建

已获取到信息。

自动时间戳

该示例展示了如何自动为自定义字段设置时间戳,每当记录保存或更新时。 在进行项目开发时,经常会遇到各种需求,比如:需要获取到某个用户的登录时间和退出时间;对某一个商品的销售数据进行统计分析等。为了方便地处理这些情况,我们可以使用SQL语句中的DUAL表来进行操作。例如,如果我们要查询当前用户登录的时间和退出时间,可以编写如下代码: SELECT login_time, logout_time FROM DUAL WHERE user_id = 1; 这里的login_time和logout_time就是我们想要的结果,它们分别代表了当前用户的登录时间和退出时间。这样,我们就能够轻松地获取到我们需要的数据。 另外,在进行数据库操作时,有时候会涉及到一些复杂的逻辑判断或者条件匹配。这时候,就可以利用SQL的CASE WHEN结构来实现。例如,假设我们有一个名为orders的表,其中包含了一些订单信息,包括订单金额、订单状态等。如果我们想要根据订单的状态来调整订单金额,就可以使用如下的SQL语句: UPDATE orders SET amount *= CASE WHEN status = ‘completed’ THEN 1.25 ELSE 1 END WHERE order_id = 1; 在这个例子中,我们首先通过CASE WHEN结构来判断订单的状态是否为“完成”。如果是“完成”,那么我们将订单金额乘以1.25;否则,保持原样不变。最后,我们在WHERE子句中指定要修改的订单ID为1。这样,我们就实现了根据订单状态调整订单金额的功能。 总的来说,SQL语言作为一种强大的工具,为我们提供了许多便捷的操作方法。只要掌握好SQL的基本语法和常用函数,就能够轻松解决很多实际问题。

<?php

namespace AppObservers;

use AppModelsPost;

class PostObserver
{
    public function saving(Post $post)
    {
        $post->last_action_at = now();
    }
}

在你的 AppServiceProvider 中,你应该将这个观察者附加到 Post 模型上:

<?php

namespace AppProviders;

use AppModelsPost;
use AppObserversPostObserver;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Post::observe(PostObserver::class);
    }
}

高级观测者使用方法

依赖注入(Dependency Injection,DI)是一种设计模式和开发实践,它通过集中管理对象之间的依赖关系来简化代码的构建和维护。在这种模式下,依赖关系不是在类内部直接定义的,而是由外部提供者通过接口或构造函数参数传递过来。这样做的好处是可以使系统更加灵活、易于测试以及更容易进行重构。

观察者也可以通过依赖注入接收依赖项。例如,如果你需要在用户注册后发送电子邮件,你可以向观察者中注入邮件服务。

<?php

namespace AppObservers;

use AppModelsUser;
use IlluminateMailMailer;

class UserObserver
{
    protected $mailer;

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

    public function created(User $user)
    {
        // Send email...
    }
}

使用观察者模式与队列相结合

如果你需要执行耗时的任务,比如发送电子邮件,你应该排队这些任务以使应用程序更响应。以下是如何在观察者方法内排队邮件工作的示例。

<?php

namespace AppObservers;

use AppJobsSendWelcomeEmail;
use AppModelsUser;

class UserObserver
{
    public function created(User $user)
    {
        dispatch(new SendWelcomeEmail($user));
    }
}

注意事项和考虑事项

观察者可以提高代码的可维护性,但也会引入一层间接性,这可能会使代码更难以追踪。在使用观察者时,请务必考虑其潜在的递归问题,例如当一个观察者无意中触发另一个事件时。

结论

观察者模式在Eloquent框架下为Laravel应用程序提供了优雅的模型生命周期事件处理方式。它们易于实现,如果适当使用,可以导致更可维护和扩展性强的代码。正如任何设计模式一样,正确使用它们以充分受益至关重要。

长工码奴1523

长工码奴1523

在 Laravel 的 Eloquent 模型库中,你可以通过 observe 方法来定义观察者(Observer)。观察者是一种监听器,当模型的属性改变时,它们会收到通知并执行相应的操作。

以下是如何在 Eloquent 中定义和使用的观察者的示例:

  1. 首先,你需要创建一个新的类,并重写 observe 方法,该方法接收两个参数:一个是观察对象,另一个是观察事件。
use IlluminateSupportFacadesEvent;

class MyModel extends Model {
    protected $table = 'my_table';

    public function observe($observer, $event)
    {
        if ($event == 'created') {
            Event::fire('MyEvent', [
                'model' => $this,
            ]);
        }
    }
}
  1. 然后,你需要在控制器或其他需要的地方调用观察者的方法,这将触发事件,并在观察者处理完成后返回响应。
$my_model = new MyModel();

$my_model->observe(function ($observer) {
    // 在这里添加你的逻辑
});

// 或者更简单的方式,直接在事件处理器中进行处理
$my_model->observe(new MyEventHandler());
  1. 观察者可以处理各种事件,例如:
  • 'created': 当某条记录被创建时。
  • 'updated': 当某条记录被更新时。
  • 'deleted': 当某条记录被删除时。
  • 'restored': 当某条记录从回收站恢复时。
  • 'forceDeleted': 当某条记录强制被删除时。
  1. 为了确保观察者正确地处理事件,你应该检查 $event 参数是否与预期相符,或者根据需要对 $observer 实例进行一些额外的操作。

以上就是在 Laravel Eloquent 中定义和使用观察者的简要教程。