note 106881 deleted from function.memory-get-usage by tularis

From: 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.

« previous php.notes (#185093) next »