Argumento de la matriz de PHP por valor, se modifica al hacer un bucle de los elementos de la matriz por referencia

He tenido problemas con la modificación de una matriz cuando se pasa por valor a una función.

Inspeccioné el código y dentro de la función, la matriz está en bucle obteniendo los elementos por referencia.

Me sorprendió ver que después del ciclo, los elementos de la matriz se marcan como referenciados. No sé qué significa esto, pero debe ser el origen de mi problema.

Permítanme poner un ejemplo para ver el punto.

<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);

$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);

function dummy($arg) {
    foreach($arg as &$item) {
        $item[0] = 3;
    }    
    dummy2($arg);
echo '--3--';var_dump($arg);
}

function dummy2($arg) {
    foreach($arg as &$item) {
        $item[1]=9;
    }
echo '--2--';var_dump($arg);
}
?>

Después de este código, esperaría que en el punto 3, $arg tuviera solo un elemento, pero tiene dos, por lo que ha sido modificado por la función dummy2.

El resultado es el siguiente:

--1--array(1) { [0]=> array(1) { [0]=> int(0) } } 
--2--array(1) { [0]=> &array(2) { [0]=> int(3) [1]=> int(9) } } 
--3--array(1) { [0]=> &array(2) { [0]=> int(3) [1]=> int(9) } } 
--4--array(1) { [0]=> array(1) { [0]=> int(0) } }

¿Por qué las matrices están marcadas como &array después de un bucle por referencia? ¿Cómo se puede evitar esto?

preguntado el 12 de junio de 12 a las 22:06

2 Respuestas

Debe desactivar la variable de bucle que captura por referencia:

<?php
error_reporting(E_ALL);
ini_set('display_errors' , 1);

$a = array( array(0) );
echo '--1--';var_dump($a);
dummy($a);
echo '--4--';var_dump($a);

function dummy($arg) {
    foreach($arg as &$item) {
        $item[0] = 3;
    }
    unset($item);
    dummy2($arg);
echo '--3--';var_dump($arg);
}

function dummy2($arg) {
    foreach($arg as &$item) {
        $item[1]=9;
    }
    unset($item);
echo '--2--';var_dump($arg);
}
?>

Ver en el documentación para foreach, hay una gran advertencia roja que dice:

La referencia de un valor de $ y el último elemento de la matriz permanecen incluso después del bucle foreach. Se recomienda destruirlo mediante unset().

Respondido el 13 de junio de 12 a las 05:06

Utiliza key => value pares y devolver la matriz en sus funciones

<?php

    error_reporting(E_ALL);
    ini_set('display_errors' , 1);

    $a = array( array(0) );

    echo '--1--';var_dump($a);

    $a = dummy($a);

    echo '--4--';var_dump($a);

    function dummy($arg) {

        foreach($arg as $key => $value) {

            $arg[$key][0] = 3;
        }

        return dummy2($arg);
    }

    function dummy2($arg) {

        foreach($arg as $key => $value) {

           $arg[$key][1]=9;
        }

        return $arg;
    }
?>

http://codepad.org/f30c6FUj

Respondido el 12 de junio de 12 a las 22:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.