You need to enable JavaScript to run this app. Guzzle调用时报错Header value must be scalar问题排查
优惠活动
大模型
产品
解决方案
定价
更多

Guzzle调用时报错Header value must be scalar问题排查

Guzzle 触发 Header value must be scalar or null but array provided 报错的原因与修复

核心根因

你对 GuzzleHttp\Psr7\Request 构造函数的参数格式理解错误,传参结构不符合预期。

  • Request 构造函数的参数顺序固定为:(string $method, $uri, array $headers = [], $body = null, string $version = '1.1'),第三个参数要求直接传入请求头关联数组本身,而非包含 headers、body 等键的配置数组。
  • 从报错堆栈第5行可以看到,Request 构造函数收到的第三个参数是你传入的整个 $options 数组,而非预期的请求头数组:此时 setHeaders 方法会把 $options 的每个键值对当成请求头的键和值,当处理对应值为数组的场景时,直接触发「请求头值不能为数组」的校验逻辑。

对组件设计的澄清

Guzzle 的 Psr7 组件确实支持数组格式的请求头值,但指的是单个请求头允许多个值的一维数组场景,例如:

// 正确的数组格式请求头值:单个Accept头对应多个MIME类型
$headers = [
    'Accept' => ['text/html', 'application/json']
];

这种格式会被组件自动处理为多个同名称的请求头,和你当前误传的二维配置数组完全不是一回事。

修复方案

方案1:调整 Request 构造函数的传参(适配现有写法)

直接把配置数组拆分为对应参数传入:

private function send(string $uri, string $method, $body): bool
{
    if ($this->getTokenValid()) {
        $headers = [
            'Authorization'             => sprintf("Bearer %s", $this->token),
            'Ocp-Apim-Subscription-Key' => SUBSCRIPTION_ID,
            'Content-Type'              => 'application/json'
        ];
        // 按参数顺序传:方法、URI、请求头数组、请求体
        $request = new Request($method, $uri, $headers, $body);
        try {
            $resp = $this->client->send($request);
            return $resp->getReasonPhrase();
        } catch (ClientErrorResponseException $e) {
            error_log($e->getMessage());
            return false;
        }
    } else {
        error_log('Not authenticated');
        return false;
    }
}

方案2:使用 Guzzle Client 原生的 request 方法(更推荐)

Guzzle Client 的 request 方法第三个参数本身就是包含 headers、body 等配置项的选项数组,更符合你原本的写法逻辑,无需手动实例化 Request:

private function send(string $uri, string $method, $body): bool
{
    if ($this->getTokenValid()) {
        $options = [
            'headers' => [
                'Authorization'             => sprintf("Bearer %s", $this->token),
                'Ocp-Apim-Subscription-Key' => SUBSCRIPTION_ID,
                'Content-Type'              => 'application/json'
            ],
            'body' => $body
        ];
        try {
            // Client->request(方法, URI, 配置选项数组)
            $resp = $this->client->request($method, $uri, $options);
            return $resp->getReasonPhrase();
        } catch (ClientErrorResponseException $e) {
            error_log($e->getMessage());
            return false;
        }
    } else {
        error_log('Not authenticated');
        return false;
    }
}

内容的提问来源于stack exchange,提问作者tjb74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 20:54:06