Re: [PHP] Copying an Object

2010-09-24 Thread Nathan Nobbe
On Thu, Sep 23, 2010 at 12:24 AM, Peter Lind peter.e.l...@gmail.com wrote:

 On 23 September 2010 02:14, Daniel Kolbo kolb0...@umn.edu wrote:

 *snip*

  On 9/22/2010 9:11 AM, chris h wrote:
  Say you have two classes: human and male.  Further, say male extends
  human.  Let's say you have a human object.  Then later you want to make
  that human object a male object.  This seems to be a pretty reasonable
  thing to request of our objects.

 Perhaps if you're a C# programmer, but the PHP way of thinking is
 radically different.
 C#: This object is whatever it was currently cast to (if possible)
 PHP: This object is this object, whatever it was created as

 If you have a need to make an object switch class in PHP, then there's
 a 99% chance you're working against, not with the language.


+1, its more like the java paradigm than anything else afaict.  maybe
javascript?  didnt know you could change class at runtime in c#, but then
again my knowledge of the .net platform is very, very minimal, and happily
so :)

getting to some of the other posts in the thread and trying to find a
reasonable place to address them, id like to point out that this scenario
(turning a human into a male) is easily modeled w/ composition in oop.

class Human
{
   // member vars  functions here
}

class Male
{
   $human = null;  // Human instance

   __construct(Human $human)
   {
  $this-human = $human;
   }
}

javascript uses a form of inheritance called prototypical inheritance.

http://en.wikipedia.org/wiki/Prototype-based_programming

and other languages that support runtime class alteration (ruby, python,
objc etc.) are quite different than the single inheritance model in php.
 that said, there are ways of modeling this problem in any of these
languages (see above for 1 reasonable solution w/ single inheritance in
php).  one of the problems w/ the runtime class alteration model is how do
you determine the class of an object after altering it at runtime?

-nathan


Re: [PHP] Copying an Object

2010-09-23 Thread Peter Lind
On 23 September 2010 02:14, Daniel Kolbo kolb0...@umn.edu wrote:

*snip*

 On 9/22/2010 9:11 AM, chris h wrote:
 Say you have two classes: human and male.  Further, say male extends
 human.  Let's say you have a human object.  Then later you want to make
 that human object a male object.  This seems to be a pretty reasonable
 thing to request of our objects.

Perhaps if you're a C# programmer, but the PHP way of thinking is
radically different.
C#: This object is whatever it was currently cast to (if possible)
PHP: This object is this object, whatever it was created as

If you have a need to make an object switch class in PHP, then there's
a 99% chance you're working against, not with the language.

  This type of thing would especially be
 easy if objects of parent classes could be cast as an object of its
 extended class.

I'll hazard a guess and say you didn't start programming in PHP but in
something else.

Regards
Peter

-- 
hype
WWW: http://plphp.dk / http://plind.dk
LinkedIn: http://www.linkedin.com/in/plind
BeWelcome/Couchsurfing: Fake51
Twitter: http://twitter.com/kafe15
/hype

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Copying an Object

2010-09-23 Thread Carlos Medina

Am 23.09.2010 08:24, schrieb Peter Lind:

On 23 September 2010 02:14, Daniel Kolbokolb0...@umn.edu  wrote:

*snip*


On 9/22/2010 9:11 AM, chris h wrote:
Say you have two classes: human and male.  Further, say male extends
human.  Let's say you have a human object.  Then later you want to make
that human object a male object.  This seems to be a pretty reasonable
thing to request of our objects.


Perhaps if you're a C# programmer, but the PHP way of thinking is
radically different.
C#: This object is whatever it was currently cast to (if possible)
PHP: This object is this object, whatever it was created as

If you have a need to make an object switch class in PHP, then there's
a 99% chance you're working against, not with the language.


  This type of thing would especially be
easy if objects of parent classes could be cast as an object of its
extended class.


I'll hazard a guess and say you didn't start programming in PHP but in
something else.

Regards
Peter


Hi,
i think the problem here is the casting posibility in PHP is not 
implemented yet. Like Java you can not cast objects to others. I found, 
dass Classes can be casted by using this code:


class ParentClass
{
public static function cast( ParentClass $object )
{
return $object;

}

public function tellMee( $value )
{
echo $value;
}
}

class childClass extends ParentClass
{

}

$parent = ParentClass::cast( new childClass());
$parent-tellMee( 'Hallo ');
var_dump($parent);

Well yes you can get the ChildClass by using the parent class and use 
the methods allowed to use in the parent class (as method of parentClass 
in childClass). But you can not use inheritance in this construct in 
PHP. I think the best way to work with PHP classes is by using the 
Design Patterns for PHP...


Regards

Carlos

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Copying an Object

2010-09-22 Thread mr bungle
Maybe statics members can help you with this ...

On Wed, Sep 22, 2010 at 07:35, Daniel Kolbo kolb0...@umn.edu wrote:

 Hello PHPers,

 I have:

 class A {
...code
 }

 class B extends A {
...code
 }

 $a = new A();

 $b = new B();

 I would like to get all of the properties of $a into $b by value.  Class
 A extends 3 other classes.  I would like a way to not have to manage a
 'copy' method in B if A or one of the subclasses of A change.

 I was reading about clone, but this doesn't really seem to help me in
 this situation.

 How can I copy $a into $b?

 Thanks,
 dK
 `


 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php




-- 
Ellis  110010100001


Re: [PHP] Copying an Object

2010-09-22 Thread chris h
You could create a method of class B that takes an object of class A as a
parameter and copies each property line by line (or method of class A that
takes an object of class B...).  If you don't want to add a method you could
just do the same thing, but procedurally.  The issue with this (aside from
being bad oop) is that you can't copy private properties unless you have all
the required getters and setters.  The issue with both of these is that it's
ugly, high maintenance code.

There is the iterator class, extending from which would allow you iterate
through all of your properties in a foreach, but if you don't want to add a
new method then you likely don't want to add a parent class.

I don't care for any of these options, but as far as I know there's no
internal PHP mechanism to to copy all the properties from one object to
another object of a different class - please correct me if I'm wrong.  Is it
possible that there's a more elegant solution to your problem that does not
include a mass copy of all an object's properties? (e.g. using statics like
Mr Bungle suggested or perhaps some nifty design pattern?)


Chris H.




On Wed, Sep 22, 2010 at 7:35 AM, Daniel Kolbo kolb0...@umn.edu wrote:

 Hello PHPers,

 I have:

 class A {
...code
 }

 class B extends A {
...code
 }

 $a = new A();

 $b = new B();

 I would like to get all of the properties of $a into $b by value.  Class
 A extends 3 other classes.  I would like a way to not have to manage a
 'copy' method in B if A or one of the subclasses of A change.

 I was reading about clone, but this doesn't really seem to help me in
 this situation.

 How can I copy $a into $b?

 Thanks,
 dK
 `


 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP] Copying an Object

2010-09-22 Thread Nathan Nobbe
On Wed, Sep 22, 2010 at 5:35 AM, Daniel Kolbo kolb0...@umn.edu wrote:

 Hello PHPers,

 I have:

 class A {
...code
 }

 class B extends A {
...code
 }

 $a = new A();

 $b = new B();

 I would like to get all of the properties of $a into $b by value.


first off you have to be careful here since there is no real explicit copy
by value in php since internally the engine uses copy on write.  there is a
caveat in __clone however, where you can force new instances of objects to
be created in cloned instance variables rather than a reference to the
original object in member variables of the cloned instance.


  Class
 A extends 3 other classes.  I would like a way to not have to manage a
 'copy' method in B if A or one of the subclasses of A change.


well since B extends A directly here, obviously theres no need to worry
about other subclasses of A changing when considering the copy constructor
(__clone in php) of B.  anyway if A changes you need only potentially revise
the __clone() implementation of A.


 I was reading about clone, but this doesn't really seem to help me in
 this situation.


egh?  define __clone() in A to be responsible for any member variables
defined in A then define __clone() in B to be responsible for any additional
member variables defined therein, making sure to invoke parent::__clone()
from B.  naturally if you add or remove member variables from A you revise
the __clone() implementation of A, the same is true for B.

this isnt a maintenance nightmare and is also a sound oop practice.  the
same idea would be applied to a copy constructor in java or c++.

note also that php internally manages a shallow copy out of the box, meaning
you wont have to implement any code to 'copy' non-object member variables in
cloned objects.  you will however have to determine if a reference to the
same objects in instance variables of cloned objects is appropriate or if
each instance of the class you are cloning needs to have their own instance
of member variables referencing objects.

here is a somewhat contrived example which illustrates everything.  all you
have to do is run the script and inspect the id of each object stored in
member variables.  what youll find is that in each instance of B shallowObj
is referring to the same instance of stdClass, yet anotherObj from B and
someObj from A are each explicitly 'copied' for each instance of B.  also
youll notice that A manages cloning of someObj and B manages cloning of
anotherObj, keeping in line with encapsulation.  also notice the scalar
variables are 'copied' by the engine w/ no work in userspace.

?php
class A
{
public $blah = 0;
protected $meh = 1;
private $care = 2;
private $someObj = null;

public function __construct()
{
$this-someObj = new stdClass();
}

public function __clone()
{
// note only if we want to force a new instance of
// stdClass into $this-someObj in cloned instance of A
$this-someObj = clone $this-someObj;
}
}

class B extends A
{
protected $what = 5;
protected $anotherObj = null;
protected $shallowObj = null;

public function __construct()
{
parent::__construct();
$this-anotherObj = new stdClass();
$this-shallowObj = new stdClass();
}

public function __clone()
{
// make sure to invoke parent __clone()
parent::__clone();

// note as in A::__clone() above, forcing new instance
// of $this-anotherObj in cloned instance of B
$this-anotherObj = clone $this-anotherObj;

// note also that we do not clone $this-shallowObj here,
// meaning each instance of B will reference the same instance of
$this-shallowObj
}
}

$b1 = new B();
$b2 = clone $b1;

var_dump(array(
$b1, $b2
));
?

/// output
array(2) {
  [0]=
  object(B)#1 (7) {
[what:protected]=
int(5)
[anotherObj:protected]=
object(stdClass)#3 (0) {
}
[shallowObj:protected]=
object(stdClass)#4 (0) {
}
[blah]=
int(0)
[meh:protected]=
int(1)
[care:A:private]=
int(2)
[someObj:A:private]=
object(stdClass)#2 (0) {
}
  }
  [1]=
  object(B)#5 (7) {
[what:protected]=
int(5)
[anotherObj:protected]=
object(stdClass)#7 (0) {
}
[shallowObj:protected]=
object(stdClass)#4 (0) {
}
[blah]=
int(0)
[meh:protected]=
int(1)
[care:A:private]=
int(2)
[someObj:A:private]=
object(stdClass)#6 (0) {
}
  }
}

hope it helps!

-nathan


Re: [PHP] Copying an Object

2010-09-22 Thread Nathan Nobbe
On Wed, Sep 22, 2010 at 5:35 AM, Daniel Kolbo kolb0...@umn.edu wrote:

 Hello PHPers,

 I have:

 class A {
...code
 }

 class B extends A {
...code
 }

 $a = new A();

 $b = new B();


after looking back over your situation, which looks strange, why not use
composition at this level,

// note untested, may have some syntax errors
class B
{
  private $a = null;

  public function __construct(A $a)
  {
 $this-a = $a;
  }

  public function swapA(A $a)
  {
$this-a = $a;
  }

  // proxy any calls to A which you would like to appear transparent
  public function __call($method, array $args)
  {
return call_user_func_array(array($this-a, $method), $args);
  }

  // note requires 5.3
  public function __callStatic($method, array $args)
  {
return call_user_func_array(array($this-a, $method), $args);
  }
}

$a = new A();
$b = new B($a);
// some code ..
$anotherA = new A();
// some more code
$b-swapA($anotherA);

-nathan


Re: [PHP] Copying an Object

2010-09-22 Thread Daniel Kolbo
On 9/22/2010 9:11 AM, chris h wrote:
 
 You could create a method of class B that takes an object of class A as
 a parameter and copies each property line by line (or method of class A
 that takes an object of class B...).  If you don't want to add a method
 you could just do the same thing, but procedurally.  The issue with this
 (aside from being bad oop) is that you can't copy private properties
 unless you have all the required getters and setters.  The issue with
 both of these is that it's ugly, high maintenance code.
 
 There is the iterator class, extending from which would allow you
 iterate through all of your properties in a foreach, but if you don't
 want to add a new method then you likely don't want to add a parent class.
 
 I don't care for any of these options, but as far as I know there's no
 internal PHP mechanism to to copy all the properties from one object to
 another object of a different class - please correct me if I'm wrong.
  Is it possible that there's a more elegant solution to your problem
 that does not include a mass copy of all an object's properties? (e.g.
 using statics like Mr Bungle suggested or perhaps some nifty design
 pattern?)
 
 
 Chris H.
 
 
 
 
 On Wed, Sep 22, 2010 at 7:35 AM, Daniel Kolbo kolb0...@umn.edu
 mailto:kolb0...@umn.edu wrote:
 
 Hello PHPers,
 
 I have:
 
 class A {
...code
 }
 
 class B extends A {
...code
 }
 
 $a = new A();
 
 $b = new B();
 
 I would like to get all of the properties of $a into $b by value.  Class
 A extends 3 other classes.  I would like a way to not have to manage a
 'copy' method in B if A or one of the subclasses of A change.
 
 I was reading about clone, but this doesn't really seem to help me in
 this situation.
 
 How can I copy $a into $b?
 
 Thanks,
 dK
 `
 
 
 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php
 
 
Hello,

Thank you Mr. Bungle, Chris, Nathan, and Carlos Medina.

Nathan, your first response though not exactly what I was looking for
was still instructive to me thanks.  I almost started to implement your
second response but I decided against it as I still wanted class B to
extend class A (and i didn't want the unused members of A to be hanging
around in the objects of B).  Also, I already had __call methods
implemented in the most base class level.  I could have handled this by
calling parent::__call from the child levels if the methods from object
$a were not found.  It would have worked.

Instead I implemented a series of copy functions in each of the
extended classes and cascaded through each of the extended classes.
Each copy method calls parent::copy($obj) to copy the elements of the
extended class.

My classes weren't too crazy just 3-5 members each (all of protected
typed) so it'll work for now.

All in all it was a learning curve.  I still think PHP needs to have
this functionality built in.

Say you have two classes: human and male.  Further, say male extends
human.  Let's say you have a human object.  Then later you want to make
that human object a male object.  This seems to be a pretty reasonable
thing to request of our objects.  This type of thing would especially be
easy if objects of parent classes could be cast as an object of its
extended class.

Thanks again for all of your input,
dK
`

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php