我是 php 和 laravel 的新手,我试图在创建一个模型时分派一项作业,但是 当我尝试分派该作业时,我收到错误“不允许序列化‘闭包’” ,这让我感到困惑,因为我认为我需要传入一个匿名函数才能得到该错误。
我有一个观察者来监视我的订单模型创建的事件。
<?php
namespace App\Observers;
use App\Models\Order;
use App\Jobs\CreateOrderTasks;
class OrderObserver
{
/**
* Handle the Order "created" event.
*/
public function created(Order $order): void
{
CreateOrderTasks::dispatch($order);
}
...etc
}
我有我的工作
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use App\Models\Order;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class CreateOrderTasks implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected Order $order;
public function __construct(Order $order)
{
$this->order = $order;
}
/**
* Execute the job.
*/
public function handle(): void
{
Log::info('Order retrieved:', ['order' => $this->order]); // Log the order details
}
}
我还尝试过仅传递订单 ID 并更新作业,例如
CreateOrderTasks::dispatch($order->id);
但我仍然遇到同样的错误。我做错了什么?
当正在序列化的数据中存在无法序列化的内容(例如闭包、资源或其他一些不可序列化的内容)时,Laravel 中经常会出现您遇到的错误“不允许序列化‘Closure’”数据结构。就您而言,由于您正在使用 Eloquent 模型调度作业,因此您应该验证并考虑以下几点来解决此问题:
您使用的
SerializesModels
特征旨在处理 Eloquent 模型的序列化。它在序列化之前将模型转换为其主键,然后在处理作业时从数据库重新检索它们。但是,有一些注意事项:
$order
模型有任何未加载的关系,它们可能无法正确序列化。确保模型中没有不可序列化的属性。闭包、流或资源等属性无法序列化。
如果您仍然遇到问题,仅传递模型 ID 是一种安全的方法。但是,请确保您随后在作业的
handle
方法中检索模型:
// In your observer
public function created(Order $order): void
{
CreateOrderTasks::dispatch($order->id);
}
// In your job
use App\Models\Order;
public function __construct(int $orderId)
{
$this->orderId = $orderId;
}
public function handle(): void
{
$order = Order::find($this->orderId);
if ($order) {
Log::info('Order retrieved:', ['order' => $order->toArray()]);
} else {
Log::warning('Order not found:', ['orderId' => $this->orderId]);
}
}
有时,中间件或事件监听器可能使用闭包或不可序列化的数据。确保没有中间件或事件侦听器使用可能间接导致问题的闭包。
为了更好地了解可能导致序列化问题的原因,您可以:
确保您的队列系统配置正确。例如,如果您使用数据库队列,请确保迁移是最新的并且数据库设置正确。
该错误通常是由于尝试序列化 PHP 无法序列化的内容而引起的。通过确保模型配置正确、仅传递必要的数据并检查任何闭包或不可序列化的属性,您应该能够解决此问题。如果您仍然遇到问题,请考虑查看 Laravel 关于队列和作业的文档以获取更多见解,或咨询 Laravel 社区论坛以获取更细致的调试技巧。