Skip to content

[Bug] 接口布尔类型参数(如 is_deleted)被 SDK 错误转换为整数,导致 API 返回类型校验失败 #20

@comsummer

Description

@comsummer

SDK版本

{
    "name": "tencent-ad/marketing-api-php-sdk",
    "version": "v1.1.100"
}

问题描述 (Description)

在使用 SDK 调用带有布尔类型参数的接口(例如 adgroups/get 接口的 is_deleted 参数)时,即使传入 PHP 原生的 truefalse,接口依然会报错。

报错信息:

TencentAds\Exception\TencentAdsResponseException: [40000] Parameter 'is_deleted' must be Boolean

根本原因分析 (Root Cause)

经过对 SDK 源码调试发现,问题出在请求参数的序列化转换逻辑上:

  1. SDK 实现:
    SDK 内部使用了 \GuzzleHttp\Psr7\Query::build 来构建 Query String。
if (class_exists('\GuzzleHttp\Psr7\Query')) {
    $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
} else {
    $httpBody = \GuzzleHttp\Psr7\build_query($formParams);
}
  1. 依赖库行为:
    guzzlehttp/psr7 库中,Query::build 方法会将 bool 类型默认转换为 int(即 10)。
  • v2.7.0 及更高版本中,其方法签名 build(array $params, $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true) 明确规定了 treatBoolsAsInts 默认为 true
  • v2.0.0 至 v2.7.0 之间,此逻辑是硬编码的,默认也会转为 int
  1. 结果:
    导致发送给腾讯广告后端的请求参数变成了 is_deleted=1,而 API 后端校验器由于不支持整数类型的布尔表示,导致请求失败。

重现步骤 (Steps to Reproduce)

$tads = TencentAds\TencentAds::init(/* config */);
$response = $tads->adgroups()->get([
    'account_id' => $accountId,
    'is_deleted' => true, // 传入 bool 类型
]);

期望行为 (Expected Behavior)

SDK 应当正确处理布尔值,确保发送到后端的参数符合 API 要求的 Boolean 格式(如 "true" / "false" 字符串)。

修复建议 (Suggested Fix)

在调用 Query::build 之前,在 SDK 内部对参数进行预处理,或者显式指定 treatBoolsAsInts = false(需考虑 Guzzle 版本的兼容性)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions