HTML forms y PHP arrays. (Analizando la mejor forma de implementar arrays en formularios)

Probablemente sepas manejar formularios. Probablemente también sepas implementar php para manejar los datos enviados a través de esos formularios y, por ejemplo, guardar dichos datos en una base de datos. Lo que quizá no sepas es que hay formas muy eficientes de hacer dicho trabajo, como puede ser, por ejemplo, agrupar distintos datos en un solo array de modo que sea más fácil manejarlos.

Yo personalmente soy entusiasta de esta técnica. Siento que mi trabajo es más organizado cuando tengo conjuntos de datos agrupados en arrays a los que me puedo referir de forma sencilla. Sin embargo, puede ser que en tu intento por hacer lo mismo termines haciéndolo de la forma incorrecta.

Consideremos el siguiente ejemplo:

Supongamos que tenemos un formulario, y una de las secciones es acerca de los gustos del usuario. Para esto tenemos los siguientes opciones:

Correr
Leer
Ir al cine
Hacer Yoga
Cocinar
Patinar
Besar bajo la luna
Otros

Como es probable que un usuario guste de más de una de estas actividades, lo mejor sería usar checkboxs que permitan al usuario elegir tantas actividades como guste. La forma común de hacer esto se representa con el siguiente markup:

<input type="checkbox" name="correr" value="correr" /> Correr
<input type="checkbox" name="leer" value="leer" /> Leer
<input type="checkbox" name="ir_al_cine" value="ir al cine" /> Ir al cine
<input type="checkbox" name="hacer_yoga" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="cocinar" value="cocinar" /> Cocinar
<input type="checkbox" name="patinar" value="patinar" /> Patinar
<input type="checkbox" name="besar_bajo_la_luna" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="otros" value="otros" /> Otros
Nótese que estoy omitiendo muchos elementos aquí, como lo puede ser <label> por considerarlos no relevantes para el ejemplo. Por favor no intenten esto en casa lol.

Si te das cuenta, cuando queramos manejar estos datos con php tendremos un montón de datos sueltos. Esta no es una forma realmente inteligente de hacer las cosas ya que dentro del formulario puede que estos datos tengan mucho sentido, pero una vez los sacamos del formulario para empezar a procesarlos con PHP pueden volverse realmente confusos. Por ejemplo, que se supone que “leer” representa una vez lo sacamos de su contexto?

La forma de resolver este problema con los datos sueltos es muy sencilla. Todo consiste en agregar un array mediante HTML. Mira el ejemplo siguiente:

<input type="checkbox" name="gustos_usuario[]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[]" value="leer" /> Leer
<input type="checkbox" name="gustos_usuario[]" value="ir al cine" /> Ir al cine
<input type="checkbox" name="gustos_usuario[]" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="gustos_usuario[]" value="cocinar" /> Cocinar
<input type="checkbox" name="gustos_usuario[]" value="patinar" /> Patinar
<input type="checkbox" name="gustos_usuario[]" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="gustos_usuario[]" value="otros" /> Otros

Como vez hemos creado una estructura un tanto diferente que agrupa todas las diferentes opciones dentro de un solo array, lo cual no hace mucho más fácil el acceso y manejo de esta información. Piensa en la infinidad de posibilidades nuevas ahora que en lugar de tener datos sueltos tenemos un conjunto de elementos relacionados en el cual podemos aplicar loops y demás. Simplemente hermoso. Sin embargo, hay un problema. Que pasa cuando queremos ver si dicha opción fue seleccionada? Por ejemplo, si quiero saber si al usuario le gusta cocinar, como rayos hago referencia a dicha opción?

Un atentado totalmente novato sería ya sea un loop, o hacer referencia a la opción en base a su posición. Ambas opciones son novatadas que deberían evitarse a toda costa. Veamos por que.

Opción 1: Utilizar un loop

El usuario novato promedio haría lo siguiente:

foreach($opciones as $opcion){
     if($opcion == 'cocinar'){
          echo "Le gusta cocinar";
     }
}

Porqué esta no es una buena solución? Simplemente por que consume recursos innecesario chequeando cada una de las opciones que han sido elegidas por el usuario para determinar si al usuario le gusta cocinar. Como  regla general, si estás usando un loop para determinar si un valor está presente en un array, probablemente estás haciendo algo mal.

Opción 2: Utilizar la posición del elemento.

Este es probablemente un intento aún más novato, y que, a diferencia del anterior, no producirá resultados, pero hay quienes lo intentarían. La idea es determinar cual es la posición del elemento a buscar dentro del array y ver si su valor es el deseado. Esto no funciona por que los elementos no aparecerán en el mismo orden dentro del array que dentro del markup. Un novato pensaría que el array producido reflejaría todas y cada una de las opciones existentes sin importar si fueron seleccionadas o no. La verdad es que elementos como checkbox no son enviados a menos que hayan sido seleccionados, por lo que este intento es simplemente fallido. Sería mejor salir a la calle dirigirse hacia el tipo más grande que se encuentre y propinarle una patada en el trasero. Después de todo, si lo que queremos es problemas, más vale que no sean tan grandes.

Como solucionamos el problema?

La solución es usar arrays asociativos. Sin embargo, esto se vuelve ‘tricky’.

Si sabes algo sobre buenas prácticas en php, sabrás que la forma correcta de crear arrays asociativos es esta:

$miArray[‘mi_elemento’] = ‘mi valor’;

El énfasis aquí lo quiero hacer en las comillas al rededor del identificador al cual esta asociado el valor dentro del array. Esto es importante en php ya que esta es la forma correcta de hacerlo. Si no pones las comillas, php tomará el identificador como una constante indefinida y no como una cadena de texto. Sin embargo, si haces lo mismo dentro del formulario de php, estarás haciendo lo equivalente a:

$miArray[“‘mi_elemento'”] =’mi valor’;

Como vez las comillas pasan a ser parte del identificador.

Por que es esto importante?

Si usamos el primer ejemplo, el que usa las comillas dentro del array en php, podemos hacer lo siguiente:

array_key_exists(‘mi_elemento’,$miArray);//regresa true;

Pero si definimos el elemento en el formulario:

<input tytpe=”checkbox” name=”miArray[‘mi_elemento’]”….

Notense las comillas al rededor del identificador,

entonces:

array_key_exists(‘mi_elemento’,$miArray);//regresa false

Esto es por que dicho identificador no existe. Lo que tenemos que hacer es no usar las comillas dentro de nuestros formularios, de modo que el formulario completo quedaría así:

<input type="checkbox" name="gustos_usuario[correr]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[leer]" value="leer" /> Leer
<input type="checkbox" name="gustos_usuario[ir_al_cine]" value="ir al cine" /> Ir al cine
<input type="checkbox" name="gustos_usuario[correr]" value="correr" /> Correr
<input type="checkbox" name="gustos_usuario[hacer_yoga]" value="hacer yoga" /> Hacer Yoga
<input type="checkbox" name="gustos_usuario[cocinar]" value="cocinar" /> Cocinar
<input type="checkbox" name="gustos_usuario[patinar]" value="patinar" /> Patinar
<input type="checkbox" name="gustos_usuario[besar_bajo_la_luna]" value="besar bajo la luna" /> Besar bajo la luna
<input type="checkbox" name="gustos_usuario[otros]" value="otros" /> Otros

De este modo si podemos usar nuestras funciones para arrays confiando en que se comportarán tal como si el array hubiera sido definido en php directamente.

8 thoughts on “HTML forms y PHP arrays. (Analizando la mejor forma de implementar arrays en formularios)

  1. “Por favor no intenten esto en casa lol” jaja.
    Ya llegará la hora para probar esta técnica que la veo bastante prometedora.

    Saludos, escribes bien🙂

  2. Excelente articulo master, es muy buena forma de agrupar los campos mayormente los programadores PHP usan solo un identificador y no lo asocian dentro de un array por ejemplo en un formulario de contacto como este ponen

    name
    email
    message

    en RoR es diferente usamos

    Contact[name]
    Contact[email]
    Contact[message]

    saludos🙂

  3. Ya había practicado tu técnica y se me olvidó venir a comentar. Se aplica bastante bien en checkbox y radio, pero no funciona para multiples pues el atributo name no se puede usar dentro de los que están dentro de él.
    Saludos🙂

  4. Llego demasiado tarde pero el articulo me saco de un apuro. Usé el array de la siguiente manera: $array = $_POST[‘array’];
    $separar = implode(“,”,$array);
    Así puedo usar la variable $separar para una consulta SQL, Saludos y gracias por compartir.

Comments are closed.