2011-08-07 12 views
25

considerar lo siguiente:objeto de copia en comparación con el clon en PHP

$object1 = new stdClass(); 
$object2 = $object1; 
$object3 = clone $object1; 

$object1->content = 'Ciao'; 

var_dump($object1); 
// Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" } 
var_dump($object2); 
// Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" } 
var_dump($object3); 
// Outputs object(stdClass)#2 (0) { } 

¿Es un comportamiento normal de PHP que $object2 tiene un contenido idéntico al $object1?

Para mí suena como $object2 es una referencia a $object1 en lugar de una copia. La clonación del objeto antes de cambiar el contenido actúa como una copia. Este comportamiento es diferente de lo que sucede con las variables y me parece poco intuitivo.

+1

Eso es sólo otro PHP-WTF resultante de las especificaciones que faltan. –

+0

Vea el ejemplo aquí: http://www.php.net/manual/en/language.oop5.references.php. –

+2

¿Puede explicar un poco por qué eso no es intuitivo para usted? – hakre

Respuesta

38

Sí, eso es normal. Los objetos son siempre "asignados" por referencia en PHP5. Para hacer una copia de un objeto, necesita clone.

Para ser más correctos, sin embargo, permítanme citar the manual:

A partir de PHP5, una variable de objeto no contiene el objeto en sí mismo como el valor más. Solo contiene un identificador de objeto que permite a los usuarios de acceso buscar el objeto real. Cuando un objeto se envía por argumento, se devuelve o se asigna a otra variable, las diferentes variables no son alias: contienen una copia del identificador, que apunta al mismo objeto.

4

Los objetos en php5 son esencialmente punteros, es decir, una variable de objeto contiene solo una dirección de los datos del objeto ubicados en otro lugar. Una asignación $obj1 = $obj2 solo copia esta dirección y no toca los datos en sí. Esto puede parecer contradictorio, pero de hecho es bastante práctico, porque rara vez se necesitan dos copias del objeto. Desearía que las matrices php usaran la misma semántica.

+0

Usar 'ArrayObject' – KingCrunch

+0

Algunas funciones solo aceptan matrices nativas, por supuesto. '$ result = new ArrayObject (array_map ($ cb, $ arrOb-> getArrayCopy()));' – KingCrunch

13

eso es normal y no voy a considerar este poco intuitivos (por objeto casos):

$object1 = new stdClass(); 

asigna una nueva instancia de objeto a $object1.

$object2 = $object1; 

Asigna la instancia del objeto a $object2.

$object3 = clone $object1; 

asigna una nueva instancia del objeto clonado a partir de una instancia de objeto existente para $object3.

Si no fuera así, cada vez que necesite pasar una instancia de objeto concreto, deberá pasarla por referencia. Eso es engorroso al menos, pero PHP lo hizo en la versión 4 (comparar zend.ze1_compatibility_mode core). Eso no fue útil.

Cloning allows the object to specify how it get's copied.

+0

@stereofrog: Bueno desde una perspectiva orientada a objetos, no lo es. Sin embargo, PHP * en realidad * hace una copia también, una copia del identificador de objeto. El valor del objeto solo está disponible por identificador desde PHP 5, de hecho, incluso con "Espero una copia" esto es intuitivo: obtienes la copia del identificador del objeto. Sin embargo, el punto clave podría ser comprender cómo se implementa OO en PHP. – hakre

+0

@stereofrog: Sería mucho más confuso, cuando los objetos se van a clonar cada vez que pasa en algún lugar. Además, nunca verás a un perro dividirse en dos copias idénticas, cuando pase por una puerta (y uno de los perros siempre se queda afuera ...). Por otro lado, cuando le doy a alguien mi número de teléfono (un valor/tipo primitivo) y él lo escribe, solo tiene una copia, no el número en sí. No es útil comparar el comportamiento de tipos primitivos y objetos entre sí. – KingCrunch

+0

@stereofrog: * ¿Por qué? * Es la pregunta correcta. Para decir mejor por qué, el OP debería compartir un poco más acerca de lo que no es intuitivo para él. De lo contrario, es difícil responder. Además de eso, en lo que respecta al lenguaje, podría diferir entre la asignación y la copia (al escribir). Eso podría abrir los ojos sobre cómo funciona el lenguaje y fomentar el entendimiento para utilizar el lenguaje como una herramienta en lugar de arrojar expectativas en contra de él. – hakre

7

copia de un objeto contra el clon objeto

class test{ 
public $name; 
public $addr; 
} 
// i create a object $ob 
$ob=new test(); 

// object copy 

$ob2=$ob; 

// in object copy both object will represent same memory address 
// example 
$ob->name='pankaj raghuwanshi'; 

// i am printing second object 
echo $ob2->name; 
// output is : pankaj raghuwanshi 

// another example 

$ob2->name='raghuwanshi pankaj'; 
echo $ob->name; 
// output is : raghuwanshi pankaj 

// it means in copy of object original and copy object share same memory place 

ahora clon de un objeto

$ob1=clone $ob; 

echo $ob1->name; // output is : raghuwanshi pankaj 
echo $ob->name; // output is : raghuwanshi pankaj 

$ob1->name='PHP Clone'; 
$ob->name='PHP Obj'; 

echo $ob1->name; // output is : PHP Clone 
echo $ob->name; // output is : PHP Obj 

// on the base of these output we can say both object have their own memory space 
// both are independent 
+0

esta respuesta es adecuada con el ejemplo en vivo – PankajR