[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Помогите! Объект не хочет возвращать в цик foreach
Гость_Юрий
Есть класс:


class a implements Iterator {

public $_config = array();


private function __get($key) {

return $this->_config[$key];

}


public function __set($key, $data) {

$this->_config[$key] = $data;

}


public function &current() {

return $this->_config[$this->key()];

}


public function key() {

return key($this->_config);

}


public function next() {

next($this->_config);

}


public function rewind() {

reset($this->_config);

}


public function valid() {

return (boolean) $this->current();

}


}



Есть клиентский код:


$obj = new a();
$obj->a = 'a';
$obj->b = 'b';
$obj->c = 'c';

foreach ($obj as $key => $value) $value = 'w';


А вот дамп внутреннего массива после цикла:


Array
(
[
a] => a
[b] => b
[c] => c
[] =>
)



Формально всё вроде бьёт, но откуда взялся пустой 4-й элемент, и почему первые три элемента не равны 'w'?



Спустя 16 минут, 14 секунд (17.06.2011 - 14:24) Renden написал(а):
Гость_Юрий
Я в ооп хоть и новичек, но я думаю что перебирать ОБЬЕКТ неправильно, тк это обьект а не массив)
Помоему ты должен делать так:

$obj = new a();
$obj->a = 'a';
$obj->b = 'b';
$obj->c = 'c';

foreach ($obj->_config as $key => $value) $value = 'w';

Спустя 6 минут, 57 секунд (17.06.2011 - 14:31) linker написал(а):
Во-первых, внимательно прочти документацию про интерфейс Iterator и сравни со своей реализацией. Во-вторых, даже с нативным массивом, в цикле
foreach ($arr as $key => $value)
$value = 'w';
ничего не произойдёт, для этого нужно писать
foreach ($arr as $key => &$value)
$value = 'w';
но в случае с итератором - это не работает.

Renden
Итератор для того и создан, чтобы с объектом работать как с массивом. Для практически полной эмуляции нужно еще реализовать интерфейс ArrayAccess.

Спустя 2 минуты, 8 секунд (17.06.2011 - 14:33) Renden написал(а):
Ого, Iterator можно перебирать, омг..

linker
Незнал, буду знать smile.gif

Спустя 9 минут, 22 секунды (17.06.2011 - 14:42) Гость_Юрий написал(а):
А как же тогда быть, если очень нужно, чтобы объект можно было модифицировать в цикле?

Спустя 29 секунд (17.06.2011 - 14:43) linker написал(а):
Ах да, для топик стартера поправка
public function current() 
{
return $this->key() ? $this->_config[$this->key()] : null;
}
foreach ($obj as $key => $value) 
$obj->$key = 'w';
Итератор хоть и эмулирует работу массива, но не до конца.

Спустя 2 минуты, 30 секунд (17.06.2011 - 14:45) Гость_Юрий написал(а):
А, ну понятно. Уже ответил. Нужно ещё реализовать ArrayAccess. Но это будет, конечно не так красиво, как хотелось бы. )

Спустя 1 минута, 19 секунд (17.06.2011 - 14:47) linker написал(а):
Реализуешь ArrayAccess, будет больше красивостей, например
$obj[] = 'd';

Спустя 2 минуты, 24 секунды (17.06.2011 - 14:49) Гость_Юрий написал(а):
Спасибо! Вопрос полностью исчерпан. )

Спустя 15 минут, 53 секунды (17.06.2011 - 15:05) Гость_Юрий написал(а):
Для пущей достоверности, ещё хорошо бы интерфейс Countable реализовать. )

Спустя 12 минут, 23 секунды (17.06.2011 - 15:17) linker написал(а):
Можно, а можно сразу использовать ArrayIterator. Кстати там же нашёл то, что тебе нужно
Цитата
If you want to make your ArrayIterator support foreach loops with PHP's & operator, such as

<?php
    foreach($list as &$item) {
        ....
    }
?>

You will need to pass the array to ArrayIterator by reference:

<?php
    new ArrayIterator(&$array);
?>

Спустя 1 день, 19 часов, 28 минут (19.06.2011 - 10:45) Гость_lekafe написал(а):
Четвертый элемент по моему возникает из за того что ты не сделал вот так
 private $_config = array();


Спустя 8 часов, 20 минут, 25 секунд (19.06.2011 - 19:06) linker написал(а):
Четвёртый элемент возникает из-за
return $this->_config[$this->key()];
в методе current(). Если интересно почему, могу объяснить.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.