¿Cómo destruir un objeto?

120

Hasta donde yo sé (que es muy poco), hay dos formas, dadas:

$var = new object()

Luego:

// Method 1: Set to null
$var = null;
// Method 2: Unset 
unset($var); 

¿Otro método mejor? ¿Me estoy partiendo los pelos aquí?

PandemoniumSyndicate
fuente

Respuestas:

152

Estás buscando unset().

Pero tenga en cuenta que no puede destruir explícitamente un objeto.

Permanecerá allí, sin embargo, si desarma el objeto y su script empuja PHP a los límites de memoria, los objetos no necesarios serán recolectados como basura. Yo iría con unset()(en lugar de establecerlo en nulo) ya que parece tener un mejor rendimiento (no probado pero documentado en uno de los comentarios del manual oficial de PHP).

Dicho esto, tenga en cuenta que PHP siempre destruye los objetos tan pronto como se sirve la página. Por lo tanto, esto solo debería ser necesario en bucles realmente largos y / o páginas muy intensivas.

Frankie
fuente
1
Entonces, Frankie, vengo de C ++, donde cuando usamos newuna vez, debemos usar deleteuna vez. ¿Esto no es cierto en PHP? ¿Hay recolección automática de basura cuando el objeto ya no es necesario?
gsamaras
3
@gsamaras eso es cierto. Sin embargo, también puede tener fugas y debería leer más sobre el GC de php si está haciendo demonios o similar. En la mayoría de los sitios, la solicitud es tan corta que no importa. php.net/manual/en/features.gc.refcounting-basics.php
Frankie
¿ unset()Elimina la referencia al objeto?
Yousha Aleayoub
9

Una publicación útil que explica varios malentendidos sobre esto:

No llames al Destructor explícitamente

Esto cubre varios conceptos erróneos sobre cómo funciona el destructor. Llamarlo explícitamente no destruirá su variable, de acuerdo con el documento PHP5:

PHP 5 introduce un concepto de destructor similar al de otros lenguajes orientados a objetos, como C ++. El método destructor se llamará tan pronto como no haya otras referencias a un objeto en particular, o en cualquier orden durante la secuencia de apagado.

La publicación anterior establece que establecer la variable en nulo puede funcionar en algunos casos, siempre que nada más apunte a la memoria asignada.

sturrockad
fuente
2

Respuesta corta: ambos son necesarios.

Siento que se dio la respuesta correcta, pero mínimamente. Sí, en general, unset () es mejor para "velocidad", pero si desea recuperar memoria inmediatamente (a costa de la CPU), debería utilizar null.

Como otros mencionaron, establecer en nulo no significa que todo se recupere, puede tener objetos de memoria compartida (no clonados) que evitarán la destrucción del objeto. Además, como han dicho otros, no puedes "destruir" los objetos explícitamente de todos modos, por lo que no deberías intentar hacerlo de todos modos.

Tendrá que averiguar cuál es mejor para usted. También puede usar __destruct () para un objeto que será llamado en unset o null, pero debe usarse con cuidado y, como dijeron otros, ¡nunca debe llamarse directamente!

ver:

http://www.stoimen.com/blog/2011/11/14/php-dont-call-the-destructor-explicitly/

¿Cuál es la diferencia entre asignar NULL y desarmar?

Mike Q
fuente
0

Esta es una prueba simple de que no puede destruir un objeto, solo puede destruir un enlace a él.

$var = (object)['a'=>1];
$var2 = $var;
$var2->a = 2;
unset($var2);
echo $var->a;

devoluciones

2

Véalo en acción aquí: https://eval.in/1054130

Yevgeniy Afanasyev
fuente
3
Bien, has destruido lo $var2que era una referencia $var. Ahora también destruye $vary, suponiendo que no haya otras referencias que retengan el objeto, ya está.
i336_
4
No está destruyendo un objeto, está destruyendo un puntero al objeto. Es una gran diferencia.
Yevgeniy Afanasyev
1
En otros idiomas, puede destruir un objeto y todos los demás indicadores le darán excepciones o basura, pero no es un caso para php
Yevgeniy Afanasyev
1
No puedes destruir. Si no hay ninguna referencia que contenga el objeto, el objeto está listo para ser recogido por el recolector de basura. Y no puede obligar a ejecutar el recolector de basura.
Daniel
0

Puede estar en una situación en la que está creando un nuevo objeto mysqli.

$MyConnection = new mysqli($hn, $un, $pw, $db);

pero incluso después de cerrar el objeto

$MyConnection->close();

si va a utilizar print_r()para comprobar el contenido de $MyConnection, obtendrá un error como se muestra a continuación:

Error:
mysqli Object

Warning: print_r(): Property access is not allowed yet in /path/to/program on line ..
( [affected_rows] => [client_info] => [client_version] =>.................)

en cuyo caso no puede usar unlink()porque unlink()requerirá una cadena de nombre de ruta, pero en este caso$MyConnection es un Objeto.

Entonces tiene otra opción de establecer su valor en nulo:

$MyConnection = null;

ahora todo va bien, como esperabas. No tienes ningún contenido dentro de la variable$MyConnection y ya limpió el objeto mysqli.

Es una práctica recomendada cerrar el objeto antes de establecer el valor de su variable en null.

Subrat Kumar Palhar
fuente
-7

Yo optaría por unset porque podría darle al recolector de basura una mejor pista para que la memoria pueda estar disponible nuevamente antes. Tenga cuidado de que cualquier cosa que señale el objeto tenga otras referencias o se desarme primero o realmente tendrá que esperar al recolector de basura, ya que entonces no habrá identificadores para ellos.

hackartista
fuente
16
A menos que realmente tenga fuentes para respaldar sus respuestas, probablemente no debería publicar lo que cree que "podría" suceder. No es útil y lleva a que este tipo de información errónea se tome como verdad y se repita.
meagar
1
@meagar, esa es la razón exacta por la que me vinculé a la página del manual oficial donde, en los comentarios, hay una prueba de muestra que compara unset () con null.
Frankie