问题
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