PHP y MySQL. Aplicaciones Web: programación PHP I (quinta...

21
PHP y MySQL. Aplicaciones Web: programación PHP I (quinta parte) Autor: Johnny Zulca Mamani 1 mailxmail - Cursos para compartir lo que sabes

Transcript of PHP y MySQL. Aplicaciones Web: programación PHP I (quinta...

Page 1: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

PHP y MySQL. Aplicaciones Web:programación PHP I (quintaparte)Autor: Johnny Zulca Mamani

1

mailxmail - Cursos para compartir lo que sabes

Page 2: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

Presentación del curso

Programación de aplicaciones Web con PHP y MySQL. Ahora estudiaremos elLenguaje de programación PHP. Aprende ahora las formas de escribir las etiquetasPHP. Estudiaremos los formularios Web y PHP, las variables, los tipos de datos devariables y el manejo de archivos.

2

mailxmail - Cursos para compartir lo que sabes

Page 3: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

1. Librería Online. PHP y HTML, etiquetas PHP

Lenguaje de programación PHP

La Aplicación "Librería Online"

Tenemos claro el funcionamiento de una página Web dinámica. La información seencuentra almacenada de manera ordenada en una base de datos conocida comoMySQL. Sabemos que esta base de datos es la manera ideal de ordenar información,y en ella esta todo el contenido de nuestra página Web. Conoceremos las sentenciasbásicas de PHP, potente lenguaje del lado del servidor especialmente diseñado parala creación de páginas Web y que puede incluirse fácilmente dentro del código HTML.

Por el lado del cliente tenemos un usuario que, vía Internet visita nuestra páginaWeb. Para ello utiliza un navegador preparado para recibir páginas Web en HTML. Elproblema es en como hacer que se entiendan ambos. Sabemos que nuestra base dedatos utiliza un lenguaje llamado SQL, que no tiene nada que ver con la páginaHTML estándar que nuestro explorador necesita para mostrar al usuario. Paraintermediar entre ambos es para lo que esta PHP, diseñado para este propósito yque puede incluirse con suma sencillez dentro de código HTML.

PHP y HTML, etiquetas PHP

Para insertar un script PHP dentro de cualquier documento HTML, solo es necesarioingresar las etiquetas de PHP, todo lo que vaya entre estas etiquetas es código enPHP, y será interpretado por el servidor Web, devolviendo los resultados quedeseamos, las instrucciones se separan con ";"

<?etiquetas PHP que código será interpretado como código PHP y lo que esta fueraserá interpretado como código HTML?>

Hay varias formas o modos de escribir las etiquetas de PHP:

1 . <? etiquetas cortas ?> el utilizado requiere, configurar en el archivo "config dephp"2. <?php etiquetas estilo XML?>3. <script language='php'>etiquetas estilo script</script>4. <% etiquetas estilo ASP %>

Práctica 1: miprimerscript.php - Mi primer script

< h t m l ><head><title>Ejemplo de PHP</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">< /head><body><?php echo 'Mi primer script PHP'; ?>< / b o d y >

3

mailxmail - Cursos para compartir lo que sabes

Page 4: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

< / h t m l >

4

mailxmail - Cursos para compartir lo que sabes

Page 5: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

2. Declaraciones y formularios web en PHP

Declaraciones en PHP

echo: imprime la cadena "string" en el navegador ( ; ) para separar declaraciones obien llamado instrucciones en HTML los espacios fuera de las etiquetas no se tomanen cuenta comentarios:

- "/*" comentario multilínea "*/"- // comentario de una sola línea

Formularios Web y PHP

<form name="frmbusqueda" action="procesar.php" method="post">

cajas de texto, botones, listas, opciones

< / f o r m >

Vamos acceder a cada uno de los datos del formulario en el script de php por mediode una variable de cada objeto texto. Para reconocer las variables en PHP,anteponiéndole el signo de "$" seguido del nombre de la variable.

$variable -> es una variable (estilo corto)

Cuando accedemos a los datos de los campos de texto por medio de variables lopodemos hacer de dos modos:

- (corto) utilizamos para la variable el mismo nombre de los campos de texto delformulario HTML, no necesitamos declarar las variables en el código por que sonpasadas dentro del post-código (pasar las variable dentro de procedimientos)

- (largo) mediante la recuperación de valores almacenados en Arrays y existen dostipos dependiendo del método que hayamos usado para enviar el formulario si es elmétodo POST o GET POST, iniciar una nueva secuencia GET, añadir dentro de unapágina ya existente los nuevos datos.

5

mailxmail - Cursos para compartir lo que sabes

Page 6: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

3. Variables del modo largo

Las variables del modo largo describen lo siguiente:

$HTTP_POST_VARS[""], $HTTP_GET_VARS[""]$_POST, $_GETPHP es sensitiva a minúsculas y mayúsculas, se ejecuta mas rápido este modo devariables.

Práctica 2: Formulario de envio de datos, procesar.php - Procesar orden

formulariocontacto.html

<form name="frmContacto" action="procesar.php" method="post"><table><tr><td colspan="2"><h2>Ingrese sus datos</h2></td></tr><t r><td>Nombres :< / td><td><input type="text" name="nombres" size="20"/></td></tr><t r><td>Apel l idos:</ td><td><input type="text" name="apel l idos" size="20"/></td></tr>< t r>< td>Comenta r io :< / td>< td>< / td>< / t r><tr><td colspan="2"><textarea name="comentario" rows="4"co ls="30"></ tex tarea></ td></ t r><tr><td colspan="2"><input type="reset"value="limpiar"/>&nbsp;&nbsp;<input type="submit" value="¡enviary a ! " / > < / t d > < / t r >< / tab le>< / f o r m >

procesar.php

<h4>Datos procesados con exito</h4><?echo "<b>Su nombre es: </b>".$_POST["nombres"]."<br>";echo "<b>Sus apellidos: </b>".$_POST["apellidos"]."<br>";echo "<b>Su comentario es: </b>".$_POST["comentario"]."<br>";?>

6

mailxmail - Cursos para compartir lo que sabes

Page 7: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

4. Variables y tipos de datos de variables

Variables

Una variable es un símbolo para recuperar otros datos que pueden estar en uncampo de texto u otros datos el nombre de cada variable se llama identificadores(letras, números, _), no pueden empezar con un dígito, son case sensitive se declarauna variable también cuando se inicializa la misma.

$mivariable1;$mivariable2 = "texto de la variable 2"

Existen 2 tipos de variables, las variable locales que solo pueden ser usadas dentrode funciones y las variables globales que tienen su ámbito de uso fuera de lasfunciones, podemos acceder a una variable global desde una función con lasinstrucción global nombre_variable;.

Tipos de dato de variables

De acuerdo a que datos se asignada a una variable se adapta a los tipos de datossiguientes: (integer, double, string, arrays, objetos "almacenar instancias de clases")

- Tipo de dato boleano$activo = True; / $activo = False; expresa un valor de verdad

- Tipo de dato Enteros$a = 1200; / $a = -125; numero decimales, numero negativos

- Enteros punto Flotante$a = 1.254; o también llamados (double)

- Cadenas$mensaje = "Esto es una prueba"; se especifican usando uno de dos tipos dedelimitadores ( " ) , ( ` )

Algunos atributos más

- typecase se utiliza para forzar a un tipo de dato una variable (tipo)- Los literales son datos por si mismo

7

mailxmail - Cursos para compartir lo que sabes

Page 8: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

5. Variables predefinidas

Variables Predefinidas

PHP proporciona una gran cantidad de variables predefinidas a cualquier script quese ejecute. De todas formas, muchas de esas variables no pueden estarcompletamente documentadas ya que dependen de sobre que servidor se esteejecutando, la versión y configuración de dicho servidor: estas pueden ser:

Superglobales:

8

mailxmail - Cursos para compartir lo que sabes

Page 9: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

9

mailxmail - Cursos para compartir lo que sabes

Page 10: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

6. Variables php yStrings. Constantes

variables.php - algunas variables predefinidas

<?echo "página actual <b>".$_SERVER["PHP_SELF"]."</b><br>";echo "nombre del servidor <b>".$_SERVER["SERVER_NAME"]."</b><br>";echo "documento raíz <b>".$_SERVER["DOCUMENT_ROOT"]."</b><br>";echo "documento que me llamo<b>".$_SERVER["HTTP_REFERER"]."</b><br>";echo "dirección IP que me esta viendo<b>".$_SERVER["REMOTE_ADDR"]."</b><br>";echo "host <b>".$_SERVER["REMOTE_HOST"]."</b><br>";echo "cabecera actual <b>".$_SERVER["HTTP_USER_AGENT"]."</b>";?>

Strings (cadena de caracteres)

Un string es una cadena de caracteres ya sea solo letras, números o en conjunto. Enlos strings se pueden hacer concatenaciones con el uso del operador "." (punto). Lascadenas de caracteres se pueden especificar usando uno de los dos tipos dedelimitadores ( " ) y ( ` ).

$a = "Hola";$b = $a . "Mundo"; //$b contiene "Hola Mundo"

Constantes

Las constantes es un identificador que se utilizan para almacenar un valor simple yese valor ya no se puede cambiar, solo se pueden definir como constantes valoresescalares (bolean, integer, float, string). Para obtener el valor de una constante soloes necesario especificar su nombre, las constantes pueden ser accedidas sin teneren cuenta el alcance del ámbito y no pueden ser redefinidas o eliminadas despuésde establecerse.

define("$nombre_var","Ha sido reemplazado"), ejemplodefine("CONSTANTE","Hello World");echo CONSTANTE; //el resultado es "Hello World"

1 0

mailxmail - Cursos para compartir lo que sabes

Page 11: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

7. Operadores

Operadores

Operadores matemáticos:

Operadores de comparación:

Operadores lógicos:

1 1

mailxmail - Cursos para compartir lo que sabes

Page 12: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

8. Sentencias condicionales

Sentencias Condicionales

Las sentencias condicionales nos permiten ejecutar o no ciertas instruccionesdependiendo del resultado de evaluar una condición.

Las más frecuentes son la instrucción "if" y la instrucción "switch".

Sentencia if ... else

if(expresion) sentencias; //primera forma de escribirloif(expresion) {sentencias;} //segunda forma de escribirloif(expresion) { //tercera forma de escribirlosentencias;}else{sentencias;}

Sentencias if ... elseif ... else

if(expresion) { //cuarta forma de escribirlosentencias;}elseif(expresion){sentencias;}else{sentencias;}

Sentencias switch ... case

switch(expresion){case expresión1:sentencias1;break;case expresión2:sentencias2;break;}

1 2

mailxmail - Cursos para compartir lo que sabes

Page 13: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

9. Uso de operadores, Sentencias condiciones ySwitch. Práctica

Práctica 3-4: Uso de Operadores, Sentencias Condicionales y Switch (Envío de datosde una orden de pedido calcular costo total pedido, tipo de cliente)

miOrderform.htm: Formulario de orden de pedido

<form action="procesarorden.php" method="post"><table border=0 cellpadding="2" cellspacing="0"><tr bgcolor=#cccccc><td width=150>Libro</td><td al ign="center">Cant idad</td></tr>< t r ><td>Act ionScript</td><td align=center><input type="text" name="actionqty" size="3"max length="3"></ td></ t r>< t r ><td>Photoshop</ td><td align=center><input type="text" name="photoqty" size="3"max length="3"></ td></ t r>< t r ><td>Flash MX </td><td align=center><input type="text" name="flashqty" size="3"max length="3"></ td></ t r>< t r ><td>¿Cómo nos conoció</td><td><select name="find"><option value = "a">Soy un cliente habitual</option><option value = "b">Anuncios de Televisión</option><option value = "c">Informaciones en internet</option>

<option value = "d">Me lo aconsejó un amigo</option></select>< / t d > < / t r >< t r ><td colspan="2" align=center><br><input type="submit" value="EnviarPed ido"></ td></ t r>< / tab le>< / f o r m >

procesarorden.php: script php que procesa orden de pedido

1 3

mailxmail - Cursos para compartir lo que sabes

Page 14: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

10. Estructuras de control

Estructuras de Control

Los bucles o bien llamado estructuras de control nos permiten iterar conjuntos deinstrucciones, es decir repetir la ejecución de un conjunto de instrucciones mientrasse cumpla una condición.

Sentencia while

while(condicion){instrucciones a ejecutar;}

Ejemplo:

$i = 0;while($i<10){echo "El valor de i es " . $i . "<br>";$ i + + ;}

Sentencias do ... while

do{instrucciones a ejecutar;} while(condicion)

Ejemplo:

$i = 0;do{echo "El valor de i es " . $i . "<br>";$ i + + ;} while($i<10)

Sentencias for

for (inicial ; condicion; contador){instrucciones a ejecutar;}

Ejemplo:

for ($i=0;$i<10;$i++){

1 4

mailxmail - Cursos para compartir lo que sabes

Page 15: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

echo "l valor de i es " . $i . "<br>";}

1 5

mailxmail - Cursos para compartir lo que sabes

Page 16: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

11. Break, Continue. Manejo de archivos

Break, Continue

Estas dos instrucciones se introducen dentro de la estructura y nos sirvenrespectivamente para escapar del bucle o saltar a la iteración siguiente. Resultapráctico en algunas ocasiones.

Exit: Nos permiten terminan el script php

Práctica 5 - uso de las estructuras de control (bucles)

bucle_while.php

<h2>Lista de categorias (uso de while)</h2><?$i = 1;echo "<select name=categorias>\n";while($i<=5){echo "<option value=$i>Categoria$i</option>\n";$ i + + ;}echo "</select>";?>

bucle_for.php

<h2>Cuadros de texto (uso de for)</h2><?for($i=1;$i<=5;$i++){echo "caja de texto $i <input type=\"text\" name=\"text$i\" value=\"\"s ize=\ "25\ " /><br> \n" ;}?>Manejo de Archivos

Posiblemente en nuestras tareas de programación nos surja la necesidad de obtenerdatos de un fichero o bien crear uno. PHP nos provee una extensa gama defunciones de acceso a ficheros.

Aquí lo que veremos son las funciones básicas; abrir (fopen), cerrar (close), leer(fgets) y escribir (fputs). Esas 4 funciones nos serán útiles para la mayoría deproblemas que necesitamos resolver con respecto al acceso de ficheros.

1 6

mailxmail - Cursos para compartir lo que sabes

Page 17: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

12. Lenguaje PHP. Funciones básicas (primera parte)

fopen(archivo. modoacceso)

Con esta función abrimos el fichero, bien local o una dirección de Internet (http:// oftp://). La función fopen nos devuelve un valor numérico (indicador de archivo) detipo integer que nos servirá para hacer referencia al archivo abierto, con fopenpodemos abrir ficheros de los siguientes modos:

El código es el siguiente:

if(!fopen("http://www.ciberaula.com/", "r")){echo "El archivo no se puede abrir\n";exit;}

fgets (indicador_archivo, longitud)

La función fgets nos devuelve una cadena con la longitud específica del fichero alque apunta el indicador de archivo.

$archivo = fopen("data.txt", "r");if($archivo){while(!feof($archivo)){$linea = fgets($archivo, 255);echo $linea;}} fclose($archivo);

La funcion feof devuelve True si el puntero de lectura/escritura se encuentra al finaldel fichero y False en caso contrario.

fputs(indicador_archivo, cadena)

1 7

mailxmail - Cursos para compartir lo que sabes

Page 18: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

fputs(indicador_archivo, cadena)

La función fputs escribe una cadena en el fichero indicado. Para escribir en unarchivo este debe haber sido previamente abierto. La función fputs devuelve True sise ha escrito con éxito, en caso contrario devuelve False.

$archivo = fopen("data.txt", "w");if($archivo){fputs($archivo, "Hola Mundo");} fclose($archivo);

fclose(indicador_archivo)

Con esta función cerramos el fichero que nos marca el indicador de archivo,devuelve True si el fichero se cierra  correctamente y False sino se ha podido cerrar.

1 8

mailxmail - Cursos para compartir lo que sabes

Page 19: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

13. Lenguaje PHP. Funciones básicas (segunda parte)

file_exists(fichero)

Esta función devuelve True si el archivo especificado existe y False en caso contrario.

if(file_exists("data.txt")){echo "El fichero existe";}else{echo "El fichero no existe";}

copy(origen, destino)

La función copy copia un fichero de un lugar (origen) a otro (destino), devuelve Truesi la copia ha tenido éxito y False en caso contrario.

if(copy("data.txt","/tmp/data.txt")){echo "El fichero ha sido copiado con exito";}else{echo "El fichero no se ha podido copiar";}

filesize(fichero): Tamaño del archivounlink(fichero): Elimina un archivo

Práctica 6: - manejo de archivos; abrir leer y escribir en un archivo contador.php-implementar un contador utilizando archivos

<?$archivo = "contador.txt";//abrir archivo como lectura y escritura y para sobre escribirlo$fp = fopen($archivo, "r");$contador = fgets($fp, 16);fclose($fp);echo "Usted es el Vistante Nº ".$contador;$contador++;$fp = fopen($archivo, "w");fwrite($fp, $contador, 16);fclose($fp);?>

1 9

mailxmail - Cursos para compartir lo que sabes

Page 20: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

14. Lenguaje PHP. Funciones básicas (tercera parte)

Vamos a ver el caso de subir archivos desde un formulario. Para ello utilizaremos laetiqueta <input> del tipo <type ="file">. El formulario debe usar el método<method=" post"> de envío de datos y el atributo<enctype="multipart/form-data">, así por ejemplo.

<form enctype="multipart/form-data" action="subirarchivo.php"method="post"><input name="archivo" type="file"><input type="submit" value="Subir Archivo">< / f o r m >

Cuando el formulario es enviado, PHP detectara automáticamente que se estasubiendo un archivo y lo colocara en un directorio temporal en el servidor. Dichodirectorio será el que este indicado en el archivo php.ini, o en su defecto en eldirectorio temporal del sistema.

Cuando PHP detecta que se esta subiendo un archivo crea varias variables con elprefijo del nombre del archivo pero con distintas terminaciones. La variableterminada en _name contiene el nombre original del archivo, la terminada en _sizeel tamaño en bytes de este y la variable terminada en _type nos indicará el tipo dearchivo si este es ofrecido por el navegador.

Si el proceso de subida no ha sido correcto la variable archivo tomara el valor none y_size será 0 y si el proceso ha sido correcto, pero la variable terminada en _size da0, quiere decir que el archivo a subir supera el tamaño máximo indicado porMAX_FILE_SIZE en el archivo php.ini.

Una vez subido el archivo, lo primero que debemos hacer es moverlo a otro lugarpues sino se hace nada con el, cuando acabe la ejecución de la pagina se borrara.

Tipos de Archivos:

"image/jpeg","image/gif","application/zip","application/pdf","application/msword","application/vnd.ms-excel","image/png","text/plain","text/php","text/asp","text/css","image/pjpeg","application/x-shockwave-flash"

2 0

mailxmail - Cursos para compartir lo que sabes

Page 21: PHP y MySQL. Aplicaciones Web: programación PHP I (quinta ...imagenes.mailxmail.com/cursos/pdf/3/php-mysql... · PHP y HTML, etiquetas PHP Lenguaje de programación PHP ... que puede

15. Subida de archivos al servidor. Práctica

Aquí el ejemplo

Práctica 7: - Subida de archivos al servidor

subir_archivo.html - Formulario para subir archivos

<form action="upload.php" method="post" enctype="multipart/form-data"><b>Enviar un nuevo archivo: </b>< b r >< b r ><input name="userfile" type="file">< b r >< b r ><input type="submit" value="Enviar">< / f o r m >

<?$folder="upload/"; //destino del archivo por ejemplo el directorio upload/$nombre_File = $_FILES['userfile']['name'];$size_File = $_FILES['userfile']['size'];$tipo_File = $_FILES['userfile']['type'];$temp_File = $_FILES['userfile']['tmp_name'];echo "<h3>Datos del archivo a subir</h3>";echo "Nombre Archivo ".$nombre_File."<br>";echo "Tamaño Archivo ".$size_File."<br>";echo "Tipo Archivo ".$tipo_File."<br>";if(file_exists($folder)){if(!move_uploaded_file($temp_File,$folder.$nombre_File)){echo "Ocurrió algún error al subir el fichero. No pudo guardarse.";}else{echo "El archivo ha sido cargado correctamente.";}}?>

- Subida de multiples archivos al servidor

NOTA: Con este capítulo hemos llegado al final del curso.

2 1

mailxmail - Cursos para compartir lo que sabes