2010-07-06 18 views
10

Acabo de leer sobre la variable unset a través del manual php.variable unset en php

el manual de PHP dice "unset() destruye las variables especificadas"

Esta definición parece perfecto hasta que me encontré variable estática ... "Si una variable estática es unset() dentro de una función, unset() destruye la variable solo en el contexto del resto de una función. Las siguientes llamadas restablecerán el valor anterior de una variable. "

Esta definición no me parece buena, en menos, dado que "destruir la variable" implica que la variable ya no es un Ssociated con esa ubicación de memoria.

¿Alguien más piensa que una mejor definición sería "unset() hace que la variable esté fuera del alcance actual"? Es decir, en lugar de apuntar hacia la vida útil, es mejor usar el alcance de palabras aquí.

+0

Esto no es una buena pregunta para el SO. Puede indicar tales cosas en listas de correo de PHP o lo que sea, pero no tiene ningún valor aquí. ¿Qué esperarías de una respuesta? ¿Estás satisfecho si digo * Sí *? ;) –

+1

felix, soy solo un principiante si dijeras que sí, seguro que aumentaría mi confianza y si dices que no, seguro que aprenderé algo, pero a partir de ahora me encargaré de esto. Gracias – Tarun

Respuesta

13

Consideremos la función:

function foo() { 
    static $bar; 
    $bar++; 
    unset($bar); 
} 
foo(); //static $bar is 1 
foo(); //static $bar is 2 

La función compila a:

 
function name: foo 
number of ops: 11 
compiled vars: !0 = $bar 
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    2  0 > EXT_NOP             
    4  1  EXT_STMT             
     2  FETCH_W      static    $0  'bar' 
     3  ASSIGN_REF            !0, $0 
    5  4  EXT_STMT             
     5  POST_INC           ~1  !0 
     6  FREE              ~1 
    6  7  EXT_STMT             
     8  UNSET_VAR            !0 
    7  9  EXT_STMT             
     10 > RETURN             null 

Una variable existe realmente fuera de cada llamada a la función foo() y, en cada llamada, es inverosímil y una referencia a está asignado a $bar.De hecho, es muy similar a esto:

function foo() { 
    global $bar; 
    $bar++; 
    unset($bar); 
} 

Cuando se llama a unset(), que sólo está destruyendo la referencia que ha creado, no el valor subyacente.

que no confirmó, pero lo que yo supongo que sucede es lo siguiente:

  • La representación subyacente de la variabe (el zval) se almacena de forma que su cuenta de referencia es 1.
  • Cuando se llama al foo(), el símbolo $bar está asociado con este zval, su recuento de referencia se incrementa a 2 y se establece el indicador de referencia.
  • Cuando unset se llama, el zval tiene su cuenta de referencia se redujo a 1, el indicador de referencia es probablemente despejado y el símbolo $bar está eliminado.

Ver reference count basics.

+0

thankz gracias por preciosa información – Tarun

+3

@artefactor Tengo curiosidad por saber cómo se generó que fuera ¿poner? – MANCHUCK

+0

@Artefacto, ¿esta salida es para HHVM o ZE? – Pacerier

9

Dentro de una función, los nombres de variables que hacen referencia a variables estáticas son solo eso .. referencias. En efecto, unset destruye la referencia.

+0

querías decir que declare una variable estática como (considere dentro de un fn) static $ a = 2; $ b = $ a + 2; // aquí $ a convertido en referencia de la variable estática $ a ;? yo no, t conseguir apuntas señor – Tarun

+0

Para las variables estáticas, se asigna espacio en el montón para el valor de los datos, y el espacio se asigna en la pila para el enlace de referencia. Al desactivar una referencia, solo el espacio de pila local se destruye/recupera/invalida. – Zak

+0

thankz Zak para obtener información útil – Tarun

3

unset (self :: $ somethingstatic); generará un error Fatal, porque la variable es estática (siempre allí, no puede deshacerse).

la documentación se refiere específicamente a las variables estáticas definidas dentro de una función, tenga en cuenta:

function t($stage) 
{ 
    static $shell = 23; 
    switch($stage) { 
    case 1: 
     $shell++; 
     break; 
    case 2: 
     unset($shell); 
     break; 
    case 3: 
     $shell--; 
    break; 
    } 
    echo $shell; 
} 

debido $ cáscara es una variable estática, siempre está ahí (estática) por lo que cualquier otro momento que mencionar $ cáscara que es simplemente una referencia: cuando la desarma, está deshaciendo la referencia (piense en desvincular un enlace simbólico); sin embargo, la variable estática todavía está allí (eso es lo que significa estática).

tanto, si se llama a la función anterior t (1) hará eco 24, t (2) se hará eco de nada, y t (3) será (con razón) echo 23 :)

ayuda alguna?

+0

i wld encanta decir "cualquier otra vez que se menciona $ cáscara que es simplemente una referencia:" Que yo sepa, pero ..en memoria PHP es asignado incluso para referencia ?? me corrija – Tarun

+0

thankz Nathan i DIN, t saber ABT unsetting propiedad estática daré error – Tarun

+0

Esta respuesta hizo más clara para mí –

0

Bueno, lo que unset() hace es borrar la memoria asociada con un nombre de variable.

En el caso de variables estáticas, sin embargo, lo que puede visualizar como que sucede es separar la variable estática del alcance de la función, y cada vez que llame a la función, obtendrá automáticamente una copia de esa variable.

Entonces, lo que esto significa es que si unset es una variable estática, solo está realmente unset ting esa copia, por lo que cuando la función se llama nuevamente, "recibe" una copia nueva.

+0

cuál es incorrecto si sólo visualizo que unset() lanzar la variable de fuera de alcance, ahora tiempo lo claro el memroy asociado con la variable es o no depende de la vida útil de la variable. – Tarun

+0

Bueno, el problema con lo que dices es que, de manera realista, una variable declarada 'estática' no está * en * el alcance de la función, y es por eso que se transfiere de llamada a llamada. Otoh, estás en el camino correcto, si se tiene en cuenta que se trata de la copia de esa variable estática que está "patadas fuera de alcance" –

1

Si no estoy equivocado, el punto es para desarmar una variable estática. Por diferentes razones, esto podría ser útil, además esto liberaría algo de memoria. Por ejemplo:

unset($some_static_var_or_property_holding_a_big_object); 

Aunque no podemos achive esto exactamente como es, en algunos casos podría ser suficiente para hacer esto:

$some_static_var_or_property_holding_a_big_object = null; 

Esto liberaría algo de memoria (supongo) y nos permitiría ir destruir un objeto que ya no queremos (espero no estar fuera del tema).