2012-04-01 12 views
9

Una cosa que a menudo quiero hacer es convertir una gran matriz asociativa, generalmente de una solicitud POST (un formulario de registro, por ejemplo, con muchas entradas) en variables locales basado en la clave de la matriz. Si usa los valores de la matriz a menudo, su código se llena rápidamente con nombres de variables largos y comillas.Convertir matrices asociativas grandes en variables locales, basadas en la clave

Para evitar esto para las pequeñas matrices asociativas, es aceptable que acaba de hacer algo como esto:

$username = $_POST['username']; 
$password = $_POST['password']; 

No estoy escapando de ellos para este ejemplo para mantener todo lo más depurada posible, para relajarse.

También puede hacer esto:

list($username, $password) = $_POST; 

Pero lo que si el array $ _POST es más grande? Entonces se vuelve tedioso hacer ambos métodos. Para solucionarlo, puede ejecutar un ciclo como este:

foreach($arr as $key => $value) 
{ 
    ${$key} = $value; 
} 

El problema con este método es que asigna variables locales. Sería bueno si fuera posible llamar a una función en una clase padre que ejecuta este ciclo y esas variables locales fueran accesibles dentro de la clase llamante. Imagine una configuración MVC donde cada controlador se deriva de una clase Controller, y lo mismo ocurre con los modelos. Sería bueno hacer:

$this->localize($_POST); 
doWhatever($username) // $username works! Assuming $_POST['username'] is defined 

Creación de un procedimiento de este tipo hace que las variables locales a sólo permanecen dentro del ámbito de la función localize() en la clase padre, así que esto no va a funcionar. Lo que he estado haciendo es ejecutar el mismo bucle con una modificación:

foreach($arr as $key => $value) 
{ 
    $this->{$key} = $value; 
} 

Esto funciona y todo, pero en realidad no se resuelve el problema inicial. En lugar de código que está desordenado con corchetes y comillas, tiene $this-> en todas partes, sin mencionar que está asignando variables que nunca se definieron formalmente dentro de la clase.

Así que, finalmente, mi pregunta: ¿es posible la creación de una función como la localize() he descrito, de tal manera que se puede heredar de una clase padre, sino crear las variables locales relativos a la clase hija ($username en lugar de $this->username).

Además, ya sea que pueda o no, ¿se considera una mala práctica? A mí me parece un poco hacky, y estás ignorando algunos principios de OOP. Si es así, ¿utilizas una solución para solucionar la fealdad y el desorden de los grandes conjuntos asociativos, o simplemente te ocupas de ello?

Respuesta

17

La función PHP extract hace exactamente esto.Extrae un hash en el espacio de nombres locales:

http://us3.php.net/extract

En una adición importante:

Asegúrese de utilizar la opción EXTR_SKIP para extract() si la función está actuando en los nombres de variables suministradas por el usuario (por ejemplo, proporcionada por $_POST) para evitar la redefinición de las variables existentes:

$myvar = 'abc'; 
extract($_POST, EXTR_SKIP); // $_POST['myvar'] won't overwrite $myvar. 
+1

Eso es justo lo que necesitaba, gracias. Parece bastante seguro si usas 'EXTR_SKIP'. Es una locura cómo puedes estar haciendo PHP durante tantos años y te pierdes estas funciones básicas ... Necesito comenzar a leer más el manual. –

+1

Estaba codificando php por más de 5 años antes de descubrir 'extract()'. Hay muchas funciones incorporadas oscuras pero poderosas. – leepowers

1

Es una mala práctica, los usuarios podrán redefinir cualquiera de sus variables simplemente pasando la llave en la matriz POST, es bastante simple y funciona así, y es por eso que esta habilidad está obsoleta en 5.3 y eliminada en 5.4.

Cuestiones relacionadas