You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

可用JavaScript API请求转PHP Curl后返回空响应,求排查问题

问题描述

我有一段可正常运行的JavaScript API调用代码:

var headers = {
  Authorization: "Bearer " + MY_ACCESS_TOKEN
};

var requestParams = {
  method: "POST",
  contentType: "application/json",
  headers: headers,
  payload: JSON.stringify({
    query: 'query {adSet(id: "' + MY_ADSET_ID + '") {insights(timeRange: {from: "2023-08-01T00:00:00Z", until: "2023-08-10T23:59:59Z"}timeIncrement: DAILY) {timestamps reports {impressions conversions offerwallImpressions offerwallAverageRank spend}}}}'
  })

var response = UrlFetchApp.fetch(MY_API_ENDPOINT, requestParams);
var data = JSON.parse(response);

将其转换为PHP Curl实现后,API仅返回空响应。已知my_curl函数用于获取$MY_ACCESS_TOKEN时可正常工作,请问我哪里出错了?

我的PHP代码:

$postdata = json_encode('query: query {adSet(id: "' . $MY_ADSET_ID . '") {insights(timeRange: {from: "2023-08-01T00:00:00Z", until: "2023-08-10T23:59:59Z"} timeIncrement: DAILY) {timestamps reports {impressions conversions offerwallImpressions offerwallAverageRank spend}}}}');
$endpoint = $MY_API_ENDPOINT;
$headers = array (
    "Content-Type: application/json",
    "Authorization: Bearer " . $MY_ACCESS_TOKEN,
    $postdata
);

$data = my_curl ($endpoint, $headers);
var_dump ($data);

function my_curl ($endpoint, $headers) {
    $ch = curl_init ();

    curl_setopt ($ch, CURLOPT_URL, $endpoint);
    curl_setopt ($ch, CURLOPT_POST, 1);
    curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt ($ch, CURLOPT_HEADER, false);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);

    $server_output = curl_exec($ch);
    curl_close ($ch);

    $json = json_decode ($server_output, true);

    return ($json);
}
错误分析与修正

你的PHP代码存在三个关键错误,导致API返回空响应:

  • POST请求体放置位置错误:你把请求体$postdata塞进了请求头数组里,这不符合HTTP协议规范。在PHP Curl中,POST请求体需要通过CURLOPT_POSTFIELDS参数单独设置,而不是放在请求头中。
  • JSON编码格式错误:JavaScript代码是将包含query键的对象转为JSON,而你直接对字符串'query: ...'做JSON编码,生成的是不符合API要求的JSON字符串,而非JSON对象。
  • 转义字符错误:代码中的"是HTML转义的双引号,在PHP字符串中应直接使用"或转义的\",否则会导致GraphQL查询语句格式失效。

修正后的PHP代码

// 构造正确的GraphQL查询语句,使用原生双引号
$query = 'query {adSet(id: "' . $MY_ADSET_ID . '") {insights(timeRange: {from: "2023-08-01T00:00:00Z", until: "2023-08-10T23:59:59Z"} timeIncrement: DAILY) {timestamps reports {impressions conversions offerwallImpressions offerwallAverageRank spend}}}}';
// 按照JavaScript的逻辑,将包含query键的数组转为JSON
$postdata = json_encode(['query' => $query]);

$endpoint = $MY_API_ENDPOINT;
// 请求头仅保留Content-Type和Authorization
$headers = array(
    "Content-Type: application/json",
    "Authorization: Bearer " . $MY_ACCESS_TOKEN
);

// 传递postdata参数给curl函数
$data = my_curl($endpoint, $headers, $postdata);
var_dump($data);

function my_curl($endpoint, $headers, $postdata) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $endpoint);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    // 设置POST请求体
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // 可选:开启调试模式,查看curl请求详情
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    $verboseLog = fopen('php://temp', 'w+');
    curl_setopt($ch, CURLOPT_STDERR, $verboseLog);

    $server_output = curl_exec($ch);

    // 调试时可打印日志排查问题
    rewind($verboseLog);
    $logContent = stream_get_contents($verboseLog);
    // echo "Curl日志:\n" . $logContent . "\n";

    // 检查curl是否执行出错
    if(curl_errno($ch)){
        echo 'Curl错误: ' . curl_error($ch);
    }

    curl_close($ch);
    fclose($verboseLog);

    $json = json_decode($server_output, true);
    return $json;
}

额外调试建议

  • 开启CURLOPT_VERBOSE可以查看完整的curl请求日志,帮助定位API返回空响应的具体原因(如权限验证失败、查询语法错误等)。
  • 确认$MY_ADSET_ID和$MY_API_ENDPOINT变量的取值与JavaScript代码完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:01:10