Laravel:无法JSON编码有效负载。错误代码:5

问题描述 投票:0回答:1

我正在使用Laravel(v5.7)应用程序,该应用程序将上传的CSV(带有联系人)转换为数组,然后在调度作业类时将其作为参数传递。

这里是CSV文件(支持的格式)的示例:

123456,Richard,Smith
654321,John,Doe

上传的(CSV)文件是这样处理的:

$file_path = $request->file_name->store('contacts');
$file = storage_path('app/' . $file_path);

$contactsIterator = $this->getContacts($file);

$contacts = iterator_to_array($contactsIterator); // Array of contacts from uploaded CSV file
    protected function getContacts($file)
    {
        $f = fopen($file, 'r');

        while ($line = fgets($f))
        {
            $row = explode(",", $line);

            yield [
                'phone'     => !empty($row[0]) ? trim($row[0]) : '',
                'firstname' => !empty($row[1]) ? trim($row[1]) : '',
                'lastname'  => !empty($row[2]) ? trim($row[2]) : '',
            ];
        }
    }

最后,$contacts数组传递到已分派的作业:

ImportContacts::dispatch($contacts);

此工作类别如下:

    public function __construct($contacts)
    {
        Log::info('ImportContacts@__construct START');
        $this->contacts = $contacts;
        Log::info('ImportContacts@__construct END');
    }

    public function handle()
    {
        Log::info('ImportContacts@handle');
    }

...并且一切正常,直到我尝试使用此CSV为止(没有错误):

123456,Richardÿ,Smith
654321,John,Doe

请注意ÿ。因此,当我尝试使用此CSV时-出现此错误异常:

/code_smsto/vendor/laravel/framework/src/Illuminate/Queue/Queue.php | 91 | Unable to JSON encode payload. Error code: 5 

...而且我的日志文件如下所示:

  error local   2019-11-11 17:17:18     /code_smsto/vendor/laravel/framework/src/Illuminate/Queue/Queue.php | 91 | Unable to JSON encode payload. Error code: 5
  info  local   2019-11-11 17:17:18     ImportContacts@__construct END
  info  local   2019-11-11 17:17:18     ImportContacts@__construct START 

您可以看到-从未执行过handle方法。如果删除ÿ-没有错误,则执行handle

我试图解决这个问题,但没有成功:

  1. 应用utf8_encode
    protected function getContacts($file, $listId)
    {
        $f = fopen($file, 'r');

        while ($line = fgets($f))
        {
            $row = explode(",", $line);

            yield [
                'phone'     => !empty($row[0]) ? utf8_encode($row[0]) : '',
                'firstname' => !empty($row[1]) ? utf8_encode($row[1]) : '',
                'lastname'  => !empty($row[2]) ? utf8_encode($row[2]) : '',
            ];
        }
    }

...并且它works(没有错误,无论是否存在ÿ),但是随后希腊字母和西里尔字母变成了问号。例如,此:Εθνικής将变为???????

我也尝试过使用mb_convert_encoding($row[1], 'utf-8')-并不会将希腊字母或西里尔字母变成问号,但是此ÿ字符将变为?

  1. 将上传的CSV文件的“处理”(转换为数组)移动到Job类的@handle方法中有效,但是后来我无法将该数组中的数据存储到DB(MongoDB)中。请参阅下面的更新。

DEBUGGING:

这是我从dd($contacts);中得到的:

enter image description here

因此,它在ÿ处具有“ b”。并且,在进行一些“搜索”之后,我发现此“ b”表示“二进制字符串”,即非Unicode字符串,其功能在字节级别(What does the b in front of string literals do?)上运行。

我了解的是:调度Job类时,Laravel尝试对其进行“ JSON编码”(传递的参数/数据),但是由于存在二进制数据(非Unicode字符串)而失败。无论如何,我找不到解决方案(能够使用ÿ处理此类CSV文件)。

我正在使用:

  • Laravel 5.7
  • PHP 7.1.31-1 + ubuntu16.04.1 + deb.sury.org + 1(cli)(内置:2019年8月7日10:22:48)(NTS)
  • Redis供电的队列

更新

当我将上传的CSV文件的“处理”(转换为数组)移到Job类的@handle方法中时-我没有收到此错误(Unable to JSON encode payload. Error code: 5),但是当我尝试存储有问题的二进制数据时与ÿb"Richardÿ")进入MongoDB-失败。奇怪的是,我在日志文件中没有得到任何错误例外message,所以我将所有内容都放在try-catch中,如下所示:

        try {
            // Insert data into MongoDB
        } catch (Exception $e) {
            Log::info($e->getFile());
            Log::info($e->getLine());
            Log::info($e->getMessage());
        }

...这是结果:

enter image description here

[无论如何,我相信它由于b"Richardÿ"而失败,并且我猜想解决方案是在编码字符串中,但是正如我已经提到的那样-我无法找到有效的解决方案:

  • utf8_encode起作用(没有错误,无论是否有ÿ),但随后希腊字母和西里尔字母变成了问号。例如,此:Εθνικής将变为???????
  • mb_convert_encoding($row[1], 'utf-8')-它不会将希腊字母或西里尔字母变成问号,但此ÿ字符将变为?
  • iconv('windows-1252', 'UTF-8', $row[1])-可以工作(没有错误,无论是否有ÿ),但是当有希腊字母或西里尔字母时-会失败(我收到此错误异常:iconv(): Detected an illegal character in input string
php laravel csv mongodb-php laravel-queue
1个回答
0
投票

您遇到的错误是UTF8编码问题,在将行值发送到作业之前,请尝试通过utf8_encode()传递行值。

© www.soinside.com 2019 - 2024. All rights reserved.