debug_zval_dump

(PHP 4 >= 4.2.0, PHP 5)

debug_zval_dumpVuelca a la salida una cadena con la representación de un valor interno de zend

Descripción

void debug_zval_dump ( mixed $variable [, mixed $... ] )

Volcar a la salida una cadena con la representación de un valor interno de zend.

Parámetros

variable

La variable a ser evaluada

Valores devueltos

No devuelve ningún valor.

Ejemplos

Ejemplo #1 Ejemplo debug_zval_dump()

<?php
$var1 
'Hola Mundo';
$var2 '';

$var2 =& $var1;

debug_zval_dump(&$var1);
?>

El resultado del ejemplo sería:

&string(11) "Hola Mundo" refcount(3)

Nota: Cuidado con refcount

El valor refcount devuelto por esta función no es evidente en determinadas circunstancias. Por ejemplo, un desarrollador puede esperar que el ejemplo anterior indique un refcount de 2. La tercera referencia se crea cuando se realiza la llamada a debug_zval_dump().

Este comportamiento se agrava aún más cuando una variable no se pasa a debug_zval_dump() por referencia. Para ilustrar esto, considere una versión ligeramente modificada del ejemplo anterior:

<?php
$var1 
'Hola Mundo';
$var2 '';

$var2 =& $var1;

debug_zval_dump($var1); // esta vez, no pasada por referencia
?>

El resultado del ejemplo sería:

string(11) "Hola Mundo" refcount(1)

Por qué refcount(1)? Porque una copia de $var1 es realizada, cuando se llama a la función.

Esta función se hace aún más confusa cuando una variable con un refcount de 1 es pasada (por copia/valor):

<?php
$var1 
'Hola Mundo';

debug_zval_dump($var1);
?>

El resultado del ejemplo sería:

string(11) "Hola Mundo" refcount(2)

Un refcount de 2, aquí, no es extremedamente evidente. Especialmente teniendo en cuenta los ejemplos anteriores. ¿Qué ha ocurrido?

Cuando una variable tiene una sola referencia (como ocurría con $var1 antes de que fuera utilizada como un argumento para debug_zval_dump()), el motor de PHP optimiza la manera en que se pasa a una función. Internamente, PHP trata $var1 como una referencia (en esa refcount se incrementa para el ámbito de esa función), con la salvedad de que si la referencia pasa a ser aprobada por escrito y, una copia es realizada, pero sólo en el momento de la escritura. Esto se conoce como "copiar al escribir."

Así que, si debug_zval_dump() pasa a escribir en su único parámetro (y no lo hace), es entonces cuando se haría una copia. Hasta entonces, el parámetro sigue siendo una referencia, haciendo que refcount sea incrementado a 2 en el ámbito de la función llamada.

Ver también

add a note add a note

User Contributed Notes 2 notes

up
8
AmberBlackthorn
3 years ago
The add of "Call-time pass-by-reference" as E_DEPRECATED makes it impossible to get the real refcount without getting an error, since <?php error_reporting(E_ALL ^ E_DEPRECATED); ?> and even <?php @debug_zval_dump(&$foo); ?> doesn't change anything.
up
-7
theriault
1 year ago
You can return a consistent refcount value for any variable (and it will work in PHP 5.3+ without problems) using the following function. 0 is returned if the variable passed has no references outside itself or the variable doesn't exist (use isset in conjunction with this function if you need to distinguish between the two).
<?php
/**
* Return the reference count of a variable.
* Returns 0 if a variable has no reference other than itself or doesn't exist.
*/
function refcount(&$var) {
   
ob_start();
   
debug_zval_dump(array(&$var));
    return
preg_replace("/^.+?refcount\((\d+)\).+$/ms", '$1', substr(ob_get_clean(), 24), 1) - 4;
}

# Example
$a = 34;
refcount($a) == 0;

$b = &$a;
refcount($a) == 1;
?>

Using the above function as a dependency, you can determine if two variables reference the same space in memory using another small function:
<?php
/**
* Return whether a and b reference the same memory
*/
function reference(&$a, &$b) {
   
$d = refcount($b);
   
$e = &$a;
    return
refcount($b) != $d;
}

# Example
$a = 3;
$b = 5;
$c = &$a;
$d = &$c;

reference($a, $b) == false;
reference($a, $c) == true;
reference($a, $d) == true;
?>
To Top