php - programming - ¿Bug o hack? $ GLOBALES



most languages (1)

$GLOBALS["items"] = array('one', 'two', 'three', 'four', 'five' ,'six', 'seven');
$alter = &$GLOBALS["items"]; // Comment this line
foreach($GLOBALS["items"] as $item) {
  echo get_item_id();
}

function get_item_id(){
  var_dump(key($GLOBALS["items"]));
}

Verifique la salida de este código, con una segunda línea comentada y sin comentarios. Mi resultado (PHP 5.3.0). Con segunda linea

int(1) int(2) int(3) int(4) int(5) int(6) NULL

Sin segunda línea:

int(1) int(1) int(1) int(1) int(1) int(1) int(1)

¿Por qué resultado tan extraño?

https://src-bin.com


Answer #1

Aquí hay una posible explicación:

Sabemos que foreach siempre recorre una copia de la matriz si no se hace referencia a ella :

A menos que se referenced la matriz, foreach opera en una copia de la matriz especificada y no en la propia matriz. foreach tiene algunos efectos secundarios en el puntero de matriz.

Eso significa que el puntero interno de la matriz original no se cambia y key() siempre devolverá el mismo valor (como podemos ver cuando comentamos la línea). Y de hecho si hacemos un var_dump($GLOBALS) , obtenemos:

 ["items"]=>
  array(7) {
    [0]=>
    string(3) "one"
    [1]=>
    string(3) "two"
    [2]=>
    string(5) "three"
    [3]=>
    string(4) "four"
    [4]=>
    string(4) "five"
    [5]=>
    string(3) "six"
    [6]=>
    string(5) "seven"
  }

(sin referencia)

Pero tan pronto como generamos una referencia a la matriz (con $alter ), $GLOBALS['items'] convierte en una referencia, porque ambas entradas deben apuntar a la misma matriz:

 ["items"]=>
  &array(7) {
    [0]=>
    string(3) "one"
    [1]=>
    string(3) "two"
    [2]=>
    string(5) "three"
    [3]=>
    string(4) "four"
    [4]=>
    string(4) "five"
    [5]=>
    string(3) "six"
    [6]=>
    string(5) "seven"
  }
  ["alter"]=>
  &array(7) {
    [0]=>
    string(3) "one"
    [1]=>
    string(3) "two"
    [2]=>
    string(5) "three"
    [3]=>
    string(4) "four"
    [4]=>
    string(4) "five"
    [5]=>
    string(3) "six"
    [6]=>
    string(5) "seven"
  }

Por lo tanto, el bucle foreach itera sobre la matriz original y cambia el puntero interno, que afecta a key() .

En resumen: es un problema con referencias, no con $GLOBALS .





global-variables