note 107533 added to control-structures.foreach
| From: | Voitcus at wp dot pl | Date: | Wed, 15 Feb 2012 20:55:28 +0000 |
| Subject: | note 107533 added to control-structures.foreach | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-186155@lists.php.net to get a copy of this message | ||
You can even iterate through "dynamic" arrays that do not physically exist, but are
objects that implement Iterator interface. They don't need to be stored in memory when foreach
starts.
Consider the array that contains some values (I called it $allValues in the example below) and we
want to have only some of them (eg. the ones that are dividable by 2). I create an object that would
serve as dynamic array, that means it would "dynamically update" its values together with
$allValues. The main advantage is that I store only one array, and it's the only array I
serialize.
An object of MyIter class will not contain any values itself:
<?php
class MyIter implements Iterator { // you can implement ArrayAccess and Countable interfaces too,
this will make class MyIter behave like a "real" array
private $position = 0; // an internal position of the current element
// please note that $position has nothing common with $allValues!
private function getTable(){ // prepare a temporary "static" table of all objects in the
class
global $allValues;
$result=array(); // temporary variable
foreach($allValues as $obj){
if($obj % 2 == 0) // check if the value is even
$result[]=$obj; // if yes, I want it
}
return $result;
}
// the all below declared methods are public and belong to the Iterator interface
function rewind() { // a method to start iterating
$this->position = 0; // just move to the beginning
}
function current() { // retrieves the current element
$table=$this->getTable(); // let us prepare a table
return $table[$this->position]; // and return the current element
}
function key() { // retrieves the current element's key
return $this->position; // this is used by foreach(... as $key=>$value), not important
here
}
function next() { // move to next element
++$this->position;
}
function valid() { // check if the current element is valid (ie. if it exists)
return array_key_exists($this->position, $this->getTable());
}
} // end of class
// now prepare the array of 12 elements
$allValues=array(0,1,2,3,4,5,6,7,8,9,10,11);
//we would like to have a dynamic array of all even values
$iterator=new MyIter();
foreach($iterator as $value){
echo $value."<br />";
}
?>
This will result in:
0
2
4
6
8
10
(You may also like to see what var_dump($iterator) produces).
Another great advantage is that you can modify the main table "on-the-fly" and it has its
impact. Let us modify the last foreach loop:
<?php
// ...all above shall stay as it was
foreach($iterator as $value){
echo $value."<br />";
if($value==6){
$allValues=array(2,3);
echo "I modified source array!<br />";
}
}
?>
This produces now:
0
2
4
6
I modified source array!
However, if you feel it is rather a catastrophic disadvantage (maybe for example, it shows the
values 0, 4, and 6 which were removed when we reached 6), and wish to have a "static"
array that will iterate even in modified objects, just call getTable() in rewind() method and save
it in temporary (private perhaps) field. In my example getTable() is called every iteration, and it
calls another foreach through $allValues, which together might be time-consuming. Consider what you
need.
----
Server IP: 82.177.164.100
Probable Submitter: 89.75.186.180
----
Manual Page -- http://www.php.net/manual/en/control-structures.foreach.php
Edit -- https://master.php.net/note/edit/107533
Del: integrated -- https://master.php.net/note/delete/107533/integrated
Del: useless -- https://master.php.net/note/delete/107533/useless
Del: bad code -- https://master.php.net/note/delete/107533/bad+code
Del: spam -- https://master.php.net/note/delete/107533/spam
Del: non-english -- https://master.php.net/note/delete/107533/non-english
Del: in docs -- https://master.php.net/note/delete/107533/in+docs
Del: other reasons-- https://master.php.net/note/delete/107533
Reject -- https://master.php.net/note/reject/107533
Search -- https://master.php.net/manage/user-notes.php