foreach array passing by reference

.des.

Поставил пиво кому надо ;-)
foreach array passing by reference

вчера столкнулся с новым для меня явлением.
Возможно это уже известно давно, но тем не менее это все таки не совсем прозрачно.
это использование цикла foreach для доступа к элементам массива.
массив у меня следующего вида.
Elements[1..NN][$object]
конструкция.

foreach([$Elements as $id=>$el)
{
$el->someAction(); // некоторый метод объекта который
// изменяет свойства объекта
}
// на выходе получаю тот же самый массив не измененный, как ожидалось.

то есть foreach работает с копиями.. что после недолгих раздумий оказывается вполне логичным. я не долго думаю заменил foreach на for так как массив был у меня не ассоциативный и первый ключ шел подряд 0..NN.
ну а что делать с ассоциативным массивом?
вообще существует ли возможность заставить работать foreach(each) с ссылками?
решение с ассоциативным массивом я вижу только одно
$k=key($Elements);
$el=& Elements[$k];
$el->someAction();
оно единственное?

-------------------------------------------------------------
[ЦВЕТОМ=red]Позже я нашел несколько комментариев в тему наwww.php.net[/ЦВЕТОМ]
PHP:
horst dot beham at gmx dot at
23-Sep-2001 06:58 
 
"foreach" returns a COPY of the values of the array, not a REFERENCE. so "foreach" isn't useful for arrays containing id=>object-ref associations.
 
//------------------------------------------------------------------------------- 
//след. комм. не совсем об этом но тоже интересно.
basil dot hussain at kodakweddings dot com
20-Nov-2001 02:17 

There is some undocumented behaviour with foreach() to do with objects. If you use the following code: 

foreach($myarray as $x->y) { 
... 
} 
On each iteration, $x will be created as an object (of class 'stdClass') with the property y containing the value of the current array element. 
This could catch you out if you type "->" instead of "=>", so beware!
//------------------------------------------------------------------------------- 
Just a small warning about referencing foreach-iterators.
Iterating over an array which contains assosiative arrays can be tricky:

Note this:

$fields=array(
array('name'=>'a name', 'text'=> 'some text'),
array('name'=> 'name2', 'text'=>'more text')
);

foreach( $fields as $key=>$value) {
$nth_field=& $fields[$key];

 # do some thing here

unset($nth_field); #sometimes necessaray
}

Iterating over this array might overwrite the last element of the array by its precessor. DonЃLt know, if this a bug, but closing each iteration by adding the line "unset($nth_field);" will fix this behaviour.

This error gave me a headache for some minutes, so I though, its nice to share it here.

IMO, if the foreach-behaviour is not changed (improved) in near future, to allow iterating by reference, it will be a real argument for perl. The foreach-statement is quiet good for writing small, clean and read-able code (in perl :-) ).
млин... отправить нажал и форум превратил мое сообщение непойми во что (в смысле кодировок) пришлось переписывать
 

AnToXa

prodigy-одаренный ребенок
вроде бы существует вот такая конструкция

PHP:
foreach ($array as $k=&$v) {
  тырым-пырым
}
 

.des.

Поставил пиво кому надо ;-)
хм интересно...
сейчас проверю...
 

Oleg Uskov

Guest
Можно использовать констркуцию:
while(list($key) = each($arr))
{
$arr[$key]->someAction();
}
Эта штуковина будет идти по реальному массиву а не копии
 

su1d

Старожил PHPClubа
можно и так ещё наверное:
PHP:
foreach($arr as $key => $val) {
 echo $arr[$key];
 // или
 $val =& $arr[$key];
 echo $val;
}
 

.des.

Поставил пиво кому надо ;-)
2 АнтоХа.. хм.. не знаю.. но кажется конструкция неверна - не работает она!
2 su1d, 2 Oleg Uskov ну это почти тоже о чем я писал
$k=key($Elements);
$el=& Elements[$k];
$el->someAction();
то есть получение ключа и обращение к изначальном массив по нему.
я так и решил.. вот хотелось бы что то похожее на то что предложил АнтоХа.. но она не работает.. пока у меня
:(
жаль что перед each нельзя поставить &
 

benadin

Guest
$value - Это переменная, содержащая значение элемента массива, как ни крути. Поэтому by reference передавать ее бесполезно.

А вот $arr[$key] - самое оно. А each-ем перебирать или foreach-ем - нету разницы.

Если хочется именно value by reference... Попробуй, как советуют в мануале:
PHP:
array_walk($av, create_function('&$v,$k','$v = $v."mango";'));
Хотя имхо, foreach-ем ничем не хуже, и уж точно не навороченнее!..
 

ONK

Пассивист PHPСluba
А если вот так:

PHP:
foreach([$Elements as $id=>$el) 
{ 
$Elements[$id]->someAction(); // некоторый метод объекта который 
// изменяет свойства объекта 
}
Тут изменения будут вноситься в оригиналы объектов.
тоесть foreach используется именно для перебора ассоциативного массива с неизвестными ключами, а действия производятся над самими объектами...
 
Сверху