Learning PHP (5) -> cloning objects?

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

    Learning PHP (5) -> cloning objects?

    Hey ho,

    The release of PHP5 seemed like a good reason to try to learn it once
    more...

    I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
    fiddling with objects. I just discovered the proper way to clone
    objects is *not* "$b = $a->__clone();", as it reads in the book, but
    "$b = clone $a". Right?

    Now it's still not fully clear to me. The class is called UnitCounter,
    two private variables are $units and $weightPerUnit. The __clone()
    function simply looks like...

    $this->weightPerUni t = $that->weightPerUni t;
    $this->units = $that->units;

    ....but when I use it like so:

    $a = new UnitCounter();
    $a->add(5);
    $c = clone $a;
    $c->add(5);

    ....both end up containing 5 units, whereas I would expect $c to contain
    5 already from the beginning (as it's a clone of $a, which contains 5
    units), so 10 in total, after adding another 5. Why is $c getting the
    initial (constructor) value of zero, instead of 5 like $a, which it is
    cloned from?

    Hoping for someone to enlighten me,
    greets,
    Tom
  • Janwillem Borleffs

    #2
    Re: Learning PHP (5) -> cloning objects?

    Tom wrote:[color=blue]
    > I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
    > fiddling with objects. I just discovered the proper way to clone
    > objects is *not* "$b = $a->__clone();", as it reads in the book, but
    > "$b = clone $a". Right?
    >[/color]

    Correct, some information from the books published before the final release
    of PHP 5 is now deprecated
    [color=blue]
    > ...both end up containing 5 units, whereas I would expect $c to
    > contain 5 already from the beginning (as it's a clone of $a, which
    > contains 5 units), so 10 in total, after adding another 5. Why is $c
    > getting the initial (constructor) value of zero, instead of 5 like
    > $a, which it is cloned from?
    >[/color]

    This is correct behavior, because a clone is a shallow copy of an object
    with all properties set to their initial values.

    Simple use "$b = $a" if you want to have a full copy of $a.


    JW



    Comment

    • Zurab Davitiani

      #3
      Re: Learning PHP (5) -> cloning objects?

      Tom wrote:
      [color=blue]
      > I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
      > fiddling with objects. I just discovered the proper way to clone
      > objects is *not* "$b = $a->__clone();", as it reads in the book, but
      > "$b = clone $a". Right?[/color]

      Right. clone then calls the __clone method.
      [color=blue]
      > Now it's still not fully clear to me. The class is called UnitCounter,
      > two private variables are $units and $weightPerUnit. The __clone()
      > function simply looks like...
      >
      > $this->weightPerUni t = $that->weightPerUni t;
      > $this->units = $that->units;
      >
      > ...but when I use it like so:
      >
      > $a = new UnitCounter();
      > $a->add(5);
      > $c = clone $a;
      > $c->add(5);
      >
      > ...both end up containing 5 units, whereas I would expect $c to contain
      > 5 already from the beginning (as it's a clone of $a, which contains 5
      > units), so 10 in total, after adding another 5. Why is $c getting the
      > initial (constructor) value of zero, instead of 5 like $a, which it is
      > cloned from?[/color]

      I think you got $this and $that confused in your __clone method. Remember
      that $this still refers to the current object and $that refers to the new
      clone. So, your assignments should read:

      $that->weightPerUni t = $this->weightPerUni t;
      $that->units = $this->units;

      Also, the default __clone method (without your specific implementation)
      should copy all properties on its own already. If you need a different
      behavior to set your own property values, only then do you need to define
      your own __clone method.

      Comment

      • Zurab Davitiani

        #4
        Re: Learning PHP (5) -> cloning objects?

        Janwillem Borleffs wrote:
        [color=blue]
        > This is correct behavior, because a clone is a shallow copy of an object
        > with all properties set to their initial values.[/color]

        If that were the case, what would be the purpose of cloning? You could just
        instantiate a new object instead. clone copies all properties by default.
        From http://www.php.net/manual/en/language.oop5.cloning.php

        "When the developer asks to create a new copy of an object, PHP 5 will check
        if a __clone() method has been defined or not. If not, it will call a
        default __clone() which will copy all of the object's properties. If a
        __clone() method is defined, then it will be responsible to set the
        necessary properties in the created object. For convenience, the engine
        will supply a function that imports all of the properties from the source
        object, so that they can start with a by-value replica of the source
        object, and only override properties that need to be changed."
        [color=blue]
        > Simple use "$b = $a" if you want to have a full copy of $a.[/color]

        That's true in PHP4 but no longer true in PHP5.

        Comment

        • Tom

          #5
          Re: Learning PHP (5) -> cloning objects?

          * [Saturday 31 July 2004 00:02] Zurab Davitiani in comp.lang.php:

          <snip>
          [color=blue][color=green]
          > > Why is $c getting the initial (constructor) value of zero, instead
          > > of 5 like $a, which it is cloned from?[/color]
          >
          > I think you got $this and $that confused in your __clone method.
          > Remember that $this still refers to the current object and $that
          > refers to the new clone. So, your assignments should read:
          >
          > $that->weightPerUni t = $this->weightPerUni t;
          > $that->units = $this->units;[/color]

          Hmpf... You're right.
          [color=blue]
          > Also, the default __clone method (without your specific
          > implementation) should copy all properties on its own already.[/color]

          And again... Both ways indeed work as expected.

          Thanks a lot,
          Tom

          Comment

          Working...