大量的HTTP发送文件流引发错误-“ json_encode错误:不支持类型”

时间:2018-08-31 11:31:56

标签: rest api curl laravel-5 guzzlehttp

我在Laravel应用程序中使用Guzzle客户端将请求与文件一起发送到API端点。我通过创建如下的多部分数据来实现这一目标-

$rid = $this->wsl->curlWSl('POST', '/throttle', [], [
            'verify' => false,
            'multipart' => [
                [
                    'name'     => 'csv',
                    'contents' => fopen($dest, 'rb')
                ],
                [
                    'name' => 'name',
                    'contents' => $request->input('name')
                ],
                [
                    'name' => 'description',
                    'contents' => $request->input('description')
                ],
                [
                    'name' => 'header',
                    'contents' => '1'
                ]
            ]
]);

我已如下定义的curlWSL方法-

public function curlWSl(string $method, string $path, Array $headers = [], Array $data = null, Array $options = [])
    {
        $endPoint = $this->getUri() . $path;

        if (!empty($headers)) {
            $options['headers'] = $headers;
        }

        if ($method == 'GET' && $data) {
            $endPoint .= http_build_query($data);
        }
        if ($method == 'POST') {
            $options['json'] = $data;
        }

        try {
            $response = $this->getClient()->request(
                $method,
                $endPoint,
                $options
            );
        } catch (\Exception $ex) {
            return ['statusCode'=>$ex->getCode(), 'errorMsg' => $ex->getMessage()];
        }

        return json_decode($response->getBody()) ?? (string)$response->getBody();
    }

这样做,抛出一个异常-

InvalidArgumentException {#296 ▼
  #message: "json_encode error: Type is not supported"
  #code: 0
  #file: "/var/www/html/vendor/guzzlehttp/guzzle/src/functions.php"
  #line: 327
  trace: {▶}
}

我确定,这是由于fopen文件流所致,因为当我删除该文件流时,我的请求已在端点处收到。

我也在寻求一些帮助,该如何使用 laravel验证程序在API端点上验证请求数据。

非常感谢您的帮助。

注意:我非常希望传递文件对象,而不仅是文件数据,我可以使用file_get_contents来传递。

1 个答案:

答案 0 :(得分:0)

我已经解决了。
食口不处理太多参数,无法按请求发送给端点。在设置$options['json'] = $data时,这会考虑json格式的数据,而实际上不是。因此,我必须将其改为多部分而不是json才能使工作正常。我不得不按如下方式修改通话-

$rid = $this->wsl->curlWSl('POST', '/throttle', [], [
                [
                    'name'     => 'csv',
                    'contents' => fopen($dest, 'rb')
                ],
                [
                    'name' => 'name',
                    'contents' => $request->input('name')
                ],
                [
                    'name' => 'description',
                    'contents' => $request->input('description')
                ],
                [
                    'name' => 'header',
                    'contents' => '1'
                ]
]);

在方法 curlWSL 中,我修改了代码以接受多部分数据-

public function curlWSl(string $method, string $path, Array $headers = [], Array $data = null, Array $options = [])
    {
        $endPoint = $this->getUri() . $path;

        if (!empty($headers)) {
            $options['headers'] = $headers;
        }

        if ($method == 'GET' && $data) {
            $endPoint .= http_build_query($data);
        }
        if ($method == 'POST') {
            $options['multipart'] = $data;
        }

        try {
            $response = $this->getClient()->request(
                $method,
                $endPoint,
                $options
            );
        } catch (\Exception $ex) {
            return ['statusCode'=>$ex->getCode(), 'errorMsg' => $ex->getMessage()];
        }

        return json_decode($response->getBody()) ?? (string)$response->getBody();
    }