3. Páginas Dinámicas con PHP¶
El objetivo de este tema es:
Entender cómo enviar información a un servidor (web/aplicaciones)
Entender cómo recibe y procesa la información el servidor
Desarrollar aplicaciones sencillas que devuelvan contenido web
Las referencias son al manual oficial de PHP. Está en inglés, pero hay traducción a diferentes idiomas (arriba a la derecha en Change language).
Requisitos
Necesitas tener conocimientos básicos del lenguaje PHP (El Lenguaje PHP (básico)) o de cualquier lenguaje que vayas a utilizar en tu entorno de desarrollo en el servidor de aplicaciones.
Está organizado en 8 talleres de unas 3 sesiones de clase. En total unas 24 sesiones de clase más tu trabajo en casa.
La dedicación depende del conocimiento previo, motivación y capacidad de aprendizaje del estudiante para esa sesión en concreto.
3.1. Páginas Dinámicas¶
Páginas Dinámicas
El HTML (o lo que sea) es generado por un lenguaje externo que …
… es ejecutado por un servidor de aplicación que usa un intérprete concreto.
Ejecución usando una interfaz CGI (RFC 3875)
Permite usar un programa externo (en cualquier lenguaje) usando un estándar de intercambio de datos ( Common Gateway Interface )
La entrada estándar al script (variables de entorno) y la salida estandar la devuelve a la conexión
Puede llegar a ser muy potente.
Esquema general de la creación de un HTML dinámico usando CGI¶
Plantea ciertos inconvenientes
Concurrencia. Abre un proceso por cada petición HTTP y puede plantear problemas de concurrencia
Seguridad. Abre la posibilidad a que se ejecuten programas en tu servidor (sin tu permiso)
Un ejemplo (muy avanzado pero interesante) por si quieres profundizar en el uso de CGI
Ejecución usando un módulo integrado
Hoy en día lo más habitual
Se ejecuta en módulos integrados (que necesitan ser instalados). Así se evita lanzar un nuevo proceso por cada petición
Se incluyen en el lenguaje etiquetas específicas dentro del HTML o se ejecuta el script directamente (al estilo CGI)
Hay un montón de posibilidades de creación de páginas dinámicas. Ojo a la diferencia en la generación de las páginas dinámicas:
en Cliente (Front End). Se modifica la que es recibida (se modifica por el cliente HTTP).
en Servidor (Back End). Se modifica en el momento de crearse en el servidor.
Sistema Híbrido (lo habitual). Hay modificaciones en cliente y servidor
Actividad T03-A01. Página Hola Mundo
Prepara tu entorno de desarrollo para hacer tu página Hola Mundo ( en php ).
Si quieres probar la interfaz CGI puedes probar a hacer tu página hola mundo con cualquier lenguaje que se te ocurra (tienes que configurar el servidor adecuadamente).
3.2. Página Dinámica Sencilla¶
Repasando Arrays:
Númericos (php-indexed-array índice númerico -> valor). P.ej mi_variable[0] = “Hola”;
Asociativos (php-associative-array clave -> valor). P.ej mi_variable[«Saludo»] = “Hola”;
Y tienes varias funciones para usarlos -> php-array-functions
Arrays superglobales: ya predefinidos y con valores de la conexión y/o datos enviados
$_SERVER -> reserved.variables.server. Parámetros de la conexión
$_GET[] -> reserved.variables.get. Parámetros en el URL (query string)
$_POST[] -> reserved.variables.post. Parámetros en cuerpo mensaje (no se ve en el URL)
$_FILES[] -> Lo vemos para subir archivos
$_COOKIE[], $_SESSION[], $_ENV[]. Lo vemos al ver el estado de la conexión HTTP
Actividad T03-A02. Diseña una página dinámica que muestre:
La IP del servidor
El nombre del host enviado en la cabecera Host
El método de la petición HTTP
La hora de la solicitud
La página que envía a esta página (referer)
La dirección IP mía (la que consulta la página, no la del servidor)
La cadena de consulta (query_string), si la hubiere
El día de la solicitud y el mes (solo)
¿Y un bucle para imprimir todas las variables y valores del array $SERVER ?
¿Y una función a la que le pases el nombre de la variable y te devuelva el valor? Me refiero a las variables de $_SERVER
3.3. Formularios HTML¶
Formulario: Elemento form
action -> form#action
method -> form#method
y algunos atributos más
Elementos (campos y controles) del Formulario -> Elementos input
Muchos tipos y muy potentes
Atributo input#attributes :
Los 10 habituales y más antiguos: text, password, checkbox, radio, submit, reset, file, hidden, image, button
HTML5 añade 12 tipos más
Usamos el atributo name para obtener el valor (value) del campo. El atributo id lo identifica (de forma única).
Cada elemento tiene sus atributos (y seudo elementos) para personalizarlos
Algunos campos (no input) muy utilizados):
Actividad T03-A03. Diseña un formulario sencillo en HTML
3.4. Formularios Avanzados¶
Mejorar la interfaz del formulario:
Mejoras en HTML5:
Nuevos 12 tipos de input añadidos en HTML5 : email, url, date, time, datetime, month, week, number, range, tel, search, color
Facilitan la validación
Facilitan la accesibilidad
Mejoran el rendimiento
Hay que comprobar la compatibilidad en tus usuarios: html5test
Actividad T03-A04. Diseña un formulario más complejo
Hacer Ejercicio 16 (Curso AG). También puedes probar con los elementos de HTML5 en este otro ejercicio
3.5. Enviar datos al servidor¶
Es un proceso secuencial ( Sending and Retrieving … )
Formulario listo para enviar (validado en el lado del cliente)
Se define a quien se le va a enviar la información -> form#action
Se define una forma de enviar la información -> form#method
Método GET. Los campos van en la cadena de búsqueda (query_string) codificados de una forma concreta ( codificación de URL )
Método POST. Los campos van en el cuerpo del mensaje ( form#enctype)
Se define un conjunto de campos (con name) y valores (value o del usuario), que se envían al servidor
Según tu plataforma de desarrollo web.
Los campos irán en algún tipo de estructura de datos. P.ej. en PHP la información va en el array $_GET y/o $_POST
El lenguaje usa esa información:
para generar su lógica de procesamiento
y (opcional) generar el resultado HTML
¿Cuando usamos GET y cuando POST?
Casi siempre POST (más limpio, más capacidad, codifica los datos, con contraseñas, etc)
A veces GET cuando queremos que se vean los parámetros y para el mismo URL siempre se dan las mismas respuestas ( concepto de idempotencia , no modifica el estado de los datos)
Actividad T03-A05. Formulario básico (con GET y POST)
Crear un servicio que me devuelva el nombre enviado, vía GET, en un campo «nombre». Es decir, que me responda «Hola $nombre», siendo nombre un campo que envío vía GET (fíjate que para esto no necesito ningún formulario).
Igual que el anterior pero usando un formulario y enviando la información con el método POST
3.6. Recibiendo formularios¶
Creas el formulario ( Form Handling ) con todos los campos que necesites
<!-- Una sugerencia en HTML es poner los atributos, p.ej name y type, en orden alfabético --> Nombre: <input name="nombre" type="text" ><br> Nombre: <input name="edad" type="number"><br> Nombre: <input name="email" type="text"><br>
Con cada uno de los campos que llegan al script:
Lo verificas porque no debes fiarte de lo que te envían ( Form Validation )
Decides si es obligario o no ( Form Required )
Piensas qué necesitas:
¿Debe tener valor el campo? -> function.isset
¿Debe existir y sino tener un valor prederterminado? Muy útil el operador de comparación null coalescing -> language.operators
Evitar entrada de caracteres no deseados -> function.htmlspecialchars.php
Filtrar (o sanear) Datos -> function.filter-var.php
Y si usas patrones específicos, nada como usar regex (Taller de Expresiones Regulares)
<?php
$_POST['nombre'] = "Javier";
$_POST['edad'] = 12;
if (!isset($_POST['nombre'])) {
echo "nombre debe tener un valor";
die(); // Sale del script
} else {
$n = htmlspecialchars($_POST['nombre']);
}
$e = $_POST['edad'] ?? '' ;
if (!preg_match("/[0-9]{1,2}/", $e)) {
echo "edad tiene que tener uno o dos dígitos";
die();
}
echo "Pasó la validación (al menos esta)"
?>
Actividad T03-A06. Crea una aplicacion web sencilla
Crea el formulario del Ejercicio 16 (Curso AG) Diseña una aplicación web que recoja esa información y la presente en el navegador de forma legible (para humanos).
Puedes añadirle un control extra sobre el contenido de los valores y que muestre qué errores existen en el formulario de entrada (o lo que le está llegando a la aplicación)
3.7. Enviar archivos¶
Los archivos son un caso especial de envío de información
Añade el tipo de contenido a la solicitud (request) en la cabecera HTTP Content-Type
Lo habitual en un formulario (POST) es Content-Type: application/x-www-form-urlencoded
Pero, para enviar archivos (siempre con POST) Content-Type: multipart/form-data -> form#enctype
Cada plataforma de desarrollo recibirá esos archivos en una variable. En PHP:
Se usa el array $_FILES (reserved.variables.files.php)
Hay diferentes métodos (features.file-upload.post-method.php)
$_FILES es un array bidimensional (hay un array para cada archivo)
El archivo lo dejará en un directorio de tu servidor (necesitas control sobre el servidor)
Aspectos de seguridad:
Subir archivos (puede) ser un riesgo importante de seguridad
Además de la entrada de valores en los campos, un archivo queda en el sistema de almacenamiento (y podría ejecutarse)
Pero no hay mayor problema si lo supervisas (p.ej comprobar function.is-uploaded-file.php o definir el directorio de subida)
Y, como siempre, en estos casos revisa bien los logs del servidor
Para guardar el archivo, lo mueves del campo recibido al sistema de almacenamiento con function.move-uploaded-file.php
Un ejemplo de código resumen:
<?php // Recibiendo un formulario con campo file y name archivo // Uso de null coalescing (devuelve el primer valor no nulo $form_file = $_FILES['archivo']['name']??''; if ($form_file == '') { $html = "<p>¡Uy! Algo pasa con el archivo!</p>"; } else { // Preparar el servidor (directorio y nombre de archivo) $dir_servidor= '/var/www/descargas/'; $nombre_archivo = $dir_servidor . basename($_FILES['archivo']['name']); // Suponemos (es mucho suponer) que no habrá // problemas en el servidor (permisos, espacio, etc) move_uploaded_file($form_file, $nombre_archivo); $html = "<p>Archivo guardado como $nombre_archivo</p>"; } // Con la cadena $html puedo o crear un documento HTML o //incrustar el valor print($html) ?>
Actividad T03-A07. Añade la subida de un archivo en un formulario
Añadele al formulario anterior (Ejercicio 16 (Curso AG)) el envío una imagen, que luego visualizarás al recibirla.
Puedes añadirle que se envíen 3 imágenes.
3.8. Aspectos de Seguridad¶
No te fíes porque:
Los datos no siempre te llegarán de donde esperas (de tu formulario)
Los valores no siempre serán los que crees (se pueden cambiar)
Revisa la puerta. Está en el script que procesa datos de entrada. Es decir, en el PHP (no en el HTML)
Y, en producción, revisa los logs
Las puertas de entrada, en este contexto son:
Los campos de los formularios (si todos son obligatorios o no)
Los valores en los campos de los formularios
Los archivos, tanto su contenido como tipo
Es más complejo (Web Security) de lo que parece, pero no hay que volverse paranoico. Simplemente prestar la atención necesaria.
Lo ideal es tener tu propia librería de validación y saneamiento de datos, porque así podrás utilizarla en todo el código
Y, si ya es algo serio, alguien experto puede probarla
Actividad T03-A08. Revisa la seguridad de tu aplicación web
Usa una librería con las funciones para revisar la entrada de datos
Prueba a usar directamente tu aplicación SIN formulario (vía GET o POST)
Prueba a usar datos que no corresponden a los que te esperas