note 106881 deleted from function.memory-get-usage by tularis
| From: | tularis@php.net | Date: | Fri, 16 Dec 2011 19:22:33 +0000 |
| Subject: | note 106881 deleted from function.memory-get-usage by tularis | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-185093@lists.php.net to get a copy of this message | ||
Note Submitter: z666zz666z at terra dot es
Reason: non-english
----
Para liberar la memoria de un array con un foreach.
Supongamos definido un array del estilo:
$MiArray=array(
array(
'Id'=>22
,'Nombre'=>'LoQueSea'
,'Apellidos=>'OtraCadanea'
),
array(
'Id'=>13
,'Nombre'=>'LoQueSea'
,'Apellidos=>'OtraCadanea'
)
);
Si usamos el siguiente código no se liberarÃa la memoria porque en el propio foreach se
estarÃa haciendo una copia:
foreach($MiArray as $ElementoDelArray){ // Aquà se hace una copia y lo que se liberará es la
copia, no el original
unset($ElementoDelArray['Id']);
unset($ElementoDelArray['Nombre']);
unset($ElementoDelArray['Apellidos']);
}
print_r($MiArray);
Sin embargo si lo hacemos asà (nótese el ampersand '&'), si libera la memoria:
foreach($MiArray as &$ElementoDelArray){ // Asà no se hace ninguna copia y por tanto se
liberará la memoria del original
unset($ElementoDelArray['Id']);
unset($ElementoDelArray['Nombre']);
unset($ElementoDelArray['Apellidos']);
}
print_r($MiArray);
Esto es algo muy habitual de olvidarse, algo que me han preguntado muchas veces.
Lo pongo aquÃ, porque la mayorÃa piensa que está liberando la memoria bien y creen que
memory_get_usage no está dando el valor correcto, el problema no es de memory_get_usage sino de
olvidarse el '&' en el foreach.
Si en lugar de usar el foreach de ese modo [foreach($MiArray as $Elemento)...] se usa un bucle for
con un Ãndice este problema de la copia no aparece:
for($i=0;$i<sizeof($MiArray);$i++){
unset($MiArray[$i]['Id']);
unset($MiArray[$i]['Nombre']);
unset($MiArray[$i]['Apellidos']);
}
Nota: Lo que se pretende liberar no es todo el array en si, sino sub-elementos de los elementos...
array de dos dimensiones o array de pares, en una tÃpica tabla de datos con registros y varios
campos por registro, se estarÃa intentando liberar algún campo, no todo el registro, por
ejemplo para quitar en todos los registros un campo, vamos como eliminar una columna.
Para eliminar todo el array bastarÃa con un único unset, asÃ:
unset($MiArray)
Y para eliminar un registro concreto bastarÃa con:
unset($MiArray[$ElIndiceDelRegistroDeseadoDeEliminar]);
Espero esto les sirva de ayuda... recuerden, el foreach sin el '&' hace una copia.