sentencia multidimensional index for crear con array php

multidimensional - Pase PHP por referencia en foreach



php foreach reference (9)

Esta pregunta ya tiene una respuesta aquí:

Tengo este código:

$a = array (''zero'',''one'',''two'', ''three''); foreach ($a as &$v) { } foreach ($a as $v) { echo $v.PHP_EOL; }

¿Alguien puede explicar por qué la salida es: cero uno dos dos.

De la guía de estudio de certificación zend.


Creo que este código muestra el procedimiento más claro.

<?php $a = array (''zero'',''one'',''two'', ''three''); foreach ($a as &$v) { } var_dump($a); foreach ($a as $v) { var_dump($a); }

Resultado: (Presta atención a los dos últimos conjuntos)

array(4) { [0]=> string(4) "zero" [1]=> string(3) "one" [2]=> string(3) "two" [3]=> &string(5) "three" } array(4) { [0]=> string(4) "zero" [1]=> string(3) "one" [2]=> string(3) "two" [3]=> &string(4) "zero" } array(4) { [0]=> string(4) "zero" [1]=> string(3) "one" [2]=> string(3) "two" [3]=> &string(3) "one" } array(4) { [0]=> string(4) "zero" [1]=> string(3) "one" [2]=> string(3) "two" [3]=> &string(3) "two" } array(4) { [0]=> string(4) "zero" [1]=> string(3) "one" [2]=> string(3) "two" [3]=> &string(3) "two" }


Encontré este ejemplo también complicado. Por qué en el segundo ciclo en la última iteración no pasa nada ($ v permanece ''dos''), es que $ v apunta a $ a [3] (y viceversa), por lo que no puede asignar valor a sí mismo, por lo que mantiene el valor asignado anterior :)


Esta :

$a = array (''zero'',''one'',''two'', ''three''); foreach ($a as &$v) { } foreach ($a as $v) { echo $v.PHP_EOL; }

es lo mismo que

$a = array (''zero'',''one'',''two'', ''three''); $v = &$a[3]; for ($i = 0; $i < 4; $i++) { $v = $a[$i]; echo $v.PHP_EOL; }

O

$a = array (''zero'',''one'',''two'', ''three''); for ($i = 0; $i < 4; $i++) { $a[3] = $a[$i]; echo $a[3].PHP_EOL; }

O

$a = array (''zero'',''one'',''two'', ''three''); $a[3] = $a[0]; echo $a[3].PHP_EOL; $a[3] = $a[1]; echo $a[3].PHP_EOL; $a[3] = $a[2]; echo $a[3].PHP_EOL; $a[3] = $a[3]; echo $a[3].PHP_EOL;


Esta pregunta tiene muchas explicaciones, pero no hay ejemplos claros de cómo resolver el problema que causa este comportamiento. En la mayoría de los casos, es probable que desee el siguiente código en su pase por referencia foreach .

foreach ($array as &$row) { // Do stuff // Unset unset($row); }


Llegué aquí por casualidad y la pregunta de OP llamó mi atención. Lamentablemente, no entiendo ninguna de las explicaciones de la parte superior. Me parece que todos lo saben, lo obtienen, lo acceden, simplemente no pueden explicarlo.

Afortunadamente, una frase pura de la documentación de PHP en foreach deja completamente en claro:

Advertencia: la referencia de $value y el último elemento de matriz permanecen incluso después del bucle foreach. Se recomienda destruirlo por unset ().


Porque en el segundo ciclo, $v sigue siendo una referencia al último elemento de la matriz, por lo que se sobrescribe cada vez.

Puedes verlo así:

$a = array (''zero'',''one'',''two'', ''three''); foreach ($a as &$v) { } foreach ($a as $v) { echo $v.''-''.$a[3].PHP_EOL; }

Como puede ver, el último elemento de la matriz toma el valor del ciclo actual: ''cero'', ''uno'', ''dos'', y luego son solo ''dos'' ...:)


Porque si crea una referencia a una variable, todos los nombres para esa variable (incluido el original) SE HACEN REFERENCIAS.


Primer ciclo

$v = $a[0]; $v = $a[1]; $v = $a[2]; $v = $a[3];

¡Sí! Posición actual $v = $a[3] .

Segundo ciclo

$a[3] = $v = $a[0], echo $v; // same as $a[3] and $a[0] == ''zero'' $a[3] = $v = $a[1], echo $v; // same as $a[3] and $a[1] == ''one'' $a[3] = $v = $a[2], echo $v; // same as $a[3] and $a[2] == ''two'' $a[3] = $v = $a[3], echo $v; // same as $a[3] and $a[3] == ''two''

porque $a[3] se asigna antes del procesamiento.


Tuve que pasar algunas horas para descubrir por qué un [3] está cambiando en cada iteración. Esta es la explicación a la que llegué.

Hay dos tipos de variables en PHP: variables normales y variables de referencia. Si asignamos una referencia de una variable a otra, la variable se convierte en una variable de referencia.

por ejemplo en

$a = array(''zero'', ''one'', ''two'', ''three'');

si lo hacemos

$v = &$a[0]

el elemento 0 ( $a[0] ) se convierte en una variable de referencia. $v apunta hacia esa variable; por lo tanto, si realizamos algún cambio en $v , se reflejará en $a[0] y viceversa.

ahora si lo hacemos

$v = &$a[1]

$a[1] se convertirá en una variable de referencia y $a[0] se convertirá en una variable normal (ya que nadie más apunta a $a[0] se convierte en una variable normal. PHP es lo suficientemente inteligente como para que sea una variable normal cuando nadie más lo señala)

Esto es lo que sucede en el primer ciclo

foreach ($a as &$v) { }

Después de la última iteración $a[3] es una variable de referencia.

Como $v apunta a $a[3] cualquier cambio a $v da como resultado un cambio a $a[3]

en el segundo ciclo,

foreach ($a as $v) { echo $v.''-''.$a[3].PHP_EOL; }

en cada iteración, cuando $v cambia, $a[3] cambia. (porque $v aún apunta a $a[3] ). Esta es la razón por la cual $a[3] cambia en cada iteración.

En la iteración anterior a la última iteración, a $v se le asigna el valor ''dos''. Como $v apunta a $a[3] , $a[3] ahora obtiene el valor ''dos''. Mantén esto en mente.

En la última iteración, $v (que apunta a $a[3] ) ahora tiene el valor de ''dos'', porque $a[3] se estableció en dos en la iteración anterior. two está impreso. Esto explica por qué ''dos'' se repite cuando $ v se imprime en la última iteración.