Laravel队列不允许序列化“关闭” [英] Laravel queue Serialization of 'Closure' is not allowed

查看:75
本文介绍了Laravel队列不允许序列化“关闭”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助来使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆