By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,264 Members | 1,277 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,264 IT Pros & Developers. It's quick & easy.

safe to delete elements of array in foreach

P: n/a
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 #1
Share this Question
Share on Google+
29 Replies


P: n/a
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?
(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
Why don't you try it and see what happens?

May 18 '07 #2

P: n/a

"ZeldorBlat" <ze********@gmail.comwrote in message
news:11*********************@p77g2000hsh.googlegro ups.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?
(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

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?
May 18 '07 #3

P: n/a
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
"ZeldorBlat" <zeldorb...@gmail.comwrote in message

news:11*********************@p77g2000hsh.googlegro ups.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?
(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
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.

May 18 '07 #4

P: n/a
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
>"ZeldorBlat" <zeldorb...@gmail.comwrote in message

news:11*********************@p77g2000hsh.googlegr oups.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?
(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
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.
js*******@attglobal.net
==================
May 19 '07 #5

P: n/a
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
"ZeldorBlat" <zeldorb...@gmail.comwrote in message
>news:11*********************@p77g2000hsh.googlegr oups.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?
(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
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...@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 :)
May 19 '07 #6

P: n/a
ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>ZeldorBlat wrote:
>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
"ZeldorBlat" <zeldorb...@gmail.comwrote in message
news:11*********************@p77g2000hsh.google groups.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?
>(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
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...@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.
js*******@attglobal.net
==================
May 19 '07 #7

P: n/a
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
"ZeldorBlat" <zeldorb...@gmail.comwrote in message
news:11*********************@p77g2000hsh.google groups.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?
(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
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...@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...@attglobal.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.

May 19 '07 #8

P: n/a
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?

--
Ra*********@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
May 19 '07 #9

P: n/a
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...@gmail.comwrote in message

news:11*********************@p77g2000hsh.googleg roups.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?
(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
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".NEWLINE;
if ($value == 'delilah') {
$array[$key]='samson';
}
elseif ($value=='james') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLINE;
}
?>
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
May 19 '07 #10

P: n/a
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('john','james','delilah','mary');
foreach ($array as $key=>&$value) {
if ($value == 'delilah') {
$value ='samson';
}
elseif ($value=='james') {
$value = null;;
}
echo "$key =$value".NEWLINE;
}

foreach ($array as $key=>$value) {
echo "$key =$value".NEWLINE;
}
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

P: n/a

"ZeldorBlat" <ze********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
"ZeldorBlat" <zeldorb...@gmail.comwrote in message
news:11*********************@p77g2000hsh.googl egroups.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?
>(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
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...@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...@attglobal.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

P: n/a
ZeldorBlat wrote:
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>ZeldorBlat wrote:
>>On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
wrote:
>"ZeldorBlat" <zeldorb...@gmail.comwrote in message
>news:11*********************@p77g2000hsh.goog legroups.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?
>>>(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
>>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...@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...@attglobal.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*******@attglobal.net
==================
May 20 '07 #13

P: n/a
Jon Slaughter wrote:
"ZeldorBlat" <ze********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
>On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>>ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
>wrote:
>>"ZeldorBlat" <zeldorb...@gmail.comwrote in message
>>news:11*********************@p77g2000hsh.goo glegroups.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?
>>>>(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
>>>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...@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...@attglobal.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*******@attglobal.net
==================
May 20 '07 #14

P: n/a
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...@gmail.comwrote in message

news:11*********************@p77g2000hsh.google groups.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?
>(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
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".NEWLINE;
if ($value == 'delilah') {
$array[$key]='samson';
}
elseif ($value=='james') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLINE;
}
?>
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*******@attglobal.net
==================
May 20 '07 #15

P: n/a
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*******@attglobal.net
==================
May 20 '07 #16

P: n/a

"Jerry Stuckle" <js*******@attglobal.netwrote in message
news:lc******************************@comcast.com. ..
Jon Slaughter wrote:
>"ZeldorBlat" <ze********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googleg roups.com...
>>On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>ZeldorBlat wrote:
>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
>>wrote:
>>>"ZeldorBlat" <zeldorb...@gmail.comwrote in message
>>>news:11*********************@p77g2000hsh.go oglegroups.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?
>>>>>(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
>>>>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...@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...@attglobal.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

P: n/a

"Jerry Stuckle" <js*******@attglobal.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...@gmail.comwrote in message
>
news:11*********************@p77g2000hsh.googl egroups.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?
>>(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
>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".NEWLINE;
if ($value == 'delilah') {
$array[$key]='samson';
} elseif ($value=='james') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLINE;
}
?>
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

P: n/a
Jon Slaughter wrote:
"Jerry Stuckle" <js*******@attglobal.netwrote in message
news:lc******************************@comcast.com. ..
>Jon Slaughter wrote:
>>"ZeldorBlat" <ze********@gmail.comwrote in message
news:11**********************@u30g2000hsc.google groups.com...
On May 18, 10:44 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
ZeldorBlat wrote:
>On May 18, 9:05 pm, Jerry Stuckle <jstuck...@attglobal.netwrote:
>>ZeldorBlat wrote:
>>>On May 18, 11:40 am, "Jon Slaughter" <Jon_Slaugh...@Hotmail.com>
>>>wrote:
>>>>"ZeldorBlat" <zeldorb...@gmail.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?
>>>>>>(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
>>>>>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...@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...@attglobal.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*******@attglobal.net
==================
May 20 '07 #19

P: n/a
Jon Slaughter wrote:
"Jerry Stuckle" <js*******@attglobal.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...@gmail.comwrote in message
>>
>news:11*********************@p77g2000hsh.goog legroups.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?
>>>(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
>>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".NEWLINE;
if ($value == 'delilah') {
$array[$key]='samson';
} elseif ($value=='james') {
unset($array[$key]);
}
}
echo NEWLINE;
foreach ($array as $key=>$value) {
echo "$key =$value".NEWLINE;
}
?>
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?

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*******@attglobal.net
==================
May 20 '07 #20

P: n/a
At Sun, 20 May 2007 10:23:31 -0400, Jerry Stuckle let his monkeys type:
>>>>
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.
In fact, there may be a hint the array behaviour isn't as straightforward
as it seems in this case. Good point Jerry. As in this example:
http://www.thescripts.com/forum/thread631554.html where it appears at
least the array pointer (which seemed unaffected in my earlier test)
doesn't behave completely as one would expect if a foreach operated on a
totally isolated array copy.

Sh.
May 20 '07 #21

P: n/a
On 20.05.2007 05:09 Jon Slaughter wrote:
>
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...
From my understanding, foreach doesn't make a copy of *entire array*,
it just copies *current value* into the loop variable (unless you
provided it by reference).
>
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 ;/
I understand your concerns. Deleting elements in a loop might be
technically ok, but it just feels unsafe. Essentially what you're doing
is filtering and it'd better to write it as such:

$good = array();
foreach($ary as $elem)
if(my_check_func($elem)) $good[] = $elem;

or simply

$good = array_filter($ary, 'my_check_func');
--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
May 21 '07 #22

P: n/a
gosha bine kirjoitti:
On 20.05.2007 05:09 Jon Slaughter wrote:
>>
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...

From my understanding, foreach doesn't make a copy of *entire array*,
it just copies *current value* into the loop variable (unless you
provided it by reference).
Here's a way to test it:

<?php

$a = range(0,4);

foreach($a as $k =$v){
if(isset($a)) unset($a);
echo "$k =$v<br>";
}

print_r($a);

?>

To me it would seem the entire array is copied, since it prints all the
values even after the array is unset, I got the output:
0 =0
1 =1
2 =2
3 =3
4 =4

--
Ra*********@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
May 21 '07 #23

P: n/a
On 21.05.2007 18:00 Rami Elomaa wrote:
gosha bine kirjoitti:
>On 20.05.2007 05:09 Jon Slaughter wrote:
>>>
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...

From my understanding, foreach doesn't make a copy of *entire array*,
it just copies *current value* into the loop variable (unless you
provided it by reference).

Here's a way to test it:

<?php

$a = range(0,4);

foreach($a as $k =$v){
if(isset($a)) unset($a);
echo "$k =$v<br>";
}

print_r($a);

?>

To me it would seem the entire array is copied, since it prints all the
values even after the array is unset, I got the output:
0 =0
1 =1
2 =2
3 =3
4 =4
Good point. Here's another example for even deeper meditation

$a = range(0,4);
// $b = &$a;
foreach($a as $k =$v){
$a[99] = 5;
echo "$k=>$v\n";
}

(try uncommenting the second line).


--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
May 21 '07 #24

P: n/a
Rami Elomaa wrote:
gosha bine kirjoitti:
>On 20.05.2007 05:09 Jon Slaughter wrote:
>>>
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...

From my understanding, foreach doesn't make a copy of *entire array*,
it just copies *current value* into the loop variable (unless you
provided it by reference).

Here's a way to test it:

<?php

$a = range(0,4);

foreach($a as $k =$v){
if(isset($a)) unset($a);
echo "$k =$v<br>";
}

print_r($a);

?>

To me it would seem the entire array is copied, since it prints all the
values even after the array is unset, I got the output:
0 =0
1 =1
2 =2
3 =3
4 =4
Rami,

That may be true on the release you're running at. But is it true for
all releases? And will it remain that way? Unless it's documented to
work that way, there's no way of telling.

And these are exactly the types of assumptions which get you in deep
trouble.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
May 21 '07 #25

P: n/a
Jerry Stuckle kirjoitti:
Rami Elomaa wrote:
>gosha bine kirjoitti:
>>On 20.05.2007 05:09 Jon Slaughter wrote:
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...

From my understanding, foreach doesn't make a copy of *entire
array*, it just copies *current value* into the loop variable (unless
you provided it by reference).

Here's a way to test it:

<?php

$a = range(0,4);

foreach($a as $k =$v){
if(isset($a)) unset($a);
echo "$k =$v<br>";
}

print_r($a);

?>

To me it would seem the entire array is copied, since it prints all
the values even after the array is unset, I got the output:
0 =0
1 =1
2 =2
3 =3
4 =4

Rami,

That may be true on the release you're running at. But is it true for
all releases? And will it remain that way? Unless it's documented to
work that way, there's no way of telling.
I agree that if it is documented you can't trust it. However, looking at
http://fi2.php.net/manual/en/control...es.foreach.php you'll find
the following: "Note: Unless the array is referenced, foreach operates
on a copy of the specified array and not the array itself." Wouldn't
that make this a _documented_ feature that you can actually rely on?

--
Ra*********@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
May 21 '07 #26

P: n/a
Rami Elomaa wrote:
Jerry Stuckle kirjoitti:
>Rami Elomaa wrote:
>>gosha bine kirjoitti:
On 20.05.2007 05:09 Jon Slaughter wrote:

>
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...

From my understanding, foreach doesn't make a copy of *entire
array*, it just copies *current value* into the loop variable
(unless you provided it by reference).

Here's a way to test it:

<?php

$a = range(0,4);

foreach($a as $k =$v){
if(isset($a)) unset($a);
echo "$k =$v<br>";
}

print_r($a);

?>

To me it would seem the entire array is copied, since it prints all
the values even after the array is unset, I got the output:
0 =0
1 =1
2 =2
3 =3
4 =4

Rami,

That may be true on the release you're running at. But is it true for
all releases? And will it remain that way? Unless it's documented to
work that way, there's no way of telling.

I agree that if it is documented you can't trust it. However, looking at
http://fi2.php.net/manual/en/control...es.foreach.php you'll find
the following: "Note: Unless the array is referenced, foreach operates
on a copy of the specified array and not the array itself." Wouldn't
that make this a _documented_ feature that you can actually rely on?

--
Ra*********@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
Yes, but that wasn't the original question.

The original question was - is it safe to delete from the original array
while in a foreach() loop? The answer to this is still no - there is no
indication what happens with the copy when the original is changed.

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

P: n/a
At Mon, 21 May 2007 19:39:43 +0200, gosha bine let his monkeys type:

Good point. Here's another example for even deeper meditation

$a = range(0,4);
// $b = &$a;
foreach($a as $k =$v){
$a[99] = 5;
echo "$k=>$v\n";
}

(try uncommenting the second line).
Yikes. Nice. Now let us get this straight. By referencing ($b = &$a)
suddenly the foreach loop becomes aware of changes in $a. Tricky.

Any solid ideas how this works internally? I'd say it suggests
PHP's reference model isn't really based on references for one. But I may
be wrong. A real headscratcher. And this proves Jerry's point once again:
don't trust anything that's not explicitly stated in detail in the
documentation.

Just for fun, a candidate for 'most original and idiotic endless
memory gobbling loop':
$a = range(0,4);
$b = &$a;
$cnt=2;
foreach($a as $k =$v){
$a[$cnt++] = 5;
echo "$k=>$v\n";
}

Weird thing is it doesn't even produce an error on my box. It just stops
(I do assume however this is due to memory running out)

Again, impressive albeit academic find, Gosha. Worth a bug report you
think? Sh.
May 21 '07 #28

P: n/a
On 21.05.2007 22:28 Schraalhans Keukenmeester wrote:
At Mon, 21 May 2007 19:39:43 +0200, gosha bine let his monkeys type:

>Good point. Here's another example for even deeper meditation

$a = range(0,4);
// $b = &$a;
foreach($a as $k =$v){
$a[99] = 5;
echo "$k=>$v\n";
}

(try uncommenting the second line).

Yikes. Nice. Now let us get this straight. By referencing ($b = &$a)
suddenly the foreach loop becomes aware of changes in $a. Tricky.

Any solid ideas how this works internally?
Internally, foreach is a pair of FE_RESET (start loop) and FE_FETCH
(iteration) opcodes, implementation of FE_RESET starts here

http://lxr.php.net/source/ZendEngine..._vm_def.h#3191

note the line 3219
(http://lxr.php.net/source/ZendEngine..._vm_def.h#3219)

SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
It basically says: "separate ZVAL" (i.e. make a copy) of the array
(array_ptr_ptr) only if it is not a reference. That is, Rami was right
about copying, but it only takes place when the array is a "normal"
variable, not a reference.
<...>
Again, impressive albeit academic find, Gosha. Worth a bug report you
think? Sh.
I'm kind of reluctant to upset the good people ;) therefore I'd refrain
from reporting this. Maybe you? ;)
--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
May 22 '07 #29

P: n/a
In article <f2*********@nyytiset.pp.htv.fi>, Rami Elomaa wrote:
$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?
Unless I'm mistaken the potential problem lies in the possibility that the array
is indexed in such a way that, if you delete elements from it whilst something
(in this case "foreach" is working through it, the index that foreach is using
might be compromised and so the next iteration might not return the element that
the programmer was expecting.

The easiest way to see this occurring is to use a numeric index into the array,
*then* delete something from the middle of it whilst in a loop.
Good question Jon! 8-)

Regards
Mark
May 22 '07 #30

This discussion thread is closed

Replies have been disabled for this discussion.