pass objects by reference (PHP4/5)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jan Pieter Kunst

    #1

    pass objects by reference (PHP4/5)

    (apologies if this message is a duplicate -- my news server seems to
    have problems)

    Greetings,

    When using PHP 4, this:

    // ex. 1
    class A {
    function A(&$obj) {
    $this->object =& $obj; // =& not needed?
    }
    }

    is one reference too many: it should be

    // ex. 2
    class A {
    function A(&$obj) {
    $this->object = $obj; // = instead of =&
    }
    }

    because $obj is already a reference when it enters the constructor, is
    that correct?

    Further question: when I upgrade to PHP 5, should I remove the & in
    constructor to get the same effect? Objects are automatically passed by
    reference in PHP 5, did I get that correctly? So the PHP 5 version would be:

    // ex. 3
    class A {
    function A($obj) { // automatically passed by reference?
    $this->object = $obj; // but what happens here?
    }
    }

    But what happens in the $this->object = $obj; line in PHP 5? Is
    $this->obj now a reference to a reference, as in ex. 1, assuming I
    understood that piece of code correctly? If so, how do I get the ex. 2
    behaviour in PHP 5?

    Thanks,
    Jan Pieter Kunst

    --
    Sorry, <devnull@cauce. org> is een "spam trap".
    E-mail adres is <jpk"at"akamail .com>, waarbij "at" = @.

  • Andy Hassall

    #2
    Re: pass objects by reference (PHP4/5)

    On Tue, 21 Dec 2004 06:23:34 +0100, Jan Pieter Kunst <jpk@akamail.co m> wrote:
    [color=blue]
    >(apologies if this message is a duplicate -- my news server seems to
    >have problems)
    >
    >Greetings,
    >
    >When using PHP 4, this:
    >
    >// ex. 1
    >class A {
    > function A(&$obj) {
    > $this->object =& $obj; // =& not needed?
    > }
    >}
    >
    >is one reference too many: it should be
    >
    >// ex. 2
    >class A {
    > function A(&$obj) {
    > $this->object = $obj; // = instead of =&
    > }
    >}
    >
    >because $obj is already a reference when it enters the constructor, is
    >that correct?[/color]

    No, if the intention is to assign a reference to $this->object; $obj is set to
    a reference to the caller's parameter, but then if you want to assign it to
    something else as a reference, you'd need to again use =& else you'll be
    assigning a copy by value.
    [color=blue]
    >Further question: when I upgrade to PHP 5, should I remove the & in
    >constructor to get the same effect? Objects are automatically passed by
    >reference in PHP 5, did I get that correctly? So the PHP 5 version would be:
    >
    >// ex. 3
    >class A {
    > function A($obj) { // automatically passed by reference?
    > $this->object = $obj; // but what happens here?
    > }
    >}
    >
    >But what happens in the $this->object = $obj; line in PHP 5? Is
    >$this->obj now a reference to a reference, as in ex. 1, assuming I
    >understood that piece of code correctly? If so, how do I get the ex. 2
    >behaviour in PHP 5?[/color]

    It's my understanding that rather than objects being passed by reference as
    such, all object variables are in PHP5 now represented by IDs which PHP
    dereferences internally. You can then pass these IDs by value or by reference,
    it doesn't really matter, since when any methods get invoked, it's dereferenced
    to the same thing.

    So, PHP4 code stuffed with '&' referencing operators will work the same in
    PHP5 (as you're now passing object IDs by reference, which is equivalent to
    passing object IDs by value since you can't modify the IDs). You could remove
    the &'s if you start using PHP5-only functionality and so have stopped caring
    about PHP4 compatibility.

    If you var_dump() and then print() an object in PHP4 you get something like:

    object(wibble)( 2) {
    ["wobble"]=>
    NULL
    ["wibble"]=>
    string(6) "wobble"
    }
    Object

    In PHP5 you get the following; note the #1 on the end - this is the object ID:

    object(wibble)# 1 (2) {
    ["wobble"]=>
    NULL
    ["wibble"]=>
    string(6) "wobble"
    }
    Object id #1

    --
    Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
    <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

    Comment

    • Michael Fesser

      #3
      Re: pass objects by reference (PHP4/5)

      .oO(Jan Pieter Kunst)
      [color=blue]
      >When using PHP 4, this:
      >
      >// ex. 1
      >class A {
      > function A(&$obj) {
      > $this->object =& $obj; // =& not needed?[/color]

      Needed.
      [color=blue]
      >is one reference too many: it should be
      >
      >// ex. 2
      >class A {
      > function A(&$obj) {
      > $this->object = $obj; // = instead of =&
      > }
      >}
      >
      >because $obj is already a reference when it enters the constructor, is
      >that correct?[/color]

      Nope. It doesn't matter if the RHS (right hand side) of the assignment
      operator is a reference or not, if used without the reference sign the
      operator will assign a copy(!) to the LHS. Watch this:

      $foo = new TFoo();

      Now $foo doesn't contain the object that was created actually, but a
      copy of it (this becomes important if you create other objects inside
      the constructor and pass a self-reference to them)!

      Whenever you want to work with references in PHP4 you have to use the
      reference sign, always. Omitting it once will break the chain.
      [color=blue]
      >Further question: when I upgrade to PHP 5, should I remove the & in
      >constructor to get the same effect? Objects are automatically passed by
      >reference in PHP 5, did I get that correctly?[/color]

      Yep.
      [color=blue]
      >So the PHP 5 version would be:
      >
      >// ex. 3
      >class A {
      > function A($obj) { // automatically passed by reference?
      > $this->object = $obj; // but what happens here?
      > }
      >}[/color]

      Works as intended, but nevertheless in PHP5 you should use the new
      generic constructor and declare member variables, e.g.

      class A {
      private $object;

      public function __construct($ob j) {
      $this->object = $obj;
      }
      }
      [color=blue]
      >But what happens in the $this->object = $obj; line in PHP 5? Is
      >$this->obj now a reference to a reference, as in ex. 1, assuming I
      >understood that piece of code correctly?[/color]

      Nope. References are no pointers! They are just a kind of alias name.
      Pointers to pointers exist, but a reference is always just that: an
      alias name for a kind of object. There's no reference to a reference.

      HTH
      Micha

      Comment

      • Jan Pieter Kunst

        #4
        Re: pass objects by reference (PHP4/5)

        Michael Fesser wrote:[color=blue]
        > .oO(Jan Pieter Kunst)[color=green]
        >>But what happens in the $this->object = $obj; line in PHP 5? Is
        >>$this->obj now a reference to a reference, as in ex. 1, assuming I
        >>understood that piece of code correctly?[/color]
        >
        >
        > Nope. References are no pointers! They are just a kind of alias name.
        > Pointers to pointers exist, but a reference is always just that: an
        > alias name for a kind of object. There's no reference to a reference.[/color]


        A-ha! Now things are getting clear. I was under the impression that
        references are like pointers. OK, thanks very much for clearing that up.
        Time to re-check the &'s in my PHP 4 code.

        JP

        --
        Sorry, <devnull@cauce. org> is een "spam trap".
        E-mail adres is <jpk"at"akamail .com>, waarbij "at" = @.

        Comment

        • Chung Leong

          #5
          Re: pass objects by reference (PHP4/5)

          "Jan Pieter Kunst" <devnull@cauce. org> wrote in message
          news:41c8ad9b$0 $146$e4fe514c@n ews.xs4all.nl.. .[color=blue]
          > Michael Fesser wrote:[color=green]
          > > .oO(Jan Pieter Kunst)[color=darkred]
          > >>But what happens in the $this->object = $obj; line in PHP 5? Is
          > >>$this->obj now a reference to a reference, as in ex. 1, assuming I
          > >>understood that piece of code correctly?[/color]
          > >
          > >
          > > Nope. References are no pointers! They are just a kind of alias name.
          > > Pointers to pointers exist, but a reference is always just that: an
          > > alias name for a kind of object. There's no reference to a reference.[/color]
          >
          >
          > A-ha! Now things are getting clear. I was under the impression that
          > references are like pointers. OK, thanks very much for clearing that up.
          > Time to re-check the &'s in my PHP 4 code.
          >[/color]

          In general, avoid using references in PHP4. When you have

          function A(&$obj) {
          $this->object =& $obj;
          }
          }

          $a = new A($the_object);

          you are basically creating a reference to a variable holding a reference:

          $this->object >>> $obj >>> $the_object

          In order to get to the actually value, PHP has to dereference twice. Now
          imagine you have a deep class structure, where all classes ultimately
          inherit from A. The constructor of every class has to pass a reference to
          the parent constructor. So you end up with references that goes like

          $this->object >>> $obj >>> $obj >>>
          $obj >>> $obj >>> $obj >>> $the_object

          which makes your script dog slow and eat up memory, as you now have all
          these function parameters that don't get freed after the function has ended
          because they're being referred to.


          Comment

          • Andy Hassall

            #6
            Re: pass objects by reference (PHP4/5)

            On Tue, 21 Dec 2004 20:13:08 -0500, "Chung Leong" <chernyshevsky@ hotmail.com>
            wrote:
            [color=blue]
            >"Jan Pieter Kunst" <devnull@cauce. org> wrote in message
            >news:41c8ad9b$ 0$146$e4fe514c@ news.xs4all.nl. ..[color=green]
            >> Michael Fesser wrote:[color=darkred]
            >> > .oO(Jan Pieter Kunst)
            >> >>But what happens in the $this->object = $obj; line in PHP 5? Is
            >> >>$this->obj now a reference to a reference, as in ex. 1, assuming I
            >> >>understood that piece of code correctly?
            >> >
            >> >
            >> > Nope. References are no pointers! They are just a kind of alias name.
            >> > Pointers to pointers exist, but a reference is always just that: an
            >> > alias name for a kind of object. There's no reference to a reference.[/color]
            >>
            >>
            >> A-ha! Now things are getting clear. I was under the impression that
            >> references are like pointers. OK, thanks very much for clearing that up.
            >> Time to re-check the &'s in my PHP 4 code.
            >>[/color]
            >
            >In general, avoid using references in PHP4. When you have
            >
            >function A(&$obj) {
            > $this->object =& $obj;
            > }
            >}
            >
            >$a = new A($the_object);
            >
            >you are basically creating a reference to a variable holding a reference:
            >
            >$this->object >>> $obj >>> $the_object
            >
            >In order to get to the actually value, PHP has to dereference twice. Now
            >imagine you have a deep class structure, where all classes ultimately
            >inherit from A. The constructor of every class has to pass a reference to
            >the parent constructor. So you end up with references that goes like
            >
            >$this->object >>> $obj >>> $obj >>>
            > $obj >>> $obj >>> $obj >>> $the_object
            >
            >which makes your script dog slow and eat up memory, as you now have all
            >these function parameters that don't get freed after the function has ended
            >because they're being referred to.[/color]

            Do you have anything to demonstrate this (maybe need to dig down into the Zend
            engine?), as it doesn't seem to match with the description in the manual?

            "What References Are

            References in PHP are a means to access the same variable content by different
            names. They are not like C pointers, they are symbol table aliases."

            If it's a symbol table alias, then you can't have a reference to a reference;
            each reference is just one step away from the actual content?

            --
            Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
            <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

            Comment

            Working...