php - ¿Qué está sucediendo exactamente al crear instancias con ''nuevo''?
reference new-operator (2)
Añadiendo otra instanciación $obj2 = new a;
aumenta el refcount a 3, no a 4, por lo que es algo que sucede como resultado de llamar a xdebug_debug_zval. El propósito de la función xdebug es evitar la confusión de pasar la variable a la función y (posiblemente) crear una referencia adicional.
Desafortunadamente, esto no se aplica a las variables miembro; Se crea otra referencia a esos zvals para exportarlos. Por lo tanto, todas las advertencias y circunstancias confusas enumeradas en la nota en la documentación de debug_zval_dump todavía se aplican a las variables miembro.
Consideremos el siguiente código:
class a {
public $var1;
function disp(){
echo $this->var1;
}
}
$obj1 = new a;
echo ''<br/>After instantiation into $obj1:<br/>'';
xdebug_debug_zval(''obj1'');
$obj1->var1 = "Hello ";
echo ''<br/><br/>After assigning "Hello" to $obj->var1:<br/>'';
$obj1->disp();
echo "<br/><br/>";
xdebug_debug_zval(''obj1'');
La salida:
Después de la instanciación en $ obj1:
obj1: (refcount = 1, is_ref = 0) = class a {public $ var1 = (refcount = 2, is_ref = 0) = NULL}Después de asignar "Hola" a $ obj-> var1:
Holaobj1: (refcount = 1, is_ref = 0) = class a {public $ var1 = (refcount = 1, is_ref = 0) = ''Hello''}
Uno a uno:
Después de la instanciación en $ obj1:
obj1: (refcount = 1, is_ref = 0) = class a {public $ var1 = (refcount = 2, is_ref = 0) = NULL}
¿Por qué $obj1->var1
tiene refcount=2
cuando solo hay un objeto de la clase a?
¿Es debido a cómo el new
operador hace la asignación? PHP hace la asignación con referencias. Cuando se crea una instancia con new
, no se asocia ningún nombre de símbolo / variable con esa instancia. Pero, las propiedades de la clase tienen nombres. ¿Es el recount=2
debido a esto?
Si ese es el caso, entonces se ha producido un COW (copia en escritura) con una copia superficial WRT en la instancia de clase. Mientras que las propiedades siguen apuntando al zval de las propiedades creadas durante la creación de instancias usando new
.
Ahora,
Después de asignar "Hola" a $ obj-> var1:
Holaobj1: (refcount = 1, is_ref = 0) = class a {public $ var1 = (refcount = 1, is_ref = 0) = ''Hello''}
Entonces, cuando asigno un valor a la propiedad $obj1->var1
un nuevo contenedor zval para esa propiedad y por lo tanto el refcount=1
?
¿Significa esto que el contenedor zval creado durante la creación de instancias con new
imágenes estáticas pero no puede accederse debido a que no hay un nombre de variable / símbolo asociado con él?
Tenga en cuenta (de xdebug: Características de la pantalla variable ):
debug_zval_dump()
es diferente de xdebug_debug_zval()
.
void xdebug_debug_zval ( [string varname [, ...]] )
Muestra información sobre una variable .
Esta función muestra información estructurada sobre una o más variables que incluye su tipo, valor e información de recuento. Las matrices se exploran recursivamente con valores. Esta función se implementa de manera diferente a la función debug_zval_dump() de PHP para debug_zval_dump() los problemas que tiene esa función porque la variable en sí misma se pasa a la función. La versión de Xdebug es mejor, ya que utiliza el nombre de la variable para buscar la variable en la tabla de símbolos interna y accede a todas las propiedades directamente sin tener que lidiar con pasar una variable a una función. El resultado es que la información que devuelve esta función es mucho más precisa que la función propia de PHP para mostrar información zval.
UPDATE
: Dec 31th 2011:
Estoy tratando de ver cómo se lleva a cabo la asignación de memoria cuando se utiliza la nueva . Pero hay muchas otras cosas que tengo que hacer ahora mismo. Espero poder publicar una actualización útil pronto. Hasta entonces aquí están los enlaces al código que estaba viendo:
Creo que la sección "Nota: Cuidado con el refcount" en la siguiente página explica esto: http://php.net/manual/en/function.debug-zval-dump.php
Muestra que el recuento de ref aumenta si zend optimiza la forma en que se pasa, pero luego aparece la "advertencia" cuando se invoca copy-on-write, devolviendo el refcount a 1.
Espero que ayude