6

I'm trying to see the structure of the PDOStatement object returned by my query:

$sql="SELECT co.CompanyId, co.Name, co.Address, co.City, co.State, ctry.NameEnglish, co.PostalCode FROM company AS co LEFT JOIN country AS ctry ON ctry.CountryId = co.CountryId ORDER BY Name;";
$result=$conn->query($sql);

The query works, as I'm able to nest some foreach statements and display the six rows of data by doing the following.

$firstRow=true;
echo '<table>';
foreach ($result as $rowId => $rowData) {
    if ($firstRow) {
        echo "<thead><tr><th>Row Number</th>";
        foreach ($rowData as $fieldId => $fieldData) {
            echo "<th>$fieldId</th>";
        }
        echo "</tr></thead>";
        $firstRow=false;
    }
    echo "<tr><td>$rowId</td>";
    foreach ($rowData as $fieldId => $fieldData) {
        $fieldData=str_replace("\n","<br>",$fieldData);
        echo "<td>$fieldData</td>";
    }
    echo "</tr>";
}
echo "</table>";

But I was curious about the internal structure of the object $result, so I var_dump'ed it and got this:

object(PDOStatement)#4 (1) {
    ["queryString"]=>
        string(185) "SELECT co.CompanyId, co.Name, co.Address, co.City, co.State, ctry.NameEnglish, co.PostalCode FROM company AS co LEFT JOIN country AS ctry ON ctry.CountryId = co.CountryId ORDER BY Name;"
}

Why doesn't var_dump show the arrays associated with the rows and fields?

Jonathan M
  • 17,145
  • 9
  • 58
  • 91
  • Did you do: `$result = $result->fetchAll();` ? and then `var_dump($result);` – Rizier123 Jan 19 '15 at 17:23
  • No. I did the two lines in the first code segment and then `var_dump($result);`. I don't use any explicit `fetch`es in the code, even to display the 6 rows. – Jonathan M Jan 19 '15 at 17:25
  • 1
    According to the docs (http://php.net/PDOStatement), the only propery on a `PDOStatement` object is `queryString`, as you can see. It also `implements Traversable`, that's what lets you `foreach` over it. When you do that, PHP calls methods on the object. Those methods get the row data. The rows are not properties of the object, so that's why they don't appear in the `var_dump`. – gen_Eric Jan 19 '15 at 17:25
  • Ah, thanks, Rocket. I wonder how, then, am I getting rows and fields in the `foreach` statements without doing any `fetch`es? I'll post that code. – Jonathan M Jan 19 '15 at 17:27
  • @JonathanM: The `fetch` is called internally when you `foreach`. `PDOStatement ` (it `implements Traversable`) implements the [`current()`](http://php.net/manual/en/iterator.current.php) method to do that. – gen_Eric Jan 19 '15 at 17:27
  • Ah, so the proper behavior for a `foreach` is built into the `PDOStatement` object. I see. So there really is additional communication going back to the database during a `foreach`, then, right? – Jonathan M Jan 19 '15 at 17:31
  • @RocketHazmat, put that in an answer and let me choose it. – Jonathan M Jan 19 '15 at 17:33
  • 1
    @JonathanM: Yeah, basically. I don't know if it's still contacting the database, or if it buffered the full result set in memory. – gen_Eric Jan 19 '15 at 17:37
  • @RocketHazmat - You should post your comment as an answer so it doesn't get buried. – Mr. Llama Jan 19 '15 at 17:40

1 Answers1

8

The manual page for PDOStatement shows what is going on here. PDOStatement objects only have one property, queryString. That's what you're seeing when you var_dump. Everything else on PDOStatement is a method, which are excluded from var_dump.

PDOStatement implements Traversable (Docs for Traversable.) This is how you are able to see the rows when you foreach. Internally, PDOStatement implements methods that are called when you foreach over the object. Those methods call fetch() and get the row data. That's how you see the rows when you foreach, but why you can't see them in a var_dump.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337