A practicar

A practicar con formularios

A practicar Desarrollo

Después de haber visto cómo solicitar datos al usuario y la recogida de datos desde PHP, vamos ahora a practicar con formularios en un nuevo artículo de la serie de A practicar… donde buscamos aplicar los conocimientos adquiridos.

Pero, antes de practicar con formularios, repasemos la solución al reto anterior, en el cual buscábamos practicar con las funciones y que empezaba a complicarse un poco.

Solución al reto anterior

Nuestro anterior reto buscaba, en base al array multidimensional que habíamos diseñado para nuestra agenda, construir una serie de funciones para insertar, modificar, eliminar y consultar las actividades. Vamos a ir viendo cada función paso a paso.

Lo primero será recordar el array multidimensional de ejemplo:

$agenda_diaria = array(
	'lunes' => array(
		array(
			'hora' => '09:35',
			'descripcion' => 'Visita al médico'
		),
		array(
			'hora' => '12:00',
			'descripcion' => 'Clase de inglés'
		)
	),
	'martes' => array(
		array(
			'hora' => '10:00',
			'descripcion' => 'He quedado con Nerea y David para hacer un trabajo'
		),
		array(
			'hora' => '15:15',
			'descripcion' => 'Debo ir a recoger a mi madre a la oficina'
		),
		array(
			'hora' => '22:00',
			'descripcion' => 'No quiero perderme el especial de televisión'
		)
	),
	'miercoles' => array(
		array(
			'hora' => '09:30',
			'descripcion' => 'He quedado con mi tutor'
		)
	),
	'jueves' => array(
		array(
			'hora' => '12:00',
			'descripcion' => 'Clase de inglés'
		)
	),
	'viernes' => array(
		array(
			'hora' => '10:45',
			'descripcion' => 'Cita con mi gestor en el banco'
		),
		array(
			'hora' => '13:00',
			'descripcion' => 'He quedado con mi hermano para ir a comer'
		),
		array(
			'hora' => '18:30',
			'descripcion' => 'Quedada para echar un partido de baloncesto'
		)
	),
	'sabado' => array(
		array(
			'hora' => '10:00',
			'descripcion' => 'Día de limpieza en casa'
		),
		array(
			'hora' => '16:00',
			'descripcion' => 'Tenemos reservado un escape room'
		)
	),
	'domingo' => array(
		array(
			'hora' => '14:00',
			'descripcion' => 'Comida familiar en casa de mis padres'
		)
	)
);

Función insertar_actividad

function insertar_actividad($agenda_diaria, $dia, $hora, $descripcion) {
	$actividad = array(
		'hora' => $hora,
		'descripcion' => $descripcion
	);
	$agenda_diaria[$dia][] = $actividad;

	sort($agenda_diaria[$dia]);

	return $agenda_diaria;
}

Esta función recibirá la propia agenda diaria, una variable string con el día de la actividad insertar, otra variable string con la hora de la actividad (recordad que pusimos que la hora tuviera formato XX:XX y fuera un string, pues aún no hemos visto trabajo con fechas y horas), y una última variable string con la descripción.

Recibida esta información, dentro de nuestra función creamos el array que representará a nuestra actividad y que contendrá, con un índice ‘hora’ la hora de la actividad y con un índice ‘descripcion’ la descripción, valga la redundancia. De esta forma, tenemos replicada la estructura que hemos utilizado para nuestras actividades.

A continuación insertamos esa nueva actividad con la instrucción $agenda_diaria[$dia][], es decir, utilizamos la forma en la que se insertaba un nuevo elemento [] dentro del array $agenda_diaria en el elemento $dia. O sea, que si $dia valiera ‘lunes’, insertaríamos en $agenda_diaria[‘lunes’] la nueva actividad que hemos creado.

¿Qué sucede? Que esta inserción la realizará al final del array para ese día concreto, así que necesitamos ordenarlos. Como tenemos la hora en primer lugar del array, podemos utilizar sort($agenda_diaria[$dia]) para ordenar ese día concreto. Ordenará por los elementos y, al ser el primer elemento la hora, al final hace lo que queremos, ordenar por la hora (si ordenáramos por descripción sería algo más complicado).

Finalmente, devolvemos $agenda_diaria con las modificaciones realizadas.

Función eliminar_actividad

function eliminar_actividad($agenda_diaria, $dia, $hora) {
	foreach ($agenda_diaria[$dia] as $indice_numerico => $actividades) {
		foreach ($actividades as $indice_actividad => $valor_actividad) {
			if ($indice_actividad === 'hora') {
				if ($hora === $valor_actividad) {
					unset($agenda_diaria[$dia][$indice_numerico]);
				}
			}
		}
	}

	return $agenda_diaria;
}

A esta función le pasamos la agenda junto con el día y la hora que queremos eliminar. No necesitará recibir la descripción, pues nos vale con la hora para localizar la actividad.

Para ello, recorremos $agenda_diaria[$dia], es decir, recorremos el día que hemos indicado que está la actividad a eliminar. En este FOREACH definimos también el $indice_numerico además de las actividades de cada día, porque vamos a necesitar ese índice. Recordar que nuestras actividades no tienen índice definido, por lo que utilizan índices numéricos.

A continuación, recorremos ahora todas las actividades de ese día concreto también con un FOREACH en el que necesitaremos el índice de los elementos, guardado como $indice_actividad y el valor de los elementos. Esto hará que recorramos la hora y descripción de las actividades sabiendo en qué elemento estamos en cada momento.

Gracias a ello, hacemos una comparación con un IF buscando cuándo nuestro $indice_actividad es la hora. En el momento en que estemos en este elemento, miramos si la hora que hemos indicado con la variable $hora y que es la de la actividad a eliminar coincide con el valor de la actividad actual. Recapitulemos, hemos llegado al elemento ‘hora’ de una actividad del día buscado. Ahora miramos si la hora de esa actividad es la hora que estamos buscando para eliminar.

Si es así, es decir, hemos llegado a la actividad del día y hora que queremos borrar, entonces hacemos unset($agenda_diaria[$dia][$indice_numerico]). Revisemos bien, queremos borrar de la agenda, en un día concreto, una actividad a la que accedemos por ese índice numérico. De ahí que lo guardáramos.

El FOREACH continuaría llegando hasta la descripción y el FOREACH inicial también continuaría buscando en las siguientes actividades. Lo he dejado así para que veáis que ésto nos lo podemos ahorrar con una buena sentencia break (habría que colocar dos en este caso). Os lo dejo a vosotros o utilizad los comentarios si tenéis dudas.

Finalmente devolvemos la agenda que ya no tendrá a ese elemento.

Parece complicado, y de hecho lo es si no se está familiarizado y si no se hace una pequeña traza para ver en cada momento por dónde va la ejecución. Hacerlo a la primera, sobre todo si no se lleva mucho tiempo, no es fácil. Lo normal es que vayáis probando y encontrándoos errores para aprender de ellos.

Función modificar_actividad

function modificar_actividad($agenda_diaria, $dia, $hora, $actividad) {
	$agenda_diaria = eliminar_actividad($agenda_diaria, $dia, $hora);
	$agenda_diaria = insertar_actividad($agenda_diaria, $dia, $actividad['hora'], $actividad['descripcion']);

	return $agenda_diaria;
}

Esta función se especificaba que recibiera el día, la hora y la actividad y utilizara las dos funciones que hemos definido anteriormente para implementarla. Realmente, lo que estamos haciendo es eliminando una actividad e insertando una nueva. No estamos modificando y, aunque por supuesto podríamos hacerlo modificándola (y hubiera sido más eficiente), he preferido hacerlo así para utilizar funciones dentro de funciones y ver que podemos reaprovechar funcionalidades.

En primer lugar, llamamos a eliminar_actividad con la hora de la actividad que queremos modificar y nos guardamos el resultado, que será la agenda sin esa actividad que se ha eliminado.

En segundo lugar, llamamos a insertar_actividad pasándole, además del mismo día por razones obvias, la nueva hora de la actividad $actividad[‘hora’] y la nueva descripción $actividad[‘descripcion’]. Es decir, nuestro argumento $actividad debe ser un array con la hora y la descripción, o fallará.

Por tanto, repetimos, lo que hemos hecho es eliminar una actividad concreta en base a su día y hora y, después, insertar una nueva actividad el mismo día y con los nuevos datos de hora y descripción. No es lo más eficiente pero funciona.

Finalmente devolvemos de nuevo la agenda con las modificaciones realizadas.

Función consultar_dia

function consultar_dia($agenda_diaria, $dia) {
	if (!empty($agenda_diaria[$dia])) {
		echo 'El ' . strtolower($dia) . ' tienes las siguientes actividades:<br>';
		foreach ($agenda_diaria[$dia] as $actividades) {
			echo '- A las ' . $actividades['hora'] . ': ' . $actividades['descripcion'] . '<br>';
		}
		echo '<br>';
	} else {
		echo 'El ' . strtolower($dia) . ' no tienes ninguna actividad<br><br>';
	}
}

Esta función es más sencilla pensando en que no tenemos que modificar ni añadir ni eliminar nada. Pero vamos a tener en cuenta algunas cositas a la hora de mostrar la información por pantalla.

Primero comprobamos si el día que queremos mostrar está vacío. Hemos utilizado en este caso !empty($agenda_diaria[$dia]), es decir si NO está vacío utilizando el operador lógico NOT con símbolo ! con lo que, si la agenda no está vacía, mostraremos por pantalla las actividades. Y si está vacía, acabará yendo al ELSE y mostrando ese mensaje. También podríamos haber usado count($agenda_diaria[$dia]) > 0 porque, si hay actividades, el número de elementos será mayor que cero, obviamente. No estoy seguro, pero creo que es más eficiente la forma empty para este caso.

Para mostrar el día hemos utilizado la función strtolower. En este caso hubiera dado igual, pues nuestros índices estaban ya en minúsculas. Pero si hubiéramos definido índices en mayúsculas, por ejemplo, nos viene bien esa función para transformar los caracteres en minúsculas para que el mensaje esté mejor escrito. Así pues, recorremos las actividades de ese día concreto (fijaos que no necesitamos el índice en el FOREACH ahora) y mostramos un mensaje accediendo a la hora y la descripción de la actividad. Al final imprimimos un <br> más simplemente por estética, para separar todos los días.

Esta función, como veis, no devuelve nada, pues se ha limitado a mostrar las actividades de un día por pantalla.

Función eliminar_actividades_de_un_dia

function eliminar_actividades_de_un_dia($agenda_diaria, $dia) {
	foreach ($agenda_diaria[$dia] as $actividad) {
		$agenda_diaria = eliminar_actividad($agenda_diaria, $dia, $actividad['hora']);
	}

	return $agenda_diaria;
}

Esta función necesita la agenda y el día que queremos eliminar. Simplemente va a recorrer todas las actividades de ese día y a eliminarlas una a día utilizando la función que ya habíamos definido eliminar_actividad.

Finalmente, devolvemos la agenda con las modificaciones. Pero, un momento, ¿por qué estamos devolviendo todo el rato la agenda cuando modificamos algo?

¿Por qué devolvemos siempre la agenda?

Podríamos pensar que, pasándole a las funciones la variable $agenda_diaria y modificándola dentro de las funciones, no haría falta devolver nada. Ya estamos modificando las funciones. Pero esto no es cierto.

Ya llegaremos en el futuro dentro de unos pocos artículos pero, realmente, a la función le estamos pasando una copia de $agenda_diaria con lo que las modificaciones las hace sobre esta copia. Si no devolviéramos esa copia, el array inicial no se modificaría nunca y nuestras funciones no tendrían sentido.

Hay varias maneras para evitar ésto, como por ejemplo el paso de valores por referencia o la utilización de variables globales. Sin embargo, aún es pronto para verlo, así que por ahora nos vale con saber que estamos pasándole realmente una copia de la variable.

Ejemplo de uso

Definidas todas nuestras funciones, habrá que usarlas. He aquí unas líneas de código para comprobar que todo funciona correctamente:

$agenda_diaria = insertar_actividad($agenda_diaria, 'lunes', '10:55', 'Recoger paquete');
$agenda_diaria = insertar_actividad($agenda_diaria, 'lunes', '21:55', 'Nuevos capítulos de la serie');
$agenda_diaria = eliminar_actividad($agenda_diaria, 'viernes', '10:45');
$agenda_diaria = modificar_actividad($agenda_diaria, 'miercoles', '09:30', array('hora' => '09:45', 'descripcion' => 'He quedado con mi tutor en su despacho'));
$agenda_diaria = eliminar_actividades_de_un_dia($agenda_diaria, 'domingo');

foreach ($agenda_diaria as $dia => $actividades) {
	consultar_dia($agenda_diaria, $dia);
}

Sólo indicar que modificar_actividad, como hemos visto, necesita un array con la actividad completa. Podríamos haber definido el array fuera de la función y habérselo pasado a través de una variable o haberlo definido como en el ejemplo, directamente en el argumento.

Por último, para consultar los días en lugar de ir indicando día por día, recorremos $agenda_diaria sabiendo que sus índices son los nombres de los días. Así podemos utilizar un FOREACH con la función consultar_dia y mostrar todos los días.

En este caso, ésto veríamos por pantalla:

El lunes tienes las siguientes actividades:
- A las 09:35: Visita al médico
- A las 10:55: Recoger paquete
- A las 12:00: Clase de inglés
- A las 21:55: Nuevos capítulos de la serie

El martes tienes las siguientes actividades:
- A las 10:00: He quedado con Nerea y David para hacer un trabajo
- A las 15:15: Debo ir a recoger a mi madre a la oficina
- A las 22:00: No quiero perderme el especial de televisión

El miercoles tienes las siguientes actividades:
- A las 09:45: He quedado con mi tutor en su despacho

El jueves tienes las siguientes actividades:
- A las 12:00: Clase de inglés

El viernes tienes las siguientes actividades:
- A las 13:00: He quedado con mi hermano para ir a comer
- A las 18:30: Quedada para echar un partido de baloncesto

El sabado tienes las siguientes actividades:
- A las 10:00: Día de limpieza en casa
- A las 16:00: Tenemos reservado un escape room

El domingo no tienes ninguna actividad

Vemos que todo ha ido bien. Se han añadido al lunes las dos actividades que queríamos, se ha eliminado la actividad del viernes a las 10:45, se ha modificado correctamente la actividad del miércoles, se han eliminado todas las actividades del domingo y hemos consultado todos los días. Reto completado.

Siguiente reto

Después de todo el repaso que le hemos dado a los formularios para poder solicitar datos al usuario y cómo recoger los datos en PHP, además de tener ya instalado un servidor local, podemos ya empezar a pedir datos al usuario y practicar con formularios. Por ahora sin preocuparnos de la seguridad o de la validación de datos (vendrá en próximos artículos), pero sí para empezar a hacer cosas a partir de datos introducidos por un usuario y practicar con formularios. Vayamos con el reto:

A practicar 2.0.1

Nos proponemos realizar un programa que calcule ecuaciones tanto de primer grado como de segundo grado. Para ello, tenemos las siguientes directrices:

– Para practicar con formularios construiremos un formulario en una página HTML completa, es decir, con su etiqueta <head>, su <title> y el contenido dentro de <body>. Este archivo se llamará ecuacion.html

– El contenido tendrá un <h1> con el título del programa y un formulario que pedirá al usuario su nombre, un selector desde donde decidirá si quiere resolver una ecuación de primer o segundo grado y tres campos para añadir los valores de a, b y c

– La parte en PHP se compondrá de dos funciones, una que se encargará de resolver la ecuación de primer grado y la otra que se encargará de resolver la de segundo grado. Este archivo se llamará resolviendo.php

– Obtendrá los datos introducidos en el formulario y, en función de si ha escogido resolver una ecuación de primer o segundo grado, utilizará la función para tal cometido

– Dichas funciones, en cuanto tengan el resultado, lo deberán imprimir en un mensaje por pantalla

Se recuerda y especifica claramente que se deben tratar todas las posibles situaciones en las que las ecuaciones pueden mostrar sus soluciones.

Utilizaremos ya el servidor local para realizar estos dos archivos, practicar con formularios y probarlos cada uno en su propio equipo en casa sin necesidad de nada externo. En dos semanas tendremos el artículo con la resolución. No olvidad que podéis dejar dudas o resultados en los comentarios si estáis registrados. ¡A practicar con formularios!

Deja una respuesta