note 91323 added to language.oop5.cloning

From: Date: Fri, 05 Jun 2009 17:33:07 +0000
Subject: note 91323 added to language.oop5.cloning
Groups: php.notes 
Request: Send a blank email to php-notes+get-156403@lists.php.net to get a copy of this message
Here are some cloning and reference gotchas we came up against at Last.fm. 1. PHP treats variables as either 'values types' or 'reference types', where the difference is supposed to be transparent. Object cloning is one of the few times when it can make a big difference. I know of no programmatic way to tell if a variable is intrinsically a value or reference type. There IS however a non-programmatic ways to tell if an object property is value or reference type: <?php class A { var $p; } $a = new A; $a->p = 'Hello'; // $a->p is a value type var_dump($a); /* object(A)#1 (1) { ["p"]=> string(5) "Hello" // <-- no & } */ $ref =& $a->p; // note that this CONVERTS $a->p into a reference type!! var_dump($a); /* object(A)#1 (1) { ["p"]=> &string(5) "Hello" // <-- note the &, this indicates it's a reference. } */ ?> 2. unsetting all-but-one of the references will convert the remaining reference back into a value. Continuing from the previous example: <?php unset($ref); var_dump($a); /* object(A)#1 (1) { ["p"]=> string(5) "Hello" } */ ?> I interpret this as the reference-count jumping from 2 straight to 0. However... 2. It IS possible to create a reference with a reference count of 1 - i.e. to convert an property from value type to reference type, without any extra references. All you have to do is declare that it refers to itself. This is HIGHLY idiosyncratic, but nevertheless it works. This leads to the observation that although the manual states that 'Any properties that are references to other variables, will remain references,' this is not strictly true. Any variables that are references, even to *themselves* (not necessarily to other variables), will be copied by reference rather than by value. Here's an example to demonstrate: <?php class ByVal { var $prop; } class ByRef { var $prop; function __construct() { $this->prop =& $this->prop; } } $a = new ByVal; $a->prop = 1; $b = clone $a; $b->prop = 2; // $a->prop remains at 1 $a = new ByRef; $a->prop = 1; $b = clone $a; $b->prop = 2; // $a->prop is now 2 ?> ---- Server IP: 92.48.74.199 Probable Submitter: 195.24.233.122 ---- Manual Page -- http://www.php.net/manual/en/language.oop5.cloning.php Edit -- https://master.php.net/note/edit/91323 Del: integrated -- https://master.php.net/note/delete/91323/integrated Del: useless -- https://master.php.net/note/delete/91323/useless Del: bad code -- https://master.php.net/note/delete/91323/bad+code Del: spam -- https://master.php.net/note/delete/91323/spam Del: non-english -- https://master.php.net/note/delete/91323/non-english Del: in docs -- https://master.php.net/note/delete/91323/in+docs Del: other reasons-- https://master.php.net/note/delete/91323 Reject -- https://master.php.net/note/reject/91323 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#156403) next »