从多维数组提取指定数据及动态键处理问题求助
问题:动态键多维数组中提取clan_id和nickname并存入数据库
问题背景
需要从API返回的多维数组中提取clan_id和nickname存入数据库,但遍历方式错误,且data下的键是动态变化的(比如示例中的535051281)。
数组结构
Array ( [status] => ok [meta] => Array ( [count] => 1 ) [data] => Array ( [535051281] => Array ( [clan_id] => 500040775 [nickname] => tiktak1999 [logout_at] => 1686514280 ) ) )
当前代码
$sql = "SELECT * FROM recruitement2"; $result = $mysqli->query($sql); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { $jsonobj = file_get_contents ("https://api.worldoftanks.eu/wot/account/info/?application_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&account_id=".$row["gameid"]."&fields=clan_id%2Cnickname%2Clogout_at"); $json = (json_decode($jsonobj, true)); echo '<pre>'.print_r($json, true).'</pre>'; echo "<br><br>hier komt de enkele info<br><br>"; foreach($json as $row) { foreach($row['data'] as $k) { foreach($k['535051281'] as $l) { echo $l['535051281']['clan_id']; echo $l['535051281']['nickname']; ; } } } } }
错误信息
Fatal error: Uncaught TypeError: Cannot access offset of type string on string in /data/sites/web/mentals-royal-army-of-legendsnl/www/test.php:18 Stack trace: #0 /data/sites/web/mentals-royal-army-of-legendsnl/www/index.php(82): include() #1 {main} thrown in /data/sites/web/mentals-royal-army-of-legendsnl/www/test.php on line 18
解决方案
错误原因
- 外层
foreach($json as $row)遍历了整个数组,包括status(字符串类型),此时访问$row['data']会触发类型错误。 - 硬编码了动态变化的键
535051281,无法适配不同用户的返回结果。
修正后的代码
$sql = "SELECT * FROM recruitement2"; $result = $mysqli->query($sql); if ($result->num_rows > 0) { while($db_row = $result->fetch_assoc()) { // 重命名变量避免冲突 $jsonobj = file_get_contents("https://api.worldoftanks.eu/wot/account/info/?application_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&account_id=".$db_row["gameid"]."&fields=clan_id%2Cnickname%2Clogout_at"); // 处理API请求失败的情况 if(!$jsonobj) { echo "API请求失败:". $db_row["gameid"] ."<br>"; continue; } $json = json_decode($jsonobj, true); // 检查API返回状态是否正常 if($json['status'] !== 'ok') { echo "API返回错误:". $db_row["gameid"] ."<br>"; continue; } // 动态获取data下的账号数据(兼容单个/多个账号返回) foreach($json['data'] as $account_data) { $clan_id = $account_data['clan_id'] ?? null; // 避免未定义索引错误 $nickname = $account_data['nickname'] ?? null; echo "clan_id: ". $clan_id ." | nickname: ". $nickname ."<br>"; // 存入数据库(用预处理语句防SQL注入) $insert_sql = "INSERT INTO 目标表名 (clan_id, nickname, gameid) VALUES (?, ?, ?)"; $stmt = $mysqli->prepare($insert_sql); $stmt->bind_param("isi", $clan_id, $nickname, $db_row["gameid"]); $stmt->execute(); $stmt->close(); } } }
关键优化点
- 变量重命名:避免循环变量名冲突导致的逻辑错误。
- 异常处理:增加API请求失败、返回状态异常的判断,提升代码健壮性。
- 动态键处理:用
foreach遍历data数组,无需关心动态变化的键名。 - 安全存储:使用MySQLi预处理语句存入数据,防止SQL注入风险。
内容的提问来源于stack exchange,提问作者Dre Langlaufer
相关产品推荐
相关产品推荐

