【问题标题】:How do i nicely decode Laravel failed jobs JSON我如何很好地解码 Laravel 失败的作业 JSON
【发布时间】:2017-03-01 13:19:29
【问题描述】:

我应该如何解码和“美化” Laravel 的失败作业负载?

在我的数据库中,在 failed_jobs 表中,我的列有效负载如下所示:

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"commandName":"App\\Jobs\\createHostingOncPanel","command":"O:30:\"App\\Jobs\\createHostingOncPanel\":7:{s:10:\"\u0000*\u0000orderNo\";i:11;s:18:\"\u0000*\u0000hostingPackages\";s:45:\"[{\"domainName\":\"qwddqwd.io\",\"hostingType\":1}]\";s:7:\"\u0000*\u0000user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":2:{s:5:\"class\";s:8:\"App\\User\";s:2:\"id\";i:1;}s:10:\"connection\";N;s:5:\"queue\";N;s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}}

希望将字符串 json 解码为可读的内容。

这是什么格式? :)

PS:这是一个 Laravel 5.2 版本

【问题讨论】:

  • 你已经说过它是什么格式:json。所以使用 json_decode()... 在那个 json 中,似乎有一个 php serialize() 数据结构,它本身必须是 unserialized()

标签: php laravel queue laravel-5.2


【解决方案1】:

我建议在事件发生时处理事件,然后以自己的方式存储您需要的任何数据。您可以使用 Failed Job Events 来捕获所有失败的作业:https://laravel.com/docs/master/queues#failed-job-events

或者您可以在作业本身上使用failed() 函数:https://laravel.com/docs/master/queues#dealing-with-failed-jobs

否则,Marc 的评论对我来说似乎很有意义。

【讨论】:

  • 我已经尝试从 AppServiceProvider 拦截失败的作业。
  • 该死的输入 :) 仍然得到这个字符串: string(320) "O:30:"App\Jobs\createHostingOncPanel":7:{s:10:"\000*\000orderNo";i :18;s:18:"\000*\000hostingPackages";s:47:"[{"domainName":"fireman21.nu","hostingType":3}]";s:7:"\000*\ 000user";O:45:"Illuminate\Contracts\Database\ModelIdentifier":2:{s:5:"class" ;s:8:"App\User";s:2:"id";i:1; }s:10:"connection";N;s:5:"queue";N;s:5:"delay";N;s:6:"\000*\000job";N;}" 也给了json_decode 和反序列化一去,没有运气
【解决方案2】:

从 failed_jobs 表中读取

json_decode 来自 failed_jobs 表的负载

$jsonpayload = json_decode($payload);

反序列化有效负载命令

$data = unserialize($jsonpayload->data->command);
print_r($data);//This is the data passed to queue

【讨论】:

  • 这绝对应该在 Laravel 文档中!谢谢楼主,很有价值的信息
  • @MikeHarrison 我知道这是“旧的”,但这不是一个正确的答案,我的意思是,这可行,但这并不意味着它是最好的......@Jeff 回答正确最好的答案,你现在处理异常,而不是稍后被解码,或者如果你想这样做,你在你的数据库中存储一些新的东西,你不再使用 unserializejson_decode 等在 Laravel ...如果您必须在普通 Laravel(不是包)中使用其中一些功能,那么这意味着您正在使用它或做错了什么...您避免使用普通 PHP 100%...
  • @matiaslauriti 我没有发布答案......但是我会说有时知道如何在失败的工作发生后如何与它们互动很重要,所以这个答案仍然有用
  • 我同意你最后的说法,但我不同意这种方式。您在documentation 上有专门讨论此问题的部分。你没有unserialize 任何东西,你现在处理它。创建一个新模型或任何可以帮助您跟踪失败的工作的东西,但您不会 unserialize 它并用它做任何事情......您的建议类似于继续使用 $_POST 或任何类似的东西,当您应该使用request...这是一个框架,可以处理所有事情...不需要做这些洞穴的东西...
【解决方案3】:

试试这个

$j = App\Models\Jobs::select('payload')->get();
$aw = json_decode($j[0]->payload)->data->command;
$cm = unserialize($aw);
dd($cm->payload);

【讨论】:

    【解决方案4】:

    我也遇到了问题,因为我无法直接访问生产数据库。 我用 auth 创建了一个路由,我的控制器返回了 json,所有失败的作业都格式化了。这是控制器代码。有了这个,我还能够获得格式化的异常堆栈跟踪,因为哪个作业失败了

        public function getFailedJob()
        {
            #Fetch all the failed jobs
            $jobs = DB::table('failed_jobs')->select()->get();
    
            #Loop through all the failed jobs and format them for json printing
            foreach ($jobs as $job) {
                $jsonpayload = json_decode($job->payload);
                $job->payload = $jsonpayload;
    
                $jsonpayload->data->command = unserialize($jsonpayload->data->command);
                $job->exception  = explode("\n", $job->exception);
            }
    
            return response()->json($jobs);
        }
    

    【讨论】:

      【解决方案5】:

      我认为最好在工作失败时处理它。但如果你想要一个懒惰、顽固的解决方法,你可以这样做。 unserialize 的问题在于它隐藏了受保护的属性,但公共属性返回为null

      创建一个特征ExposeJobComands

      <?php
      
      namespace App\Traits;
      
      trait ExposeJobComands {
      
          public function getAllVars()
          {
              return get_object_vars($this);
          }
      }
      

      让所有工作都使用这个特性。 创建自定义演员Payload

      <?php
      
      namespace App\Casts;
      
      use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
      class Payload implements CastsAttributes
      {
          public function get($model, $key, $value, $attributes)
          {
              $payload = json_decode($value);
              $command = unserialize($payload->data->command);
              $payload->data->command = $command->getAllVars();
      
              return $payload;
          }
      }
      

      为失败的作业创建模型并将有效负载转换为Payload::class

      <?php
      
      namespace App\Models;
      
      use App\Casts\Payload;
      use Illuminate\Database\Eloquent\Model;
      
      class FailedJob extends Model
      {
          protected $casts = [
              'payload' => Payload::class,
          ];
      }
      

      【讨论】:

        猜你喜欢
        • 2021-07-25
        • 1970-01-01
        • 2016-04-01
        • 1970-01-01
        • 2014-11-19
        • 1970-01-01
        • 1970-01-01
        • 2020-01-18
        • 1970-01-01
        相关资源
        最近更新 更多