1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel JobにClosureを渡して実行させたくない?

Posted at

Laravel Jobのコンストラクタ引数にクロージャを渡す方法

LaravelのJobを利用する際に、コンストラクタの引数としてクロージャを渡したいと思ったことはありませんか?通常の方法ではクロージャはシリアライズできないためエラーになりますが、シリアライズ可能なクロージャを使えば、この問題を解決できます。

本記事では、Job実行中にクロージャを活用する方法を解説します。

問題: クロージャをそのまま渡せない

LaravelのJobクラスでは、コンストラクタに渡されたデータはシリアライズされ、Queueに保存されます。しかし、PHPの標準クロージャはシリアライズできないため、エラーが発生します。

エラー例

class MyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $closure;

    public function __construct(\Closure $closure)
    {
        $this->closure = $closure;
    }

    public function handle(): void
    {
        ($this->closure)();
    }
}

// Dispatchする
MyJob::dispatch(function () {
    echo 'This is a test.';
});

このコードを実行すると、次のようなエラーが発生します。

Serialization of 'Closure' is not allowed

解決策: クロージャのシリアライズ対応

opis/closureパッケージを利用すると、シリアライズ可能なクロージャを作成できます。

必要なパッケージのインストール

まず、opis/closureパッケージをインストールします。

composer require opis/closure

Jobクラスの修正

SerializesModelsトレイトとSerializableClosureを活用して、Jobクラスを修正します。

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Opis\Closure\SerializableClosure;

class MyJob implements ShouldQueue
{
    use Dispatchable, Queueable

    public $closure;

    public function __construct(\Closure $closure)
    {
        $this->closure = new SerializableClosure($closure);
    }

    public function handle(): void
    {
        // クロージャを実行
        ($this->closure)();
    }
}

実行例

上記の修正後、次のようにクロージャを渡してJobをDispatchできます。

use App\Jobs\MyJob;

MyJob::dispatch(function () {
    echo 'Job実行中にこのクロージャが実行されます!';
});

Queueが処理されると、以下の出力が得られます。

Job実行中にこのクロージャが実行されます!

注意点

  • セキュリティ: クロージャをシリアライズしてQueueに保存するため、信頼できるコードのみを扱うようにしてください
  • 依存関係: クロージャ内で外部変数やサービスコンテナへの依存がある場合などはどうなんでしょうね

まとめ

LaravelのJobでクロージャを扱うには、opis/closureを利用してシリアライズ可能なクロージャを作成できます。皆様のエレガントな抽象化を祈念いたします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?