Laravel队列不允许序列化“关闭” [英] Laravel queue Serialization of 'Closure' is not allowed
问题描述
我需要帮助来使用Laravel调度作业,似乎系统在尝试使用队列作业时会尝试序列化关闭操作,因此会出现此错误。
I need help to dispatch a job with Laravel, seems the system try to serialize a closure when using queue job so there's this error.
如何解决此问题问题?我也尝试过此软件包
https://github.com/jeremeamia/super_closure
,但在我的情况下不起作用。
How can I fix this problem? I also tried this package
https://github.com/jeremeamia/super_closure
but it doesn't work in my case.
这是我的代码:
在控制器FacebookController中:
In the controller FacebookController:
public function getPosts(\SammyK\LaravelFacebookSdk\LaravelFacebookSdk $fb) //get all post of logged user
{
dispatch(new SyncFacebook($fb));
}
要分派的工作:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Session, DB, Carbon\Carbon, Auth;
use App\{
User, Reaction, Post, Synchronisation
};
class SyncFacebook implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $fb;
public function __construct($fb)
{
$this->fb = $fb;
}
public function handle()
{
set_time_limit(0);
$user = Auth::user();
try {
$response = $this->fb->get('/me/posts?limit=100', session('fb_user_access_token'));
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
dd($e->getMessage());
}
$postEdge = $response->getGraphEdge();
if(count($postEdge) > 0){
$pageCount = 0;
$maxPages = 9000000000000000000;
DB::beginTransaction();
try{
do{
foreach ($postEdge as $result) {
$result = $result->asArray();
$post_id = $result['id'];
$post = Post::where('post_id', $post_id)->first() ?: new Post;
$post->post_id = $post_id;
$post->user_id = $user->id;
$post->timezone = collect($result['created_time'])->toArray()['timezone'];
$post->post_date = collect($result['created_time'])->toArray()['date'];
$post->content = $result['message'] ?? $result['story'] ?? '';
$post->save();
$req = !empty(Synchronisation::whereUserId($user->id)->orderBy('id','desc')->date) ?
$post_id.'/reactions?limit=100&summary=total_count&since'.time(Synchronisation::whereUserId($user->id)->orderBy('id','desc')->date) :
$post_id.'/reactions?limit=100&summary=total_count';
try {
$response = $this->fb->get($req, session('fb_user_access_token'));
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
dd($e->getMessage());
}
$reactionEdge = $response->getGraphEdge();
$total_reactions = $reactionEdge->getMetaData()['summary']['total_count'] ?? null;
//dd($total_reactions);
$post->total_reactions = $total_reactions;
$post->save();
if(count($reactionEdge)){
$pagesReactionCount = 0;
do{
foreach($reactionEdge as $react){
$react = $react->asArray();
$reaction = Reaction::where('reaction_id', $react['id'])->first() ?: new Reaction;
$reaction->type = $react['type'];
$reaction->reaction_id = $react['id'];
$reaction->post_id = $post->id;
$reaction->author = $react['name'];
$reaction->save();
}
$pagesReactionCount++;
}
while($pagesReactionCount < $maxPages && $reactionEdge = $this->fb->next($reactionEdge));
}
}
$pageCount++;
}
while ($pageCount < $maxPages && $postEdge = $this->fb->next($postEdge));
$synchro = new Synchronisation;
$synchro->user_id = $user->id;
$synchro->date = now();
$synchro->completed = true;
$synchro->save();
}
catch(ValidationException $e){
DB::rollback();
if(env('APP_ENV') != 'production'){
dd($e->getMessage());
}
}
DB::commit();
}
else{
//no post
}
}
}
似乎错误在于 $ this-> fb = $ fb;
//的序列化
It seems the error is on the constructor at $this->fb = $fb;
// Serialization of 'Closure' is not allowed
推荐答案
我的理解是,由于Laravel赢得了胜利,您不能在Job中包含不可序列化的变量
My understanding is that you can't include non-serializable variables in the Job, as Laravel won't know how to deal with them when storing the job details.
因此,您需要删除 $ fb
从 construct()
方法和相关的受保护的$ fb;
和 $ this-> ; fb = $ fb;
行。
So you need to remove the $fb
from the construct()
method and the associated protected $fb;
and $this->fb = $fb;
lines.
相反,您有两个选择
1)简单
在您的<$ c $中创建一个新的 \SammyK\LaravelFacebookSdk\LaravelFacebookSdk
对象c> handle()方法,例如
Create a new \SammyK\LaravelFacebookSdk\LaravelFacebookSdk
object in your handle()
method, e.g.
public function handle() {
$fb = new \SammyK\LaravelFacebookSdk\LaravelFacebookSdk;
'.... replace all $this->fb with $fb
}
2)高级
如果您需要传递之前使用的特定FB实例,请注册 FacebookSDK
服务提供商和将其注入处理程序中,如文档所示。
If you need to pass the specific FB instance you used before, register a FacebookSDK
Service Provider and inject it into the handler as seen in the docs.
Eg
public function handle(FacebookSDK $fb) {
'.... replace all $this->fb with $fb
}
注册时绑定服务 handle()
方法中的这种类型提示会自动检索$ fb实例并将其注入准备使用的方法中。您可以确定是每次创建一个新的FacebookSDK对象,还是仅创建一个并始终使用该对象(称为Singleton)。
When you register bind the service container for your Facebook SDK, this type-hinting in the handle()
method automatically retrieves the $fb instance and injects it into the method ready for use. You can determine whether to create a new FacebookSDK object each time, or just create one and always use that one (known as a Singleton).
这篇关于Laravel队列不允许序列化“关闭”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!