Any way to dispatch a closure in laravel 5?

十年热恋 提交于 2021-01-27 07:13:57

问题


In laravel 4, I could push a closure onto the queue with queue::push(function...), but this no longer works in laravel 5. Instead, it appears that I have to make a custom Job class for every function that I want to push onto the queue.

Since the functions I want to be pushing are only a couple of lines long, and are only ever used in exactly one place, it really seems like a waste of time and space to be writing up a full class for every case.

The best "solutions" I can currently think of, are to either have a helper function that uses PHP's reflection methods to dynamically generate a new class when called, or to have generic job that accepts a closure as parameter, i.e. dispatch(new ClosureJob(function(){...}));

These seem less than ideal to me. Is there another way to do this? Or am I going to have to implement one of these?


回答1:


I've accomplished this by relying on the OpisClosure library. Extend the class as so:

class QueueableClosure extends SerializableClosure
{
    public function handle() {
        call_user_func_array($this->closure, func_get_args());
    }
}

Then use it like this:

Queue::push(new QueueableClosure(function(){
    Log::debug("this is the QueueableClosure in action.");
}));

N.B. See the comment below from @Quezler about possible limitations!




回答2:


https://laravel.com/docs/5.0/queues#queueing-closures says:

You may also push a Closure onto the queue. This is very convenient for quick, simple tasks that need to be queued:

Pushing A Closure Onto The Queue

Queue::push(function($job) use ($id)
{
    Account::delete($id);

    $job->delete();
});

However, my guess is that you're using Laravel 5.3+, because https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0 says:

Queueing Closures is no longer supported. If you are queueing a Closure in your application, you should convert the Closure to a class and queue an instance of the class.




回答3:


As of Laravel v5.7 you can queue an closure like this:

$podcast = App\Podcast::find(1);

dispatch(function () use ($podcast) {
    $podcast->publish();
});

Docs: https://laravel.com/docs/7.x/queues#queueing-closures

However it is strongly recommended to use a dedicated job class to improve your code quality and for the sake of a better maintenance of your application. Think of you want to check what tasks are left in queue, or want to control on which queue/connection the particular code should run at.

Therefore you need a dedicated job class: https://laravel.com/docs/5.7/queues#creating-jobs

I'd say that writing a dedicated class is pretty much the Laravel standard and this is what you should align to.



来源:https://stackoverflow.com/questions/44409007/any-way-to-dispatch-a-closure-in-laravel-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!