Page 71 - 4636
P. 71
Ця реалізація робить спробу включити файл з ім'ям, що збігається з ім'ям класу.
Реалізація ітераторів та ітерації
Виключно корисна характеристика об'єктно-орієнтованого механізму РНР пов'язана з можливістю
використання циклу foreach() для перебору атрибутів об'єкта подібно до того, як це робиться у
відношенні елементів масиву. Нижче показаний приклад:
class myClass { public $а="5"; public $b="7";
public $c="9"; } $x = new myClass;
foreach ($x as $attribute) { echo
$attribute."<br />";
}
Якщо потрібно отримати більш складну поведінку, необхідно створити ітератор (iterator). Для цього
реалізуйте в класі, в якому потрібно виконати перебір, інтерфейс IteratorAggregate, і напишіть метод
getlterator, повертає екземпляр класу ітератора. Інтерфейс Iterator містить набір методів, які
також повинні бути реалізовані. Приклад реалізації класу та ітератора показано у лістингу 2.7.
Лістинг 2.7. iterator .php - приклад базового класу і класуітератора
<?phpклас Objectlterator iplementsIterator {
private $obj;
private $count;
private $currentlndex;function_construct($obj) {$this->obj =
$obj;$this->count = count($this->obj->data);}function rewind () {$this-
>currentlndex =0;}function valid() {
return $this->currentlndex < $this->count;}
function key() {
return $this->currentlndex;}function current() {
return $this->obj->data[$this->currentlndex];}function next() {$this-
>currentlndex++; }}class Object implements IteratorAggregate {
public $data = array(); function __construct ($in) {$this-
>data=$;}function getlterator() ( return new Objectlterator ($this.);
}}SmyObject = new Object (array(2, 4, 6, 8, 10));$myIterator =
$myObject->getIterator();for($myIterator->rewind (); $myIterator-
>valid(); $myIterator->next()) ($key = $myIterator->key();$value =
$myIterator->current();
echo $key." => ".Svalue. "<br />";
}
?>
Клас Objectlterator має набір функцій, необхідний інтерфейсу Iterator.
Конструктор не обов'язковий, проте, очевидно, він являє собою гарне місце для встановлення
кількості итерируемых елементів і посилання на поточний елемент:
функція rewind() повинна встановлювати внутрішній покажчик даних на початок даних;
функція valid() повинна повідомляти, є ще дані в поточній позиції курсору;
функція key() повинна повертати значення покажчика на дані;
функція value() повинна повертати значення, що зберігається за вказівником даних;
функція next() повинна переміщати покажчик всередині даних.
Причина використання такого класу ітератора полягає в тому, що інтерфейс до даних не
змінюється, навіть якщо змінюється уявлення даних. У розглянутому прикладі клас
IteratorAggregate являє собою простий масив. Навіть якщо ви вирішите змінити його, скажімо,
на хеш-таблицю або однозв'язний список, ви все одно зможете користуватися стандартним
інтерфейсом Iterator для його перебору, незважаючи на те, що код реалізації інтерфейсу Iterator
зміниться.
68