473,807 Members | 2,856 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

For gurus: bug in php? Recursive foreach dont work properly.

Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok. Example:

I have an array of 3 objects connected hierarchically by their
variables id and parentId, here is the hierarchy:
id=1 parentId=0
....id=2 parentId=1
....id=3 parentId=1

I start digging from item with id=1 down to its chils and top-level
foreach NEVER REACH ELEMENT 3!!! Top-level foreach just stops.

<?php
function prn($s){
echo($s.'<br>') ;
}

$nodes = array();
$nodes[0] = new node(1, 0);
$nodes[1] = new node(2, 1);
$nodes[2] = new node(3, 1);
$nodes[3] = new node(4, 0);

class node{
var $id;
var $parentId;

function node($id, $parentId){
$this->id = $id;
$this->parentId = $parentId;
}

function dig($level){
global $nodes;

$l = '';
for($i=0; $i<$level; $i++) $l.='..';
prn($l.'looking for childs of '.$this->id.' {');

foreach($nodes as $n){
prn($l.$n->id.' (parent '.$n->parentId.')' );
if($n->parentId == $this->id){
$n->dig($level+1 );
}
}

prn($l.'}');
}

}

$nodes[0]->dig(0);

?>

The output should look like this:

looking for childs of 1 {
1 (parent 0)
2 (parent 1)
...looking for childs of 2 {
...1 (parent 0)
...2 (parent 1)
...3 (parent 1)
...}
3 (parent 1)
...looking for childs of 3 {
...1 (parent 0)
...2 (parent 1)
...3 (parent 1)
...}
}

But it looks like this:

looking for childs of 1 {
1 (parent 0)
2 (parent 1)
...looking for childs of 2 {
...1 (parent 0)
...2 (parent 1)
...3 (parent 1)
...}
}

Apr 12 '07 #1
13 5425
One more thing: pretend that there is no $nodes[3] = new node(4, 0);
:)

Apr 12 '07 #2
Tamagafk wrote:
Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok.
It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"
element of array. foreach() uses this pointer to iterate through the
array. This is alluded to in the manual:

"the internal pointer of the original array *is*
advanced with the processing of the array."

So both foreach() functions are playing with the same internal pointer,
and screw things up for each other.

As an aside, you can use this internal pointer yourself via the following
functions:

each() - Returns current key, value pair
key() - Returns current key
current() - Returns current value
reset() - Reset pointer to start, return value
next() - Move pointer forwards, return value
prev() - Move pointer backwards, return value
end() - Move pointer to end, return value

Anyway, one solution is to either use for(), as you've discovered. This
works because instead of using PHP's internal array pointer to keep track
of your position in the array, you've defined your own pointer.

The other solution is to make a local copy of the array and run your
foreach() loop on that. Using for() is probably neater though.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 12 '07 #3
"Toby A Inkster" <us**********@t obyinkster.co.u kwrote in message
news:gr******** ****@ophelia.g5 n.co.uk...
Tamagafk wrote:
Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok.

It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"
Why not in the "C sense"?
Something similar to an itterator in C++ ?

TIA
Vince
Apr 12 '07 #4
Vince Morgan kirjoitti:
"Toby A Inkster" <us**********@t obyinkster.co.u kwrote in message
news:gr******** ****@ophelia.g5 n.co.uk...
>Tamagafk wrote:
>>Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok.
It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"

Why not in the "C sense"?
Well it's not like a pointer in C. In C your basic arrays (or strings
which are just arrays of characters) are pointers to memory locations,
and the index is an offset. Since PHP works at a higher level, it
doesn't know anything about the memory, so pointers in that sense don't
exist in php. However the datastructure of an array has an internal
"pointer" but it doesn't mean the same as pointers in C.

See http://en.wikipedia.org/wiki/Pointer_%28computing%29

--
Ra*********@gma il.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
Apr 12 '07 #5
Vince Morgan wrote:
"Toby A Inkster" <us**********@t obyinkster.co.u kwrote in message
news:gr******** ****@ophelia.g5 n.co.uk...
>Tamagafk wrote:
>>Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok.
It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"

Why not in the "C sense"?
Something similar to an itterator in C++ ?

TIA
Vince

Vince,

Because in C a pointer is a memory location. It's not in PHP - just an
indicator to the current location in an array.

And no, it's not like an iterator - there are no methods you can use on
the internal pointer - only the array itself.

--
=============== ===
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attgl obal.net
=============== ===
Apr 12 '07 #6
Jerry Stuckle kirjoitti:
And no, it's not like an iterator - there are no methods you can use on
the internal pointer - only the array itself.
Sigh... In the previous post Toby listed all the methods that can be
used on the internal pointer... So there are indeed methods for
manipulating the internal pointer, but the internal pointer is not like
an iterator in C++. :)

--
Ra*********@gma il.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
Apr 12 '07 #7
Vince Morgan wrote:
Toby A Inkster wrote:
>It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"

Why not in the "C sense"?
A pointer in the C sense of the word is (more or less) an exact memory
address for a piece of data.

The internal pointer in a PHP array has a far more ethereal nature.
Exactly how it works is an enigma wrapped in a riddle and shrouded by
mystery. We don't have direct access to the pointer, but can see its
ghostly effects in the list of functions I mentioned in my previous
post.

It's exact implementation in the PHP source code may well be as a C
pointer, but that doesn't (and shouldn't) matter to a person who's using
PHP arrays. The internal implementation as might well change for each new
version of PHP which is released -- as far as they're concerned, it
doesn't matter, as long as each(), next() and so on keep working as they
do.
Something similar to an itterator in C++ ?
The array is, yes.

PHP 5 has iterators too.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 12 '07 #8
"Vince Morgan" <vi****@REMOVEo ptusnet.com.auw rote in message
news:46******** **************@ news.optusnet.c om.au...
"Toby A Inkster" <us**********@t obyinkster.co.u kwrote in message
news:gr******** ****@ophelia.g5 n.co.uk...
Tamagafk wrote:
Hi! Looks like there is a bug in php. If I have function which uses
foreach to run trough array recursively, the lop-level foreach
interupted by lover-level foreach'es. If I use simply 'for' everything
is ok.
It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the "current"

Why not in the "C sense"?
Something similar to an itterator in C++ ?

TIA
Vince
I guess I didn't ask that q very well at all.
I'm familiar with pointers in C/C++, and iterators in C++, they are
languages I have most experience with.
However, I was thinking that they may be in some ways similar to say, a
vector iterator, without regard for methods etc.
I meant in a very general way, but I think it was probably a silly question
realy.
Trying to cheat my way into a greater understanding of the unerlying
implementation without doing the reading I guess ;)
Thank you for the reply though,
Regards,
Vince
Apr 12 '07 #9

"Toby A Inkster" <us**********@t obyinkster.co.u kwrote in message
news:iv******** ****@ophelia.g5 n.co.uk...
Vince Morgan wrote:
Toby A Inkster wrote:
It's not a bug -- it's a "feature". Internally, arrays in PHP have a
"pointer" (not in the C sense of the word) which points at the
"current"

Why not in the "C sense"?

A pointer in the C sense of the word is (more or less) an exact memory
address for a piece of data.

The internal pointer in a PHP array has a far more ethereal nature.
Exactly how it works is an enigma wrapped in a riddle and shrouded by
mystery. We don't have direct access to the pointer, but can see its
ghostly effects in the list of functions I mentioned in my previous
post.
Those functions had a sic "ghostly" likeness to a C++ vector and I was
wondering if in fact a vector may be used in the underlying implementation.
It's exact implementation in the PHP source code may well be as a C
pointer, but that doesn't (and shouldn't) matter to a person who's using
PHP arrays. The internal implementation as might well change for each new
version of PHP which is released -- as far as they're concerned, it
doesn't matter, as long as each(), next() and so on keep working as they
do.
My first problem in going from C to C++ was that I didn't "own" the pointers
of the library objects, so I appreciate what your saying here.
>
Something similar to an itterator in C++ ?

The array is, yes.
That's what I was imagining might be below the surface.

Thank you for taking the time Toby,

Vince
Apr 12 '07 #10

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

Similar topics

2
1627
by: Dirk McCormick | last post by:
I need to transform something that looks like this <!-- %%%%%%%%%%%%%%%%%%%%%%% --> <MyStructure> <Packages> <Package> <PkgBenefitCode>1</PkgBenefitCode> <PkgBenefitCode>2</PkgBenefitCode> <PkgBenefitCode>3</PkgBenefitCode>
4
6485
by: Ryan Ternier | last post by:
I have a section of my project that is Driving me nuts. No one has been able to help that much on it, so i thought of posting it here in hopes someone could help. I need to print out an Ordered list. Ex. 1. Something
0
1137
by: MrData | last post by:
Hi, I have a big problem with my recursive function. This function have the task to find all blocks in the template file out and put it recursive into a array. hierarchy of the blocks are important At first I try to get all the blocks, but the result is wrong.
0
1960
by: champ1979 | last post by:
I wrote an algorithm to get all the relatives of a person in a family tree. I'm basically getting all the users from the DB and am doing the recursive logic in code, so that there is only 1 call made to the DB. However, I am trying to do the same thing within a stored procedure in SQL using recursive CTEs (I think the performance might be better) but I'm finding it really tough to craft the CTE. I would really appreciate if someone could...
0
1664
by: Silly Milly | last post by:
Calling ALL SSIS GURUS I am trying to import identical MDBs (Access Database) columns into SQL Server 2005 using foreach loop in SSIS. The data and file name of the MDBs are not the same; however the structure (column) is. I do need to capture part of the file name and insert it into the destination column (i.e. Year). I've used the foreach loop with the flat file connection manager, and was able to capture any part of a text file name and...
16
4270
by: colin | last post by:
Hi, is it possible to have a recursive GetEnumerator for traversing a tree structure ? public IEnumerator<DTypeGetEnumerator() { return GetEnumerator(root);
1
1432
by: J. Frank Parnell | last post by:
arrrrrg: Condo for rent has 3 price tiers (for different times of the year): value regular premium For every 7 nites they stay, they get 1 free, and that free one should be the cheapest night (1 value nite, 6 premium nites, they should get the value nite free)
1
1478
by: rekkufa | last post by:
I am currently building a system for serializing python objects to a readable file-format, as well as creating python objects by parsing the same format. It is more or less complete except for a single issue I just cannot figure out by myself: How to load data that specifies immutables that recursively reference themselves. There are only a few solutions I can think of. One: While loading recursive objects, I always create empty versions...
3
1844
by: usman | last post by:
Hi I have a windows service that backups a folder onto another location on the same computer. The service is written in C#. The size of the original folder is large i.e. over 8 GB. Also the folder structure is very deep, i.e lot of recursion. What happens is that the backup process terminates after sometime taking backup of around 2 GB. If I debug the same code I dont get any error, instead the whole folder is copied successfully. Is...
0
9721
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
9600
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10628
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
10113
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
9195
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
7651
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
5685
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3859
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3011
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.