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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tamagafk

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

  • Tamagafk

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

    One more thing: pretend that there is no $nodes[3] = new node(4, 0);
    :)

    Comment

    • Toby A Inkster

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

      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!

      Comment

      • Vince Morgan

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

        "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
        news:gr81f4-4kp.ln1@ophelia .g5n.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


        Comment

        • Rami Elomaa

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

          Vince Morgan kirjoitti:
          "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
          news:gr81f4-4kp.ln1@ophelia .g5n.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

          --
          Rami.Elomaa@gma il.com

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

          Comment

          • Jerry Stuckle

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

            Vince Morgan wrote:
            "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
            news:gr81f4-4kp.ln1@ophelia .g5n.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.
            jstucklex@attgl obal.net
            =============== ===

            Comment

            • Rami Elomaa

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

              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++. :)

              --
              Rami.Elomaa@gma il.com

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

              Comment

              • Toby A Inkster

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

                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!

                Comment

                • Vince Morgan

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

                  "Vince Morgan" <vinhar@REMOVEo ptusnet.com.auw rote in message
                  news:461e08a4$0 $9771$afc38c87@ news.optusnet.c om.au...
                  "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
                  news:gr81f4-4kp.ln1@ophelia .g5n.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


                  Comment

                  • Vince Morgan

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


                    "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
                    news:ivg1f4-4kp.ln1@ophelia .g5n.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


                    Comment

                    • Steve

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


                      "Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
                      news:ivg1f4-4kp.ln1@ophelia .g5n.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.

                      ethereal?

                      let's say an enumerable object inherits an 'ienumerable' class. that
                      interface simply has a getEnumerator() function which php calls natively
                      when the code uses things like foreach(). getEnumerator() returns an
                      'ienumerator' object that defines the reset(), each(), key(), etc..

                      for all of that, ienumerator only has 2 variables. one for the array of
                      items, and one representing the current index. reset() just sets the index
                      to 0, each() increments, etc., etc.. none of that is brain surgurery and is
                      a common practice in object C, C++, VB, etc. whenever you want to strongly
                      type your own 'collection' to speed things up and enforce your variables'
                      integrity a bit more. it's not mysterious in any way.

                      :)


                      Comment

                      • Jerry Stuckle

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

                        Rami Elomaa wrote:
                        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++. :)
                        >
                        No, the methods are operating on the array, not the internal pointer.
                        You have no direct access to the internal pointer.

                        For instance, you use next(array), not pointer.next() as you would with
                        a C++ iterator.

                        --
                        =============== ===
                        Remove the "x" from my email address
                        Jerry Stuckle
                        JDS Computer Training Corp.
                        jstucklex@attgl obal.net
                        =============== ===

                        Comment

                        • Jerry Stuckle

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

                          Vince Morgan wrote:
                          "Vince Morgan" <vinhar@REMOVEo ptusnet.com.auw rote in message
                          news:461e08a4$0 $9771$afc38c87@ news.optusnet.c om.au...
                          >"Toby A Inkster" <usenet200703@t obyinkster.co.u kwrote in message
                          >news:gr81f4-4kp.ln1@ophelia .g5n.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
                          >
                          >
                          Vince,

                          But the whole point of an iterator is that it has methods you can use to
                          manipulate it. The PHP internal pointer does not - you can only
                          manipulate the pointer through the array itself.

                          Additionally, you can define multiple (or no) iterators for the same
                          list/array/whatever because it is a separate object. But in PHP you
                          have exactly one pointer which is tied to the array.

                          --
                          =============== ===
                          Remove the "x" from my email address
                          Jerry Stuckle
                          JDS Computer Training Corp.
                          jstucklex@attgl obal.net
                          =============== ===

                          Comment

                          • Vince Morgan

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

                            "Jerry Stuckle" <jstucklex@attg lobal.netwrote in message
                            news:FKudneecv7 62PYPbnZ2dnUVZ_ gydnZ2d@comcast .com...
                            But the whole point of an iterator is that it has methods you can use to
                            manipulate it. The PHP internal pointer does not - you can only
                            manipulate the pointer through the array itself.
                            >
                            Additionally, you can define multiple (or no) iterators for the same
                            list/array/whatever because it is a separate object. But in PHP you
                            have exactly one pointer which is tied to the array.
                            >
                            Thanks Jerry, I get the point now that it's tomorrow.
                            I was trying to compare apples to oranges, and there was no point.
                            No sleep, no brain, stupid question.
                            Thanks for your patience!
                            Regards,
                            Vince


                            Comment

                            Working...