foreach traversal arrays are common, and foreach can also traverse objects
Do the following tests:
Class I
{public
$a = ' a ';
protected $b = ' B ';
Private $c = ' C ';
Private $data = Array (' Fantasy ', ' windows ', ' Linux ');
Internal foreach Traversal class
function traversable ()
{
foreach ($this as $key => $val)
{
echo $key. ' => ';
Print_r ($val);
Echo ' <br> ';
}} $m = new My ();
The outer foreach traverses class
foreach ($m as $key => $val)
{
echo $key. ' => ';
Print_r ($val);
Echo ' <br> ';
}
Echo '--------------------------<br> ';
Internal foreach Traversal class
$m->traversable ();
The output results are as follows:
A=>a
--------------------------
a=>a
b=>b
c=>c
It can be concluded that for an external foreach traversal there is no permission to access the two decorated attributes of protected private, while within the class is privileged access, and foreach traverses all the attributes.
today, when I wrote PDO, I found that I could write this:
foreach ($db->query (' SELECT * from tab ') as $row)
{
print_r ($row);
}
This quickly gets all the query results, but it's strange that $this->query () returns the object type Pdostatement, and Var_dump () prints the result:
Object (Pdostatement) #2 (1) {
[querystring]]=>
String (a) select * from User
}
Pdostatement inside is a public attribute querystring and foreach does not appear this value, such a situation is not simply to traverse the property, but the class inherits the iterator iterator, When foreach executes the iteration in class, traversing the data specified by the iterator
About iterators Look at the following example:
Class Test implements iterator
{public
$a = ' a ';
Private $data = Array (' Apple ', ' banlance ', ' current ');
Private $point = 0;
Public function __construct ()
{
$this->point = 0;
}
Public function current ()
{return
$this->data[$this->point];
}
Public Function key ()
{return
$this->point;
}
Public function Next ()
{
+ + $this->point;
}
Public Function Rewind ()
{
$this->point=0;
}
Public function valid ()
{return
isset ($this->data[$this->point]);
}
$t = new test ();
foreach ($t as $val)
{
print_r ($val);
Echo ' <br> ';
}
The output results are as follows:
Apple
banlance
current
Test class implements the iterator interface, which is used when foreach calls, and the calling process is roughly the following pseudo code:
Iterative process pseudo code while
(valid)
{
<span style= "White-space:pre" > </span>current/key
< Span style= "White-space:pre" > </span>next
}
Rewind
So, the previous foreach processing of the class is a default method, which is the way it is if the class being inherited iterator is traversed by a foreach
It is not possible to apply PDO in this case, because if we var_dump the above test class The result is this:
Test Object
(
[a] => a
[data:test:private] => Array
(
[0] => Apple
[1] => Banlance
[2] => current
)
[point:test:private] => 0
)
But when we var_dump $db the object returned by->query, we do not see the attributes defined in the iterator interface and the $data of the data being traversed;
So we can guess that Pdostatement inherits an iterative interface, but it's not iterator.
View the manual to find:
See Traversable's introduction to the following figure:
As a result, Pdostatement's iterative implementations are internally, and inheriting iterator is the way PHP scripts are implemented.
The General summary:
foreach can traverse an array, or it can traverse an object. objects can only list the properties of the public, and if you want to list the protected attributes by foreach, you can let class inherit iterator and implement the methods in which the foreach iterates through a class in accordance with the iterator of the class implementation.
-------------------------------------------------------------
PDO's Problem:
Pdo::query () returns the object Pdostatement (inherited traversable this null interface, which must be implemented by the iterator or Iteratoraggregate interface).
Pdostatement implements the method of iterator interface, the implementation of which is not public-decorated properties, which store the query result set.
At this point, the execution of foreach ($db->query (' sql.. ') as $row) is clear.