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

使用curl_multi获取数据后无法访问数组偏移量的问题排查

问题

使用curl_multi批量请求API时,尝试通过$results[2]['context']或$results[0]['dom']访问数据,出现「Cannot access offset of type string on string」或「Undefined array key」错误,无法直接或循环访问结果,怀疑是curl_multi使用方式导致数组异常。

我的代码:

<?php
session_start();
$authorization = "Authorization: Bearer ".$_SESSION['toke'];
$domurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'];
$dimurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/dim';
$conurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/con';
$lisurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/lis';
$senurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/sen';
$nsurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/ns';
$malurl = 'https://api.xxxx.xx/intel/v4/dom/' . $_POST['domata'] . '/mal/urls';

$requests = array($domurl, $dimurl, $conurl, $lisurl, $senurl, $nsurl, $malurl);
$main    = curl_multi_init();
$results = array();
$errors  = array();
$info = array();
$count = count($requests);
for($i = 0; $i < $count; $i++)
{
$handles[$i] = curl_init($requests[$i]);
//var_dump($requests[$i]);

curl_setopt_array($handles[$i], array(
  CURLOPT_URL => $requests[$i],
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array($authorization),
));

//curl_setopt($handles[$i], CURLOPT_URL, $requests[$i]);
//curl_setopt($handles[$i], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($main, $handles[$i]);
}
$running = 0;
do {
curl_multi_exec($main, $running);
}
while($running > 0);
for($i = 0; $i < $count; $i++)
{
$results[] = curl_multi_getcontent($handles[$i]);
//$errors[]  = curl_error($handles[$i]);
//$info[]    = curl_getinfo($handles[$i]);
curl_multi_remove_handle($main, $handles[$i]);
}
curl_multi_close($main);
//print_r($results);
//echo implode(" ",$results);
//echo json_encode($results);
var_dump($results);
//var_dump($errors);
echo $requests[0]. " ==><br>";
//echo gettype($results);
//print_r($info[0]);
echo "<br><br>";
echo '<table class="tftable" border="1">';
//if (isset($results['dom'])){
//$domm = $results['dom'];
//echo 'Dom: ' . $domm; }
print_r(array_values($results));
print("<pre>".print_r($results,true)."</pre>");


echo '         <tr>';
echo '            <th colspan=4><center>Dom Info</th></center>';
echo '        </tr>';
echo '        <tr><th>Type</th><th>Value</th><th>Laseen</th></tr>';
echo '            <td>Dom: </td>';
echo '            <td> ' . $results['2']['context'] . '</td> ';
echo '            <td>' . date('m/d/Y H:i', $results['lseen'])  . '</td>';
echo '            </tr>';

//print_r();
?>

输出结果:

Array ( [0] => {"dom":"biggie.com","lseen":9393789,"ebused":false,"who":{"created":7416583,"expire":7032583,"reg":"Company Solutions, LLC"},"score":144.5} [1] => {"human-test":12.5,"infrared":12} [2] => [{"context":"cert","lseen":393789},{"context":"hello","last-seen":9361558},{"context":"mailbody","lseen":545360},{"context":"sample","lseen":1645360}] [3] => {"ts":9393789,"listed":false} [4] => [{"ip":"314.199.23.133","hello":"biggie.com","lseen":167558,"score":49.6},{"ip":"629.732.363.252","hello":null,"lseen":167360,"score":15.5},{"ip":"49.75.156.214","hello":null,"lseen":167785,"score":191.1}] [5] => [{"ns":"graham.ns.asample.com","lseen":163789,"score":443.0003716,"counting":75},{"ns":"island.ns.potato.com","lseen":13789,"score":333.84,"counting":69}] [6] => [] )
Array
(
    [0] => {"dom":"biggie.com","lseen":9393789,"ebused":false,"who":{"created":7416583,"expire":7032583,"reg":"Company Solutions, LLC"},"score":144.5}

    [1] => {"human-test":12.5,"infrared":12}

    [2] => [{"context":"cert","lseen":393789},{"context":"hello","last-seen":9361558},{"context":"mailbody","lseen":545360},{"context":"sample","lseen":1645360}]

    [3] => {"ts":9393789,"listed":false}

    [4] => [{"ip":"314.199.23.133","hello":"biggie.com","lseen":167558,"score":49.6},{"ip":"629.732.363.252","hello":null,"lseen":167360,"score":15.5},{"ip":"49.75.156.214","hello":null,"lseen":167785,"score":191.1}]

    [5] => [{"ns":"graham.ns.asample.com","lseen":163789,"score":443.0003716,"counting":75},{"ns":"island.ns.potato.com","lseen":13789,"score":333.84,"counting":69}]

    [6] => []

)

解决方案

核心问题

当前$results数组存储的是JSON格式的字符串,并非PHP可直接访问的数组/对象。curl_multi_getcontent()返回的是API响应的原始文本,必须先解析为PHP数组才能通过键名访问数据。

修复步骤

  1. 解析JSON字符串:在存储结果时,使用json_decode()将每个响应字符串转换为关联数组(第二个参数传true),同时处理解析失败的情况。
  2. 修正访问语法:数组索引需使用数字(如$results[2]而非$results['2']),并匹配正确的数据层级。

修改后的关键代码

替换结果存储的循环部分:

for($i = 0; $i < $count; $i++)
{
    // 获取原始响应并解析为关联数组,解析失败时返回空数组兜底
    $response = curl_multi_getcontent($handles[$i]);
    $results[] = json_decode($response, true) ?: [];
    
    // 可选:记录请求错误和状态信息
    $errors[] = curl_error($handles[$i]);
    $info[] = curl_getinfo($handles[$i]);
    
    curl_multi_remove_handle($main, $handles[$i]);
}

正确访问示例

  • 获取第一个请求的域名:
    echo $results[0]['dom']; // 输出:biggie.com
    
  • 遍历第三个请求的context列表:
    foreach($results[2] as $item) {
        $lastSeen = $item['lseen'] ?? $item['last-seen'];
        echo "Context: {$item['context']}, Last Seen: " . date('m/d/Y H:i', $lastSeen) . "<br>";
    }
    
  • 修正表格部分的错误代码:
    echo '<table class="tftable" border="1">';
    echo '         <tr>';
    echo '            <th colspan=3><center>Dom Info</th></center>';
    echo '        </tr>';
    echo '        <tr><th>Type</th><th>Value</th><th>Last Seen</th></tr>';
    echo '            <td>Dom: </td>';
    echo '            <td> ' . $results[0]['dom'] . '</td> ';
    echo '            <td>' . date('m/d/Y H:i', $results[0]['lseen'])  . '</td>';
    echo '            </tr>';
    
    // 输出Context列表
    echo '<tr><th colspan=3><center>Context List</th></center></tr>';
    foreach($results[2] as $ctx) {
        $lastSeen = $ctx['lseen'] ?? $ctx['last-seen'];
        echo '<tr>';
        echo '<td>Context</td>';
        echo '<td>' . $ctx['context'] . '</td>';
        echo '<td>' . date('m/d/Y H:i', $lastSeen) . '</td>';
        echo '</tr>';
    }
    echo '</table>';
    

额外注意事项

  • 处理解析失败:json_decode()在遇到非JSON格式内容时会返回null,用?: []兜底为空数组可避免后续访问报错。
  • 验证请求状态:通过$info[$i]['http_code']检查HTTP状态码(如200表示请求成功),再决定是否解析响应内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:12:10