473,837 Members | 1,993 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

safe to delete elements of array in foreach

Is it safe to remove elements from an array that foreach is working on?
(normally this is not the case but not sure in php) If so is there an
efficient way to handle it? (I could add the indexes to a temp array and
delete afterwards if necessary but since I'm actually working in a nested
situation this could get a little messy. I guess I could set there values to
null and remove them afterwards?

Thanks,
Jon
May 18 '07
29 4264
At Fri, 18 May 2007 20:10:57 -0700, ZeldorBlat let his monkeys type:
>============== ====

This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."
Okay, well, uhmmm, not so well hidden then.

Try unsetting and/or changing values in a referenced array foreach:
You might not end u with what you expect. I repeated the code in my other
reply, now operating on $value directly:

$array=array('j ohn','james','d elilah','mary') ;
foreach ($array as $key=>&$value) {
if ($value == 'delilah') {
$value ='samson';
}
elseif ($value=='james ') {
$value = null;;
}
echo "$key =$value".NEWLIN E;
}

foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
}
Output:
0 =john
1 =>
2 =samson
3 =mary
0 =john
1 =>
2 =samson
3 =samson // !!!

Must be some logic for this, but I fail to see it right now.

Sh.
May 19 '07 #11

"ZeldorBlat " <ze********@gma il.comwrote in message
news:11******** **************@ u30g2000hsc.goo glegroups.com.. .
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
>ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
"ZeldorBla t" <zeldorb...@gma il.comwrote in message
news:11**** *************** **@p77g2000hsh. googlegroups.co m...
On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
>Is it safe to remove elements from an array that foreach is
>working on?
>(normall y this is not the case but not sure in php) If so is there
>an
>efficien t way to handle it? (I could add the indexes to a temp
>array and
>delete afterwards if necessary but since I'm actually working in a
>nested
>situatio n this could get a little messy. I guess I could set there
>values
>to
>null and remove them afterwards?
>Thanks,
>Jon
Why don't you try it and see what happens?
Um... cause I did... but that doesn't mean much. Just cause someone
tries
something doesn't prove that it will always work like that...
got any more bright ideas?
Or is the question to hard for you?
No, the question is not to (sic) hard for me. But, as you've already
discovered, it isn't that difficult to test, either.
Sorry, I agree with Jon on this one.
>I make it a habit not to delete entries in a foreach() loop. Rather,
I
build an array of keys I want to delete, and after the loop ends,
delete
the entries from my delete array.
>I don't know whether an operation like this is guaranteed to work in
PHP
- I've never seen it documented, so I suspect not. And just because
it
works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different
conditions.
>--
============== ====
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@attg lobal.net
============== ====
I never said I disagreed with him -- in fact I, too, generally don't
delete elements inside a foreach. However, I will say that when I
have done it things seem to work as expected. I guess it all comes
down to whether or not the array's internal pointer is modified when
you unset the element it's pointing to (I suspect it isn't).
I see a lot of questions in these newsgroups that look something like,
"What happens if I do X?" or "In PHP is this code valid?" The point I
was trying to make (and apparently Jon took offense to it) was that
it's easy enough to just try it and see what happens. Software is
just that: soft. It can be changed easily enough :)

Yes, and in a case like this that change can break his code.

As I said - I've never seen it documented that this is valid. Maybe it
is and I missed it; I really don't know.

But this isn't the same as a lot of other "try it and find out"
questions. In this case it's a known problem in other programming
languages, and if it is documented that this should or should not work,
no one has pointed anyone to it.

And until I see something from the PHP developers saying it is OK, I
wouldn't do it.

--
============== ====
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@attg lobal.net
============== ====

This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."

So unsetting a value in the original array should not affect the copy
that foreach is working on.

Your right. I saw this after the fact after I did try it out and compared it
with a for loop. The foreach worked while the for loop didn't. Then I went
to the manual and saw that it worked on a copy.

So in this case it should work just fine. The for looped version actually
doesn't work and does give the problem I suspected. (thought I sent a post
a bout it though).

So unless they go change how foreach works in a newer version I think it
will be safe. I'm still trying to get used to php as it does a lot of things
differently than I'm used to.

The issue with "trying it out" is that in things like this you can't be sure
since its a implementation artifact... The only way to know is to know that
foreach is working on a copy. Of course maybe one could realize that by
doing a few examples but when usually one doesn't want to rely on what they
think is going on in this sorta situation and needs to know the facts.

Of course now I know its completely safe which was my original question ;)
It came from the manual which is where I should have looked in the fist
place(I did but I guess I skipped over that part ;/

Thanks,
Jon
May 19 '07 #12
ZeldorBlat wrote:
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
>ZeldorBlat wrote:
>>On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
>"ZeldorBla t" <zeldorb...@gma il.comwrote in message
>news:11*** *************** ***@p77g2000hsh .googlegroups.c om...
>>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>wrote:
>>>Is it safe to remove elements from an array that foreach is working on?
>>>(normall y this is not the case but not sure in php) If so is there an
>>>efficien t way to handle it? (I could add the indexes to a temp array and
>>>delete afterwards if necessary but since I'm actually working in a nested
>>>situatio n this could get a little messy. I guess I could set there values
>>>to
>>>null and remove them afterwards?
>>>Thanks ,
>>>Jon
>>Why don't you try it and see what happens?
>Um... cause I did... but that doesn't mean much. Just cause someone tries
>somethin g doesn't prove that it will always work like that...
>got any more bright ideas?
>Or is the question to hard for you?
No, the question is not to (sic) hard for me. But, as you've already
discovere d, it isn't that difficult to test, either.
Sorry, I agree with Jon on this one.
I make it a habit not to delete entries in a foreach() loop. Rather, I
build an array of keys I want to delete, and after the loop ends, delete
the entries from my delete array.
I don't know whether an operation like this is guaranteed to work in PHP
- I've never seen it documented, so I suspect not. And just because it
works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different conditions.
--
============ ======
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@at tglobal.net
============ ======
I never said I disagreed with him -- in fact I, too, generally don't
delete elements inside a foreach. However, I will say that when I
have done it things seem to work as expected. I guess it all comes
down to whether or not the array's internal pointer is modified when
you unset the element it's pointing to (I suspect it isn't).
I see a lot of questions in these newsgroups that look something like,
"What happens if I do X?" or "In PHP is this code valid?" The point I
was trying to make (and apparently Jon took offense to it) was that
it's easy enough to just try it and see what happens. Software is
just that: soft. It can be changed easily enough :)
Yes, and in a case like this that change can break his code.

As I said - I've never seen it documented that this is valid. Maybe it
is and I missed it; I really don't know.

But this isn't the same as a lot of other "try it and find out"
questions. In this case it's a known problem in other programming
languages, and if it is documented that this should or should not work,
no one has pointed anyone to it.

And until I see something from the PHP developers saying it is OK, I
wouldn't do it.

--
============== ====
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@attg lobal.net
============== ====

This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."

So unsetting a value in the original array should not affect the copy
that foreach is working on.
I read that as just the opposite - changes in the copy do not affect the
original array.

It doesn't say how often the copy is refreshed from the original array -
or when changes in the original are reflected in the copy.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #13
Jon Slaughter wrote:
"ZeldorBlat " <ze********@gma il.comwrote in message
news:11******** **************@ u30g2000hsc.goo glegroups.com.. .
>On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
>>ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
ZeldorBla t wrote:
>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>wrote:
>>"ZeldorBl at" <zeldorb...@gma il.comwrote in message
>>news:11** *************** ****@p77g2000hs h.googlegroups. com...
>>>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>>wrote:
>>>>Is it safe to remove elements from an array that foreach is
>>>>worki ng on?
>>>>(normal ly this is not the case but not sure in php) If so is there
>>>>an
>>>>efficie nt way to handle it? (I could add the indexes to a temp
>>>>array and
>>>>delet e afterwards if necessary but since I'm actually working in a
>>>>neste d
>>>>situati on this could get a little messy. I guess I could set there
>>>>value s
>>>>to
>>>>null and remove them afterwards?
>>>>Thank s,
>>>>Jon
>>>Why don't you try it and see what happens?
>>Um... cause I did... but that doesn't mean much. Just cause someone
>>tries
>>somethi ng doesn't prove that it will always work like that...
>>got any more bright ideas?
>>Or is the question to hard for you?
>No, the question is not to (sic) hard for me. But, as you've already
>discovered , it isn't that difficult to test, either.
Sorry, I agree with Jon on this one.
I make it a habit not to delete entries in a foreach() loop. Rather,
I
build an array of keys I want to delete, and after the loop ends,
delete
the entries from my delete array.
I don't know whether an operation like this is guaranteed to work in
PHP
- I've never seen it documented, so I suspect not. And just because
it
works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different
condition s.
--
=========== =======
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@a ttglobal.net
=========== =======
I never said I disagreed with him -- in fact I, too, generally don't
delete elements inside a foreach. However, I will say that when I
have done it things seem to work as expected. I guess it all comes
down to whether or not the array's internal pointer is modified when
you unset the element it's pointing to (I suspect it isn't).
I see a lot of questions in these newsgroups that look something like,
"What happens if I do X?" or "In PHP is this code valid?" The point I
was trying to make (and apparently Jon took offense to it) was that
it's easy enough to just try it and see what happens. Software is
just that: soft. It can be changed easily enough :)
Yes, and in a case like this that change can break his code.

As I said - I've never seen it documented that this is valid. Maybe it
is and I missed it; I really don't know.

But this isn't the same as a lot of other "try it and find out"
questions. In this case it's a known problem in other programming
languages, and if it is documented that this should or should not work,
no one has pointed anyone to it.

And until I see something from the PHP developers saying it is OK, I
wouldn't do it.

--
============= =====
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@att global.net
============= =====
This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."

So unsetting a value in the original array should not affect the copy
that foreach is working on.


Your right. I saw this after the fact after I did try it out and compared it
with a for loop. The foreach worked while the for loop didn't. Then I went
to the manual and saw that it worked on a copy.

So in this case it should work just fine. The for looped version actually
doesn't work and does give the problem I suspected. (thought I sent a post
a bout it though).

So unless they go change how foreach works in a newer version I think it
will be safe. I'm still trying to get used to php as it does a lot of things
differently than I'm used to.

The issue with "trying it out" is that in things like this you can't be sure
since its a implementation artifact... The only way to know is to know that
foreach is working on a copy. Of course maybe one could realize that by
doing a few examples but when usually one doesn't want to rely on what they
think is going on in this sorta situation and needs to know the facts.

Of course now I know its completely safe which was my original question ;)
It came from the manual which is where I should have looked in the fist
place(I did but I guess I skipped over that part ;/

Thanks,
Jon

Jon,

I disagree it's "completely safe". All this is saying is that the
changes to the copy will not affect the original. It says nothing about
what changes to the original will affect.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #14
Schraalhans Keukenmeester wrote:
At Fri, 18 May 2007 21:05:36 -0400, Jerry Stuckle let his monkeys type:
>ZeldorBlat wrote:
>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
"ZeldorBla t" <zeldorb...@gma il.comwrote in message

news:11***** *************** *@p77g2000hsh.g ooglegroups.com ...

On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
>Is it safe to remove elements from an array that foreach is working on?
>(normall y this is not the case but not sure in php) If so is there an
>efficien t way to handle it? (I could add the indexes to a temp array and
>delete afterwards if necessary but since I'm actually working in a nested
>situatio n this could get a little messy. I guess I could set there values
>to
>null and remove them afterwards?
>Thanks,
>Jon
Why don't you try it and see what happens?
Um... cause I did... but that doesn't mean much. Just cause someone tries
something doesn't prove that it will always work like that...

got any more bright ideas?

Or is the question to hard for you?
No, the question is not to (sic) hard for me. But, as you've already
discovered, it isn't that difficult to test, either.
Sorry, I agree with Jon on this one.

I make it a habit not to delete entries in a foreach() loop. Rather, I
build an array of keys I want to delete, and after the loop ends, delete
the entries from my delete array.

I don't know whether an operation like this is guaranteed to work in PHP
- I've never seen it documented, so I suspect not. And just because it
works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different conditions.

I agree 100% with you not to rely on undocumented 'features'.
Just out of curiosity I took this one step further and discovered the
following (again, can't rely on this to hold true unless it's documented
somewhere, well hidden):

<?PHP
$array=array('j ohn','james','d elilah','mary') ;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
if ($value == 'delilah') {
$array[$key]='samson';
}
elseif ($value=='james ') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
}
?>
0 =john
1 =james
2 =delilah
3 =mary

0 =john
2 =samson
3 =mary

The foreach loop operates on a copy of the array
The original array remains in scope
Current($array) points to the first element throughout the loop

I'd think setting elements to NULL directly in the array isn't any better,
you're still relying on the same 'feature'.

Sh
Yes, foreach() works on a copy. But while the manual indicates changes
to the copy don't affect the original - they say nothing about when
changes to the original will affect the copy.

When I want to delete entries, I keep an array of keys to delete. When
I'm done with the array itself, I go through the second array and delete
all indicated keys.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #15
Rami Elomaa wrote:
Jon Slaughter kirjoitti:
>Is it safe to remove elements from an array that foreach is working
on? (normally this is not the case but not sure in php) If so is there
an efficient way to handle it? (I could add the indexes to a temp
array and delete afterwards if necessary but since I'm actually
working in a nested situation this could get a little messy. I guess I
could set there values to null and remove them afterwards?

$a = range(0,10);
foreach($a as $key =$val)
if($val%2)
unset($a[$key]);

I've done something like this and have never had any problems. I don't
see the threats in this kind of thing, can you explain me what you think
that might be unsafe in this method?
It is never safe to assume you can delete (or in this case unset)
something while it is in use. Results are usually very unpredictable.
It may work now - but may fail when you upgrade PHP, when you
restructure your code a little, or even under heavier load. The latter
two are spectacularly difficult to find!

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #16

"Jerry Stuckle" <js*******@attg lobal.netwrote in message
news:lc******** *************** *******@comcast .com...
Jon Slaughter wrote:
>"ZeldorBlat " <ze********@gma il.comwrote in message
news:11******* *************** @u30g2000hsc.go oglegroups.com. ..
>>On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
>ZeldorBl at wrote:
>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>wrote:
>>>"ZeldorB lat" <zeldorb...@gma il.comwrote in message
>>>news:11* *************** *****@p77g2000h sh.googlegroups .com...
>>>>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>>>wrote :
>>>>>Is it safe to remove elements from an array that foreach is
>>>>>workin g on?
>>>>>(norma lly this is not the case but not sure in php) If so is
>>>>>ther e an
>>>>>effici ent way to handle it? (I could add the indexes to a temp
>>>>>arra y and
>>>>>dele te afterwards if necessary but since I'm actually working in
>>>>>a nested
>>>>>situat ion this could get a little messy. I guess I could set
>>>>>ther e values
>>>>>to
>>>>>null and remove them afterwards?
>>>>>Thanks ,
>>>>>Jon
>>>>Why don't you try it and see what happens?
>>>Um... cause I did... but that doesn't mean much. Just cause
>>>someon e tries
>>>somethin g doesn't prove that it will always work like that...
>>>got any more bright ideas?
>>>Or is the question to hard for you?
>>No, the question is not to (sic) hard for me. But, as you've
>>already
>>discovere d, it isn't that difficult to test, either.
>Sorry, I agree with Jon on this one.
>I make it a habit not to delete entries in a foreach() loop. Rather,
>I
>build an array of keys I want to delete, and after the loop ends,
>delete
>the entries from my delete array.
>I don't know whether an operation like this is guaranteed to work in
>PHP
>- I've never seen it documented, so I suspect not. And just because
>it
>works in one release under a certain set of conditions is not a
>guarante e it will work on another release or under different
>conditions .
>--
>========== ========
>Remove the "x" from my email address
>Jerry Stuckle
>JDS Computer Training Corp.
>jstuck...@ attglobal.net
>========== ========
I never said I disagreed with him -- in fact I, too, generally don't
delete elements inside a foreach. However, I will say that when I
have done it things seem to work as expected. I guess it all comes
down to whether or not the array's internal pointer is modified when
you unset the element it's pointing to (I suspect it isn't).
I see a lot of questions in these newsgroups that look something like,
"What happens if I do X?" or "In PHP is this code valid?" The point I
was trying to make (and apparently Jon took offense to it) was that
it's easy enough to just try it and see what happens. Software is
just that: soft. It can be changed easily enough :)
Yes, and in a case like this that change can break his code.

As I said - I've never seen it documented that this is valid. Maybe it
is and I missed it; I really don't know.

But this isn't the same as a lot of other "try it and find out"
questions. In this case it's a known problem in other programming
languages, and if it is documented that this should or should not work,
no one has pointed anyone to it.

And until I see something from the PHP developers saying it is OK, I
wouldn't do it.

--
============ ======
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@at tglobal.net
============ ======
This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."

So unsetting a value in the original array should not affect the copy
that foreach is working on.


Your right. I saw this after the fact after I did try it out and compared
it with a for loop. The foreach worked while the for loop didn't. Then I
went to the manual and saw that it worked on a copy.

So in this case it should work just fine. The for looped version
actually doesn't work and does give the problem I suspected. (thought I
sent a post a bout it though).

So unless they go change how foreach works in a newer version I think it
will be safe. I'm still trying to get used to php as it does a lot of
things differently than I'm used to.

The issue with "trying it out" is that in things like this you can't be
sure since its a implementation artifact... The only way to know is to
know that foreach is working on a copy. Of course maybe one could realize
that by doing a few examples but when usually one doesn't want to rely on
what they think is going on in this sorta situation and needs to know the
facts.

Of course now I know its completely safe which was my original question
;) It came from the manual which is where I should have looked in the
fist place(I did but I guess I skipped over that part ;/

Thanks,
Jon

Jon,

I disagree it's "completely safe". All this is saying is that the changes
to the copy will not affect the original. It says nothing about what
changes to the original will affect.

Well, your right. I assume that when it says copy it means a deep copy. If
so then essentially its working on a different variable...

If it was C/C++ then you would definitely have to worry about that sorta
stuff and chances are would have to buffer the deletes or use some other
method unless you can be absolutely sure its a deep copy.

The more one dives into these sorta of things the more vague the solution
is. It should be completely spelled out in the manual but its not ;/ These
times of issues usually are a big deal and technically one can't assume
anything but its working and I'm about 95% sure that I'm right in the way it
works so I'm just going to assume that until otherwise. Obviously no one
really seems to know the answer completely it seems ;/
May 20 '07 #17

"Jerry Stuckle" <js*******@attg lobal.netwrote in message
news:lc******** *************** *******@comcast .com...
Schraalhans Keukenmeester wrote:
>At Fri, 18 May 2007 21:05:36 -0400, Jerry Stuckle let his monkeys type:
>>ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
"ZeldorBlat " <zeldorb...@gma il.comwrote in message
>
news:11**** *************** **@p77g2000hsh. googlegroups.co m...
>
>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>wrote:
>>Is it safe to remove elements from an array that foreach is working
>>on?
>>(normal ly this is not the case but not sure in php) If so is there
>>an
>>efficie nt way to handle it? (I could add the indexes to a temp array
>>and
>>delete afterwards if necessary but since I'm actually working in a
>>nested
>>situati on this could get a little messy. I guess I could set there
>>values
>>to
>>null and remove them afterwards?
>>Thanks,
>>Jon
>Why don't you try it and see what happens?
Um... cause I did... but that doesn't mean much. Just cause someone
tries
something doesn't prove that it will always work like that...
>
got any more bright ideas?
>
Or is the question to hard for you?
No, the question is not to (sic) hard for me. But, as you've already
discovered , it isn't that difficult to test, either.

Sorry, I agree with Jon on this one.

I make it a habit not to delete entries in a foreach() loop. Rather, I
build an array of keys I want to delete, and after the loop ends, delete
the entries from my delete array.

I don't know whether an operation like this is guaranteed to work in
PHP - I've never seen it documented, so I suspect not. And just because
it works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different conditions.

I agree 100% with you not to rely on undocumented 'features'.
Just out of curiosity I took this one step further and discovered the
following (again, can't rely on this to hold true unless it's documented
somewhere, well hidden):

<?PHP
$array=array(' john','james',' delilah','mary' );
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
if ($value == 'delilah') {
$array[$key]='samson';
} elseif ($value=='james ') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
}
?>
0 =john
1 =james
2 =delilah
3 =mary

0 =john
2 =samson
3 =mary

The foreach loop operates on a copy of the array
The original array remains in scope
Current($array ) points to the first element throughout the loop

I'd think setting elements to NULL directly in the array isn't any
better,
you're still relying on the same 'feature'.

Sh

Yes, foreach() works on a copy. But while the manual indicates changes to
the copy don't affect the original - they say nothing about when changes
to the original will affect the copy.
since its a copy the original should effect in any way the copy?

I could only see this if the copy is not a deep copy.... but in php all
copies are deep?
May 20 '07 #18
Jon Slaughter wrote:
"Jerry Stuckle" <js*******@attg lobal.netwrote in message
news:lc******** *************** *******@comcast .com...
>Jon Slaughter wrote:
>>"ZeldorBlat " <ze********@gma il.comwrote in message
news:11****** *************** *@u30g2000hsc.g ooglegroups.com ...
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
ZeldorBla t wrote:
>On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attg lobal.netwrote:
>>ZeldorBla t wrote:
>>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>>wrote:
>>>>"Zeldor Blat" <zeldorb...@gma il.comwrote in message
>>>>news:11 *************** ******@p77g2000 hsh.googlegroup s.com...
>>>>>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>>>>wrot e:
>>>>>>Is it safe to remove elements from an array that foreach is
>>>>>>worki ng on?
>>>>>>(norm ally this is not the case but not sure in php) If so is
>>>>>>the re an
>>>>>>effic ient way to handle it? (I could add the indexes to a temp
>>>>>>arr ay and
>>>>>>delet e afterwards if necessary but since I'm actually working in
>>>>>>a nested
>>>>>>situa tion this could get a little messy. I guess I could set
>>>>>>the re values
>>>>>>to
>>>>>>nul l and remove them afterwards?
>>>>>>Thank s,
>>>>>>Jon
>>>>>Why don't you try it and see what happens?
>>>>Um... cause I did... but that doesn't mean much. Just cause
>>>>someo ne tries
>>>>somethi ng doesn't prove that it will always work like that...
>>>>got any more bright ideas?
>>>>Or is the question to hard for you?
>>>No, the question is not to (sic) hard for me. But, as you've
>>>alread y
>>>discover ed, it isn't that difficult to test, either.
>>Sorry, I agree with Jon on this one.
>>I make it a habit not to delete entries in a foreach() loop. Rather,
>>I
>>build an array of keys I want to delete, and after the loop ends,
>>delete
>>the entries from my delete array.
>>I don't know whether an operation like this is guaranteed to work in
>>PHP
>>- I've never seen it documented, so I suspect not. And just because
>>it
>>works in one release under a certain set of conditions is not a
>>guarant ee it will work on another release or under different
>>condition s.
>>--
>>========= =========
>>Remove the "x" from my email address
>>Jerry Stuckle
>>JDS Computer Training Corp.
>>jstuck... @attglobal.net
>>========= =========
>I never said I disagreed with him -- in fact I, too, generally don't
>delete elements inside a foreach. However, I will say that when I
>have done it things seem to work as expected. I guess it all comes
>down to whether or not the array's internal pointer is modified when
>you unset the element it's pointing to (I suspect it isn't).
>I see a lot of questions in these newsgroups that look something like,
>"What happens if I do X?" or "In PHP is this code valid?" The point I
>was trying to make (and apparently Jon took offense to it) was that
>it's easy enough to just try it and see what happens. Software is
>just that: soft. It can be changed easily enough :)
Yes, and in a case like this that change can break his code.
>
As I said - I've never seen it documented that this is valid. Maybe it
is and I missed it; I really don't know.
>
But this isn't the same as a lot of other "try it and find out"
questions . In this case it's a known problem in other programming
languages , and if it is documented that this should or should not work,
no one has pointed anyone to it.
>
And until I see something from the PHP developers saying it is OK, I
wouldn't do it.
>
--
=========== =======
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstuck...@a ttglobal.net
=========== =======
This suggests that it's safe (from <http://www.php.net/foreach>):

"Unless the array is referenced, foreach operates on a copy of the
specified array and not the array itself. Therefore, the array pointer
is not modified as with the each() construct, and changes to the array
element returned are not reflected in the original array."

So unsetting a value in the original array should not affect the copy
that foreach is working on.

Your right. I saw this after the fact after I did try it out and compared
it with a for loop. The foreach worked while the for loop didn't. Then I
went to the manual and saw that it worked on a copy.

So in this case it should work just fine. The for looped version
actually doesn't work and does give the problem I suspected. (thought I
sent a post a bout it though).

So unless they go change how foreach works in a newer version I think it
will be safe. I'm still trying to get used to php as it does a lot of
things differently than I'm used to.

The issue with "trying it out" is that in things like this you can't be
sure since its a implementation artifact... The only way to know is to
know that foreach is working on a copy. Of course maybe one could realize
that by doing a few examples but when usually one doesn't want to rely on
what they think is going on in this sorta situation and needs to know the
facts.

Of course now I know its completely safe which was my original question
;) It came from the manual which is where I should have looked in the
fist place(I did but I guess I skipped over that part ;/

Thanks,
Jon
Jon,

I disagree it's "completely safe". All this is saying is that the changes
to the copy will not affect the original. It says nothing about what
changes to the original will affect.


Well, your right. I assume that when it says copy it means a deep copy. If
so then essentially its working on a different variable...

If it was C/C++ then you would definitely have to worry about that sorta
stuff and chances are would have to buffer the deletes or use some other
method unless you can be absolutely sure its a deep copy.

The more one dives into these sorta of things the more vague the solution
is. It should be completely spelled out in the manual but its not ;/ These
times of issues usually are a big deal and technically one can't assume
anything but its working and I'm about 95% sure that I'm right in the way it
works so I'm just going to assume that until otherwise. Obviously no one
really seems to know the answer completely it seems ;/

Yes, it does say a copy. But it says nothing about then the copy is
refreshed from the original.

Typically manuals indicate what is valid - but not what is not valid.
There are too may possibilities to cover.

In 40 years of programming, I've learned never to assume something.
I've been burned too many times. And it makes you look very bad to your
clients.
--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #19
Jon Slaughter wrote:
"Jerry Stuckle" <js*******@attg lobal.netwrote in message
news:lc******** *************** *******@comcast .com...
>Schraalhans Keukenmeester wrote:
>>At Fri, 18 May 2007 21:05:36 -0400, Jerry Stuckle let his monkeys type:

ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
wrote:
>"ZeldorBla t" <zeldorb...@gma il.comwrote in message
>>
>news:11*** *************** ***@p77g2000hsh .googlegroups.c om...
>>
>>On May 18, 11:05 am, "Jon Slaughter" <Jon_Slaugh...@ Hotmail.com>
>>wrote:
>>>Is it safe to remove elements from an array that foreach is working
>>>on?
>>>(normall y this is not the case but not sure in php) If so is there
>>>an
>>>efficien t way to handle it? (I could add the indexes to a temp array
>>>and
>>>delete afterwards if necessary but since I'm actually working in a
>>>nested
>>>situatio n this could get a little messy. I guess I could set there
>>>values
>>>to
>>>null and remove them afterwards?
>>>Thanks ,
>>>Jon
>>Why don't you try it and see what happens?
>Um... cause I did... but that doesn't mean much. Just cause someone
>tries
>somethin g doesn't prove that it will always work like that...
>>
>got any more bright ideas?
>>
>Or is the question to hard for you?
No, the question is not to (sic) hard for me. But, as you've already
discovere d, it isn't that difficult to test, either.
>
Sorry, I agree with Jon on this one.

I make it a habit not to delete entries in a foreach() loop. Rather, I
build an array of keys I want to delete, and after the loop ends, delete
the entries from my delete array.

I don't know whether an operation like this is guaranteed to work in
PHP - I've never seen it documented, so I suspect not. And just because
it works in one release under a certain set of conditions is not a
guarantee it will work on another release or under different conditions.
I agree 100% with you not to rely on undocumented 'features'.
Just out of curiosity I took this one step further and discovered the
following (again, can't rely on this to hold true unless it's documented
somewhere, well hidden):

<?PHP
$array=array( 'john','james', 'delilah','mary ');
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
if ($value == 'delilah') {
$array[$key]='samson';
} elseif ($value=='james ') {
unset($arra y[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLIN E;
}
?>
0 =john
1 =james
2 =delilah
3 =mary

0 =john
2 =samson
3 =mary

The foreach loop operates on a copy of the array
The original array remains in scope
Current($arra y) points to the first element throughout the loop

I'd think setting elements to NULL directly in the array isn't any
better,
you're still relying on the same 'feature'.

Sh
Yes, foreach() works on a copy. But while the manual indicates changes to
the copy don't affect the original - they say nothing about when changes
to the original will affect the copy.

since its a copy the original should effect in any way the copy?

I could only see this if the copy is not a deep copy.... but in php all
copies are deep?

There is nothing indicating when the copy is updated from the original.
It might be only at the beginning, everything through the loop or
anything else.

It's not documented - so you can't depend on the operation.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
May 20 '07 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
3705
by: deko | last post by:
I'm kind of lost on this one - I need to modify 2 files based on user input: $data_array = file($data_file); $counter_array = file($counter_file); // There is a line-for-line relationship between the data and counter files //for example, if the 3rd line in the counter file is deleted, //so also must the 3rd line of the data file be deleted. // Each line of the data_file has 4 items: //date|ip_address|user_id|url for ( $i=0; $i <...
8
2221
by: Generic Usenet Account | last post by:
To settle the dispute regarding what happens when an "erase" method is invoked on an STL container (i.e. whether the element is merely removed from the container or whether it also gets deleted in the process), I looked up the STL code. Erase certainly does not delete the memory associated with the element. However, it appears that the destructor on the element is invoked. I wonder why it has to be this way. In my opinion, this renders...
3
4768
by: Rik | last post by:
Hello, first of all, my provider sucks, newsserver is down for the #nth time now, offcourse when I have an urgent question.... So this will be me first time using Google Groups, forgive me if something goes wrong. The problem at hand: In a restricted area I let a user upload an image, no problem The image gets scaled down with imagecopyresampled(), and stored with imagejpeg($resized_img,'/path/to/target/image.jpg')
1
2317
by: kamal kothandaraman | last post by:
Is it safe to remove elements from an array that foreach is working on? (normally this is not the case but not sure in php) If so is there an efficient way to handle it? (I could add the indexes to a temp array and delete afterwards if necessary but since I'm actually working in a nested situation this could get a little messy. I guess I could set there values to regards, K. Kothandaraman
3
2687
by: SM | last post by:
Hello, I have an array that holds images path of cd covers. The array looks like this: $cd = array( 589=>'sylver.jpg', 782=>'bigone.jpg', 158=>'dime.jpg' );
0
9846
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10890
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10581
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10634
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10279
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9416
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7819
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5855
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3127
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.