遍历SQL查询结果时触发数组转字符串错误的问题及解决方法
解决SQL嵌套查询中的Array to string conversion错误
我最近在处理PHP+MySQL的业务需求时踩了个坑:从主查询获取多条SN数据后,用foreach循环执行嵌套查询时,触发了Array to string conversion错误。
问题场景与原代码
我原本的逻辑是先从list表筛选出符合条件的SN,再用这些SN去pc表查询对应最新记录,但运行时直接报错。原代码如下:
$con=mysqli_connect($localhost,$username,$password,'db'); $query = 'SELECT `SN` FROM `list` WHERE `Floor` LIKE "LP60" AND `type`LIKE "pc"'; $result = mysqli_query($con,$query) or die(mysqli_error()); foreach ($result as $SN) { $get = mysqli_query($con,'SELECT * FROM pc WHERE pcSN LIKE '.$SN.'ORDER BY EvenID DESC LIMIT 1'); while ($get_row = mysqli_fetch_assoc($get)) { echo '<tr>'; // printing table row echo '<td id="ID">'.$get_row[0].'</td>'; echo '<td>'.$get_row[1].'</td>'; echo '<td>'.$get_row[2].'</td>'; echo '<td>'.$get_row[3].'</td>'; echo '<td>'.$get_row[4].'</td>'; echo '<td>'.$get_row[5].'</td>'; echo '<td>'.$get_row[6].'</td>'; echo '<td>'.$get_row[7].'</td>'; echo '<td>'.$get_row[8].'</td>'; echo '<td>'.$get_row[9].'</td>'; echo '<td>'.$get_row[10].'</td>'; echo '<td>'.$get_row[11].'</td>'; echo '<td>'.$get_row[12].'</td>'; echo '<td>'.$get_row[13].'</td>'; echo '<td>'.$get_row[14].'</td>'; echo'</tr>'; // closing table row } }
我已经单独验证过两个查询都能正常运行,也用print_r($SN)排查过,但还是触发了错误。
错误原因分析
后来我理清了问题根源:
- 直接遍历
mysqli_query返回的结果集时,$SN是一个关联数组(比如['SN' => 'PC-123']),不是字符串,把数组直接拼到SQL语句里就会触发"Array to string conversion"错误。 - 原代码还有两个隐藏问题:一是存在SQL注入风险,二是
mysqli_fetch_assoc返回的是关联数组,用数字索引(比如$get_row[0])取值是无效的。
解决方法与修正后代码
我调整了遍历逻辑,同时用mysqli_escape_string对SN值进行转义处理,修正后的代码如下:
$con=mysqli_connect($localhost,$username,$password,'db'); // mysql select query $query = 'SELECT `SN` FROM `list` WHERE `Floor` LIKE "LP60" AND `type`LIKE "pc"'; $result = mysqli_query($con,$query) or die(mysqli_error()); while($row = mysqli_fetch_assoc($result)) { foreach ($row as $SN){ $sql = "SELECT * FROM pc WHERE pcSN LIKE '" . mysqli_escape_string($con,$SN) . "' ORDER BY EvenID DESC LIMIT 1"; $get = mysqli_query($con,$sql); while ($get_row = mysqli_fetch_assoc($get)) { echo '<tr>'; // printing table row echo '<td>'.$get_row['xxx'].'</td>'; // ... 其他字段用对应的键名取值 echo '<td>'.$get_row['yyy'].'</td>'; echo'</tr>'; // closing table row } } }
关键修正点:
- 用
while(mysqli_fetch_assoc($result))遍历主查询结果,每次取出完整的行数据数组 - 遍历行数组拿到真正的SN字符串值
- 用
mysqli_escape_string转义SN值,避免SQL注入,同时确保字符串能正确拼入SQL语句 - 改用关联数组的键名(比如
$get_row['xxx'])来获取字段值,而不是数字索引
内容的提问来源于stack exchange,提问作者NDSAC
相关产品推荐
相关产品推荐

