【问题标题】:Guzzle HTTP send file stream throws error- "json_encode error: Type is not supported"Guzzle HTTP 发送文件流抛出错误-“json_encode 错误:不支持类型”
【发布时间】:2018-08-31 11:31:56
【问题描述】:

我在我的 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 来完成。

【问题讨论】:

  • 我看到的是您的包装器询问方法是否为“POST”并设置 json => 数据。但实际上,Guzzle 期望请求方法中有整个第三个参数,而不是仅设置一个“json”键。此外,看起来你正在双重包装你的 Guzzle 实现。看起来太麻烦了。
  • @MarkSkayff,谢谢你的建议,你说得对,Guzzle 不会处理太多参数,如果它得到json=>data 可用,那么它会忽略请求中的多部分数据。因此,我必须从选项数据中删除 json=>data 才能使事情正常进行。

标签: rest api curl laravel-5 guzzle


【解决方案1】:

我把它修好了。
Guzzle 不会处理太多参数以将请求发送到端点。当我们设置 $options['json'] = $data 时,这考虑了 json 格式的数据,实际上不是。因此,我不得不将其转换为 multipart 而不是 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();
    }

【讨论】:

    猜你喜欢
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多