多维数组使用foreach返回错误结果


multidimensional array returns bad results with foreach

我有一个php类,它与mysql数据库交互,然后获取一个数组。

$res = $db->getResult(); // $res is an array

我将它与print_r:一起使用

print_r($res);

它输出这个:

大堆([0]=>数组([id]=>1[名字]=>穆罕默德[lastname]=>卡德里)[1] =>阵列([id]=>2[firstname]=>苗条[lastname]=>奈梅奥伊)[2] =>阵列([id]=>3[名字]=>Sameh[lastname]=>Chraiti)

和foreach:

foreach ($res as $row) {
    echo $row['id'] . ' ' . $row['firstname'] . ' ' . $row['lastname'] . '<br />';
}

它输出这个:

1 Mohamed Kadri
2 Slim Nejmaoui
3 Sameh Chraiti

但当只有一行时,它会显示:

1 1 1
M M M    
K K K

(1是id,M是名字中的第一个字母,K是姓氏中的第一字母)。

因此,当有多行时,类可能会生成一个多维数组,foreach将对其进行处理,而当只有一行时,它会产生一个简单数组,该数组将被这个精确的foreach视为多维数组。

那么,我应该设定一个条件来处理两种类型的foreach中的一种吗?

谢谢。

是的,看起来这正是发生的事情。最有可能的是,当查询只返回一行时,$db->getResult()将结果行作为数组(而不是结果中的子数组)返回。因此,您需要检测是否存在嵌套数组并进行适当处理:

if (isset($res[0]) && is_array($res[0])){
    foreach ($res as $row) {
        echo $row['id'] . ' ' . $row['firstname'] . ' ' . $row['lastname'] . '<br />';
    }
}else{
    echo $res['id'] . ' ' . $res['firstname'] . ' ' . $res['lastname'] . '<br />';
}

显然,当你只有一个结果时,你的db对象会返回一个数组,比如

Array
(
    [id] => 2
    [firstname] => Slim
    [lastname] => Nejmaoui
)

你可以测试第一个输入,如果这不是一个数组,不要循环通过foreach,否则做foreach

if( is_array(current($res)) ){
  // do the foreach...
}else{
  echo $res['id'] . ' ' . $res['firstname'] . ' ' . $res['lastname'] . '<br />';
}

我认为您应该更改数据库类,使其始终返回嵌套数组,即使是在单行结果上也是如此,以保持结果的一致性。

您正在使用CodeIgniter吗?因为它看起来像你。在CodeIgniter中,当只有一个结果时,它只返回一个数组。

我的建议?创建一个支持函数(下面的do_something_with_row),然后有条件地调用它:

if(count($res) > 1)
{
    foreach($res as $row)
    {
        do_something_with_a_row($row);
    }
}
else
{
    do_something_with_a_row($res);
}

在您不清楚的情况下,您正在对一个结果行进行迭代。

你没有注意到的是,$row只包含标量值:

  1. 1(int)
  2. Mohamed(字符串)
  3. KadriK(字符串)

这是每个迭代(1-3)中已经存在的$row的内容。

这些值是使用子字符串访问语法访问的,该语法看起来完全像一个数组,使用方括号。

由于所有索引'id''firstname''firstname'都被解释为未定义的常量,并导致0,因此您实际上正在访问字符串中的第一个字符/字节:1MK

对于更新版本的PHP,1甚至不会返回。

现在重要的部分是:如果您开发或查找错误,请启用通知日志记录他们警告你这些事情:

PHP Notice:  Use of undefined constant Kadri - assumed 'Kadri' in ...

可以通过添加以下内容进行快速设置:

  error_reporting(-1);
  ini_set('display_errors', 1);