Las variables en PHP

Después de la primera entrada sobre el motor de Zend sigo con el libro de George Schlossnagle, Advanced PHP Programming, mirando de entender las variables

PHP es un lenguaje de tipado  dinámico y débil. Lo que significa que se pueden asignar variables sin definir el tipo y luego asignarles valores de otro tipo:

$mivar = 2; 
$mivar = 'otro valor';

Con la excepción del forzado de tipos en los argumentos de las funciones:

 function mi_funcion (Exception $e);

Lo cual tiene ventajas y desventajas, como todo. Pero miremos  un poco más detalladamente en las tripas de PHP. Todas las variables se representan con una estructura zval:

struct _zval_struct {
   /* Variable information */
   zvalue_value value;   /* value */
   zend_uint refcount;
   zend_uchar type;      /* active type */
   zend_uchar is_ref;
};

donde zvalue_value es:

typedef union _zvalue_value {
   long lval;             /* long value */
   double dval;           /* double value */
   struct {
      char *val;
      int len;
   } str;                 /* string value */
  HashTable *ht;          /* hashtable value */
  zend_object_value obj;  /* handle to an object */

} zvalue_value;

El zval consta de su propio valor, un recuento de referencias, un tipo, y la is_ref bandera.
refcount es un contador asociado al valor de esta variable:
– al crearla: $mivar = ‘primera;’ / $mivar.recount = 1
– si creamos una copia $copia_mivar = $mivar; / $mivar.recount = 2
– si modificamos el valor de la copia $copia_mivar =’otro’ /$mivar.recount = 1

Cuando una variable queda fuera de ámbito, o cuando la variable es destruida, el valor de recount es decrementado en 1. Cuando un zval llega a 0, que es recogido por la recolector de basura y su contenido será liberado.

El tipo zval es especialmente interesante.El hecho de que PP sea un lenguaje débilmente tipado no significa que las variables no tenga un atributo de tipo. El campo type de zval especifica
el tipo actual de la variable que determina que parte de zvalue_value debe ser considerado como valor. Por último, is_ref indica si esta variable realmente contiene los datos o es simplemente una referencia a otra;

La unión zvalue_value donde se guardan los datos para una variable, es un   área de memoria compartida. El valor guardado en zvalue_value toma sentido según lo especificado en type. Esta estructura utiliza una cantidad mínima de espacio para almacenar en momentos diferentes tipos posibles. Prácticamente,se puede acceder al mismo valor o como una representación de un número o una cadena.

Por eso la diferencia entre == y === . En el caso de la igualdad ambas variables sonconvertidas al mismo tipo y se comprueba si coinciden. En la identidad si el type es diferente, devuelve false.