Controles en formularios

Esta lección comenta los aspectos de los formularios con respecto al procesamiento de los datos. Para conocer los aspectos de los formularios con respecto a su apariencia y navegación, se puede consultar la lección sobre formularios en los apuntes de HTML y CSS.

Los ejemplos incluidos en los apartados dedicados a los diferentes controles se componen de cuatro elementos: la etiqueta html, una página de ejemplo que se puede probar, el contenido de la matriz $_REQUEST cuando se recibe la información y un enlace al ejemplo para ejecutarlo en una pestaña aparte.

En construcción Falta comentar los controles introducidos en HTML 5.

Cómo se recibe la información enviada por los controles de los formularios

Para que un control envíe información es necesario:

El programa que recibe los datos los guarda automáticamente en la matriz $_REQUEST.

El siguiente ejemplo muestra un formulario y la página que recibe los datos del formulario. En el ejemplo siguiente, la página que recibe los datos muestra el contenido de la matriz $_REQUEST mediante la orden print_r($_REQUEST).

<!-- Formulario (form-input-1.php) -->
<form action="form-input-2.php">
  <p>Nombre: <input type="text" name="nombre"></p>
  <p><input type="submit" value="Enviar"></p>
</form>
<?php
// Página que recibe los datos del formulario (form-input-2.php)
print "<pre>";
print_r($_REQUEST);
print "</pre>\n";
?>
Enlace a ejemplo

El nombre del elemento de la matriz $_REQUEST coincide con el nombre del control (atributo name) en el formulario, con algunas excepciones que se comentan más adelante.


Los controles deben de tener nombres distintos. Si varios controles tienen el mismo nombre, en la matriz $_REQUEST solo se recibirá uno de ellos, el último, como muestra el siguiente ejemplo.

Desaconsejado
<!-- Formulario (form-name-repetido-1.php) -->
<form action="form-name-repetido-2.php">
  <p>Nombre 1: <input type="text" name="nombre"></p>
  <p>Nombre 2: <input type="text" name="nombre"></p>
  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo

Nota: El código HTML del formulario no es incorrecto, pero el programa PHP no recibiría todos los datos.


El nombre de un control puede ser tanto una cadena de texto como un número. En la matriz $_REQUEST los índices son siempre de tipo cadena excepto si nombre del control es un número entero en cuyo caso el índice es de tipo entero. Los datos enviados por el formulario y recibidos en la matriz $_REQUEST son siempre de tipo cadena, como muestra el siguiente ejemplo.

<!-- Formulario (form-name-cadena-numero-1.php) -->
<form action="form-name-cadena-numero-2.php" method="get">
  <p>Dato 1: <input type="text" name="1"></p>

  <p>Dato 2: <input type="number" name="n" step="any"></p>

  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo

Nota: En los ejercicios propuestos en estos apuntes los nombres de los controles nunca son números debido al procedimiento de recogida de datos que se propone en la lección Recogida de datos. En ese procedimiento, para cada dato recibido se crea una variable que se llama como el control (esto se hace simplemente por simplificar los programas y que sea fácil recordar qué variable corresponde a cada control). Como el nombre de una variable no puede ser un número, los nombres de los controles que se emplean en los ejercicios no son números, pero nada impediría hacerlo (bastaría con elegir nombres de variables válidos, simplemente no coincidirían con los nombres de los controles).


El nombre de un control puede seguir la notación de las matrices de PHP, es decir, incluir corchetes e índices (numéricos o cadenas). La matriz $_REQUEST contendrá entonces una matriz llamada como el control y con los índices indicados, como muestran los ejemplos siguientes:

<!-- Formulario (form-name-matriz-1-1.php) -->
<form action="form-name-matriz-1-2.php" method="get">
  <p>Primer apellido: <input type="text" name="apellidos[1]"></p>

  <p>Segundo apellido: <input type="text" name="apellidos[2]"></p>

  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo
<!-- Formulario (form-name-matriz-2-1.php) -->
<form action="form-name-matriz-2-2.php" method="get">
  <p>Primer apellido: <input type="text" name="apellidos[primero]"></p>

  <p>Segundo apellido: <input type="text" name="apellidos[segundo]"></p>

  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo

El nombre del control puede contener cualquier carácter (números, acentos, guiones, etc), pero en la matriz $_REQUEST PHP convierte en guiones bajos (_) los espacios en blanco ( ), el punto (.) y el corchete abierto ([) si no va acompañado de un corchete cerrado (]) [Referencia]. En el ejemplo siguiente hay tres controles que contienen esos tres caracteres y al enviar el formulario puede verse como en la matriz $_REQUEST los índices contienen guiones bajos en vez de esos caracteres.

<!-- Formulario (form-name-caracteres especiales-1.php) -->
<form action="form-name-caracteres especiales-2.php" method="get">
  <p>Primer dato: <input type="text" name="ejemplo.a"></p>

  <p>Segundo dato: <input type="text" name="ejemplo b"></p>

  <p>Tercer dato: <input type="text" name="ejemplo[c"></p>

  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo

Botón Enviar (input submit, button submit)

Este control se puede crear con la etiqueta <input> o con la etiqueta <button>. En ambos casos, este control se envía siempre que esté definido el atributo name y que se haya hecho clic en el botón. El valor enviado es el valor del atributo value.

Etiqueta html
Ejemplo
$_REQUEST
<input type="submit" value="Submit">
Array
(
)
Enlace a ejemplo
<input type="submit" value="Enviar" name="boton2">
Array
(
    [boton2] => Enviar
)
Enlace a ejemplo
Etiqueta html
Ejemplo
$_REQUEST
<button type="submit">Submit</button>
Array
(
)
Enlace a ejemplo
<button type="submit" name="boton3">Enviar</button>
Array
(
    [boton3] =>
)
Enlace a ejemplo
<button type="submit" name="boton4" value="enviado">Enviar</button>
Array
(
    [boton4] => enviado
)
Enlace a ejemplo

Normalmente no se suele dar el atributo name al botón Enviar ya que el usuario no aporta información en el botón, simplemente hace clic en él para enviar el formulario, pero en algunos casos sí que puede ser conveniente. Por ejemplo, si el formulario contiene varios botones y queremos saber cuál se ha pulsado, como en el ejemplo siguiente, en el que los atributos name son iguales, pero los atributos value son distintos:

Etiqueta html
Ejemplo
$_REQUEST
<p>¿Sí o no?</p>

<p>
  <input type="submit" name="respuesta" value="Sí">
  <input type="submit" name="respuesta" value="No">
</p>
Array
(
    [respuesta] => Sí;
)
Array
(
  [respuesta] => No;
)
Enlace a ejemplo

Atributo formaction de un botón Enviar

El atributo formaction en un botón Enviar permite enviar los controles del formulario a una página distinta a la indicada por el atributo action de la etiqueta form.

<form action="form-input-formaction-2.php" method="get">
  <p>Nombre: <input type="text" name="nombre"></p>
  <p>
    <input type="submit" value="Enviar a 2">
    <input type="submit" value="Enviar a 3"
           formaction="form-input-formaction-3.php">
  </p>
</form>
Enlace a ejemplo

Botón Reset (input reset, button reset)

El botón Reset, tanto si se crea con la etiqueta <input> como con la etiqueta <button>, no envía nunca datos, aunque tenga definido el atributo name. Su única finalidad es devolver los controles del formulario a su valor inicial.

Caja de texto, caja de contraseña y área de texto (input text, input password, textarea)

Los controles caja de texto, caja de contraseña y área de texto se envían siempre, aunque estén vacíos. El valor enviado es el contenido de la caja o área.

Etiqueta html
Ejemplo
$_REQUEST
<input type="text" name="cajaTexto1">
Array
(
    [cajaTexto1] =>
)
Enlace a ejemplo
<input type="password" name="cajaPassword1">
Array
(
    [cajaPassword1] =>
)
Enlace a ejemplo
<textarea rows="4" cols="20" name="areaTexto1"></textarea>
Array
(
    [areaTexto1] =>
)
Enlace a ejemplo

El atributo placeholder permite añadir al control un texto que desaparece al escribir en él. Ese texto no se envía en ningún caso.

Etiqueta html
Ejemplo
$_REQUEST
<input type="text" name="cajaTexto2" placeholder="Escriba aquí cualquier cosa">
Array
(
    [cajaTexto2] =>
)
Enlace a ejemplo
<input type="password" name="cajaPassword2" placeholder="Escriba aquí su contraseña">
Array
(
    [cajaPassword2] =>
)
Enlace a ejemplo
<textarea rows="4" cols="20" name="areaTexto2" placeholder="Escriba aquí cualquier cosa"></textarea>
Array
(
    [areaTexto2] =>
)
Enlace a ejemplo

El atributo value permite incluir texto en las cajas de texto y contraseña (en las área de texto se debe escribir en el interior de la etiqueta textarea). Si no se borra, ese texto sí que se envía, por lo que se recomienda utilizar en su lugar el atributo placeholder.

Etiqueta html
Ejemplo
$_REQUEST
Desaconsejado
<input type="text" name="cajaTexto3" value="Escriba aquí cualquier cosa">
Array
(
    [cajaTexto3] => Escriba aquí cualquier cosa
)
Enlace a ejemplo
Desaconsejado
<input type="password" name="cajaPassword3" value="Escriba aquí su contraseña">
Array
(
    [cajaPassword3] => Escriba aquí su contraseña
)
Enlace a ejemplo
Desaconsejado
<textarea rows="4" cols="20" name="areaTexto3">Escriba aquí cualquier cosa</textarea>
Array
(
    [areaTexto3] => Escriba aquí cualquier cosa
)
Enlace a ejemplo

Casilla de verificación (input checkbox)

Este control se envía solamente si se marca la casilla. El valor enviado es "on" si la casilla no tiene definido el atributo value o el valor del atributo value si éste está definido.

Etiqueta html
Ejemplo
$_REQUEST
<input type="checkbox" name="casilla1">
Array
(
)
Array
(
    [casilla1] => on
)
Enlace a ejemplo
<input type="checkbox" name="casilla2" value="Tres">
Array
(
)
Array
(
    [casilla2] => Tres
)
Enlace a ejemplo

Botón radio (input radio)

Este control se envía solamente si se marca alguno de los botones radio que forman el control. El valor enviado es "on" si el botón marcado no tiene definido el atributo value o el valor del atributo value si éste está definido.

Etiqueta html
Ejemplo
$_REQUEST
Desaconsejado
<input type="radio" name="radio1">
<input type="radio" name="radio1">
Array
(
)
Array
(
    [radio1] => on
)
Array
(
    [radio1] => on
)
Enlace a ejemplo
Correcto
<input type="radio" name="radio2" value="Uno">
<input type="radio" name="radio2" value="Dos">
Array
(
)
Array
(
    [radio2] => Uno
)
Array
(
    [radio2] => Dos
)
Enlace a ejemplo

Menú (select)

Este control envía siempre la opción elegida. El valor enviado es el contenido de la etiqueta option elegida si la opción elegida no tiene definido el atributo value o el valor del atributo value si éste está definido.

Si el menú admite selección múltiple, entonces el nombre del menú debe acabar con corchetes ([]) y se envía como una matriz, de tantos elementos como opciones se hayan elegido.

Etiqueta html
Ejemplo
$_REQUEST
<select name="menu1">
  <option></option>
</select>
Array
(
    [menu1] =>
)
Enlace a ejemplo
<select name="menu2">
  <option>Opción 1</option>
  <option>Opción 2</option>
</select>
Array
(
    [menu2] => Opción 1
)
Array
(
    [menu2] => Opción 2
)
Enlace a ejemplo
<select name="menu3">
  <option value="Uno">Opción 1</option>
  <option value="Dos">Opción 2</option>
</select>
Array
(
    [menu3] => Uno
)
Array
(
    [menu3] => Dos
)
Enlace a ejemplo
<select name="menu4[]" size="3" multiple>
  <option>Opción 1</option>
  <option>Opción 2</option>
  <option>Opción 3</option>
  <option>Opción 4</option>
</select>
Array
(
    [menu4] => Array
        (
            [0] => Opción 1
            [1] => Opción 3
         )
)
Enlace a ejemplo

Control oculto (input hidden)

Este control se envía siempre y el valor enviado es el valor del atributo value.

Etiqueta html
Ejemplo
$_REQUEST
<input type="hidden" name="oculto1">
Array
(
    [oculto1] =>
)
Enlace a ejemplo
<input type="hidden" name="oculto2" value="Cualquier cosa">
Array
(
    [oculto2] => Cualquier cosa
)
Enlace a ejemplo

Imagen (input image)

El control de tipo imagen inserta una imagen que funciona como un botón (aunque Firefox no le da relieve como a los botones). Al hacer clic en un punto de la imagen es como si se hubiera pulsado a un botón submit y se envían las coordenadas del punto en el que se ha hecho clic (junto con los valores de los otros controles del formulario).

El origen de las coordenadas es el extremo superior izquierdo de la imagen. El valor X aumenta a medida que nos desplazamos a la derecha y el valor Y aumenta a medida que nos desplazamos hacia abajo.

Etiqueta html
Ejemplo
$_REQUEST
<input type="image" name="gnu" src="gnu.jpg" alt="Logotipo GNU" height="100">
Array
(
    [gnu_x] => 47
    [gnu_y] => 34
)
Enlace a ejemplo

Las coordenadas se reciben en $_REQUEST en dos elementos que añaden al nombre del control el sufijo _x e _y. En la barra de dirección el nombre aparece con el sufijo .x e .y.

Control de tipo image

Archivo (input file)

El selector de archivo permite enviar un archivo desde el ordenador del cliente al servidor.

En un formulario "normal", este control se envía siempre y el valor enviado es el nombre del archivo elegido.

Etiqueta html
Ejemplo
$_REQUEST
<input type="file" name="archivo1">
Array
(
    [archivo1] => loquesea.txt
)

Para que este control envíe toda la información, el formulario debe tener el atributo enctype con el valor multipart/form-data y ser enviado con el método POST. La información se almacena entonces en la matriz $_FILES (pero no en la variable $_REQUEST).

Etiqueta html
Ejemplo
$_FILES
<form enctype="multipart/form-data"
  action="ejemplo.php" method="post" >
<input type="file" name="archivo2">
Array
(
    [archivo2] => Array
        (
          [name] => loquesea.txt
          [type] => text/plain
          [tmp_name] => C:\ejemplos\loquesea.txt
          [error] => 0
          [size] => 27890
        )
)

Antes de utilizar este control, hay que configurar en el archivo php.ini el tamaño máximo de los archivos que se pueden enviar (mediante la directiva post_max_size) y es conveniente leer el capítulo correspondiente a la subida de archivos del manual de PHP para conocer la manera de evitar los posibles riesgos de seguridad.

En la lección Cargar archivos se comenta un poco más el uso de este control.