multidimensional array returns bad results with foreach

I have a php class that interacts with mysql database and then fetches an array as a result.

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

I use it with print_r :

print_r($res);

and it outputs this:

Array
(
    [0] => Array
        (
            [id] => 1
            [firstname] => Mohamed
            [lastname] => Kadri
        )

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

    [2] => Array
        (
            [id] => 3
            [firstname] => Sameh
            [lastname] => Chraiti
        )

And with foreach:

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

it outputs this:

1 Mohamed Kadri
2 Slim Nejmaoui
3 Sameh Chraiti

but when there is only one row, it shows this:

1 1 1
M M M    
K K K

(1 is the id, M is the first letter in the firstname and K is the first letter in the lastname).

So maybe when there is more than one row the class generates a multidimensional array and the foreach will work on it, and when there is only one row it generates a simple array that will be treated as a multidimensional array by this exact foreach.

So should I make a condition to process one of two types of foreach?

Thanks.

Answers


apparently your db object return a single array when you have only one result somthing like that:

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

you can test first input and if this is not an array don't loop thrue the foreach else do a foreach

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

I think you should change your db class to always return a nested array even on single row result to keep your results consistents.


Yep, it looks like that's exactly what's happening. Most likely, $db->getResult() returns the resulting row as an array (not sub-arrays within the result) when there is only one row returned from the query. So, you'll need to detect if there are nested arrays and handle appropriately:

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 />';
}

Are you using CodeIgniter? Because it looks like you are. In CodeIgniter, when there is only one result, it only returns one array.

My suggestion? Create a support function (do_something_with_row below) and then call it conditionally:

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

You are iterating over one result-row in the case that is unclear to you.

What happens unnoticed to you is that $row then contains only scalar values:

  1. 1 (int)
  2. Mohamed (string)
  3. KadriK (string)

This is the contents for $row already per each iteration (1-3).

These values are getting accessed with the substring access syntax that looks exactly like an array, making use of square brackets.

As all indezies 'id', 'firstname' and 'firstname' are interpreted as constants which are all undefined and result in 0, you're actually accessing the first character/byte in the string: 1, M and K.

With a newer version of PHP the 1 would not even be returned.

Now the important part: If you develop or you look for errors, enable the logging of notices. They warn you about such things:

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

A quick setup can be done by adding this:

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

Need Your Help

How to display a standard SharePoint “Access Denied” message

c# sharepoint exception

How can I re-direct the user to the standard SharePoint "access denied" page, similar to the image below?

template specialization, different behavior on windows vs gcc?

c++ templates gcc linker

I'm looking for an overview or description of what GCC does differently than MSVC for compile + link of template classes with specializations. For example, this type of thing works on GCC but not M...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.