2018 PHP Básico PROGRAMACIÓN GENÉRICA STUDIUM Programación Web Introducción En el mundo de la programación originariamente teníamos la programación de aplicaciones de escritorio para un único sistema y usuario. Posteriormente, y gracias a la implantación de las redes, las aplicaciones se fueron expandiendo y ya se podían instalar en varios sistemas y con varios usuarios y poder interactuar entre ellos. Nacía la programación distribuida. Hoy en día, con la expansión casi a nivel mundial de Internet, esta programación distribuida se ha elevado al nivel de programación web o en la nube: cualquier persona desde cualquier equipo, con cualquier sistema operativo, con cualquier software, y con una simple conexión a Internet, puede tener acceso a sus aplicaciones, documentos, datos, etc. Las aplicaciones de escritorio no son sustituidas por las aplicaciones web, ni viceversa. Simplemente tienen diferentes usos según las necesidades de los usuarios. En ocasiones habrá que desarrollar aplicaciones de escritorio, en otras ocasiones habrá que desarrollar aplicaciones web, en otras tantas crearemos aplicaciones para dispositivos móviles y en otras habrá que hacer un híbrido entre todas para dar servicio a un gran número de usuarios. Si nos centramos en las aplicaciones web, el lenguaje que destaca por encima de todos actualmente es PHP, y lleva en los primeros lugares muchos años. Próximamente desbancado puede por las ser nuevas generaciones de lenguajes como JavaScript y sus variantes, así como Python o C#. Pero de momento, una gran cantidad de aplicaciones en Internet están desarrolladas en este PHP en sus últimas versiones, por lo que todavía hacen faltan muchos desarrolladores conozcan esta tecnología programación web. Página 1 de 59 que de Programación Web Si en la gráfica, quitamos los primeros puestos por ser lenguajes de programación usados fundamentalmente en aplicaciones de escritorio1, el primer leguaje de programación web que aparece es PHP. En el presente manual, veremos los aspectos más generales para poder realizar todo tipo de aplicaciones web con este popular lenguaje de programación, comenzando por los elementos básicos de cualquier lenguaje de programación, viendo la funcionalidad principal y acabando por cuestiones como operaciones CRUD en acceso a bases de datos y alguna que otra funcionalidad avanzada que se verán en el manual “PHP Avanzado”. Como podemos observar leyendo el párrafo anterior, este manual está pensado para aprender PHP sabiendo ya programar en algún otro lenguaje de programación. Entorno para trabajar Lo primero que vamos a hacer es “montar” un sistema que nos permita desarrollar en PHP. Los requisitos son los siguientes: • Servidor de páginas Web o Servidor Web a secas, como pueden ser el archiconocido Apache, pero también el Nginx o el Internet Information Server (IIS) de Microsoft. El servidor web se debe configurar para servir páginas PHP. • Un editor de texto para escribir el código PHP. Desde el sencillo Notepad ++ hasta el potente Microsoft Visual Studio Community, pasando por Eclipse, Sublime o algunos otros específicos de PHP. • Por último, para ver el resultado, un simple navegador web como el Chrome o el Firefox. Algunos entornos de programación tienen su propio navegador web para probar el código PHP dentro del propio programa. Para este curso de PHP usaremos uno de los buenos paquetes que existen en el mercado que “montan” toda la infraestructura de forma sencilla y rápida. Nos estamos refiriendo a los paquetes AMP, que instalan el servidor web Apache, con soporte para PHP y además un servidor de bases de datos MySQL Server. Según el sistema operativo tenemos el WAMP para Windows, el LAMP para Linux y el MAMP para Mac. Pero MAMP se ha desarrollado también para Windows y es muy cómodo de instalar y configurar, así que optaremos por este. 1 JAVA también permite el desarrollo de aplicaciones Web, pero no es su uso fundamental. Página 2 de 59 Programación Web Podemos descargarlo en su página oficial. La versión Pro es de pago, así que nos conformaremos con el gratuito. Aunque la instalación se tenga que hacer en inglés, luego el software se puede usar en castellano. En la pantalla correspondiente, hay que desmarcar las opciones de instalación de MAMP Pro y de Apple Bonjour. Página 3 de 59 Programación Web En la pantalla en la que nos pide la ubicación de la instalación es importante elegir bien la ruta, pues nuestros proyectos PHP tendrán que “montarse” a partir de dicha ruta. Página 4 de 59 Programación Web La instalación no debe suponer ningún problema. Si se necesitase algún software adicional, el propio instalador de MAMP se encargará de instalarlo, previo aviso por pantalla al usuario. Debemos tener en cuenta que, si tenemos ya instalado algún servidor web o algún servidor de MySQL, pueden entrar en conflicto. La última versión de MAMP lo detectará y nos propondrá la configuración del nuevo software con puertos diferentes para que todo funcione correctamente. Página 5 de 59 Programación Web Una vez acabado todo el proceso de instalación, ya podemos ejecutar nuestro MAMP. La primera vez, debemos aceptar los avisos del cortafuegos, uno por cada servicio instalado: Página 6 de 59 Programación Web Ya nos aparecerá el panel principal de la aplicación, arrancando los servicios de forma automática. Si no arrancasen de forma automática, podemos hacerlo nosotros manualmente con “Start Servers”. Página 7 de 59 Programación Web Igualmente podemos parar los servidores con “Stop Servers”. Página 8 de 59 Programación Web En “Preferences” podemos configurar nuestro MAMP con multitud de opciones: Página 9 de 59 Programación Web Si tenemos los servicios activos marcados en verde como se puede ver arriba a la derecha, ya podemos probar nuestro servidor de páginas web pulsando en “Open start page”. Se abrirá nuestro navegador por defecto cargando la página principal de MAMP: Si obtenemos esta pantalla o similar, todo está correcto. Aquí podemos ver multitud de opciones: versiones de PHP y de MySQL disponibles, códigos de ayuda, herramientas instaladas como phpMyadmin, etc. De momento nos centraremos en probar una primera aplicación en php desarrollada por nosotros. Página 10 de 59 Programación Web Primera aplicación Comenzaremos abriendo nuestro editor de código favorito, creando un nuevo fichero en blanco2 e introduciendo el siguiente código PHP: <?php echo "<h1>Hola mundo</h1>"; ?> Ahora debemos elegir la ubicación de nuestra aplicación web. Debemos elegir una carpeta creada dentro de la carpeta de proyectos de nuestro servidor Web. En nuestro caso, sería la carpeta \MAMP\htdocs en la unidad donde lo hayamos instalado. En dicha carpeta crearemos otra llamada \HolaMundo donde guardaremos el fichero antes descrito, asegurándonos de que su extensión es php. Le daremos el nombre index.php. Ya estamos en disposición de probar nuestro primer proyecto PHP. Para ello, nos iremos al navegador web y escribiremos la siguiente dirección web: Y como podemos observar en la imagen anterior, tenemos el resultado de nuestro código. Analicemos un poco el código. Todo código PHP debe ir englobado entre las etiquetas <?php de inicio y la de fin ¿> para que los navegadores lo interpreten correctamente. Entre esas etiquetas irán las instrucciones de PHP propiamente. Y como último apunte, todo el PHP puede ir integrado en páginas web HTML con sus estilos CSS, junto a JavaScript, y así todo tipo de elementos web interactuando unos con otros como explicaremos en la siguiente sección. 2 Algunos entornos nos piden inicialmente el tipo de fichero a crear: elegir PHP o en todo caso, página web HTML Página 11 de 59 Programación Web Fundamentos de PHP El lenguaje PHP es un lenguaje de programación de estilo clásico, es decir, que es un lenguaje de programación con variables, sentencias condicionales, bucles, funciones.... No es un lenguaje de marcas como podría ser HTML, XML o WML. Está más cercano a JavaScript o a C, para aquellos que conocen estos lenguajes. Pero a diferencia de JavaScript que se ejecuta en el navegador, PHP se ejecuta en el servidor, por eso nos permite acceder a los recursos que tenga el servidor como por ejemplo podría ser una base de datos. El programa PHP es ejecutado en el servidor y el resultado enviado al navegador. El resultado es normalmente una página HTML pero igualmente podría ser una página XML. Al ser PHP un lenguaje que se ejecuta en el servidor no es necesario que su navegador lo soporte, es independiente del navegador, pero sin embargo para que sus páginas PHP funcionen, el servidor donde están alojadas debe soportar PHP. El proceso es como sigue: un usuario, desde un dispositivo con navegador web, hace una petición de datos escribiendo en la barra de direcciones una URL. Mediante el protocolo de comunicaciones HTTP o HTTPS se establece la comunicación entre el cliente y el servidor correspondiente. En este se aloja una página web con un programa o script de PHP que se ejecuta, obteniéndose una respuesta, que es devuelta por el mismo protocolo al cliente que lo solicitó en formato HTML o XML. Página 12 de 59 Programación Web Sintaxis Como hemos visto en el ejemplo anterior, el código o script PHP tiene su formato para ser reconocido por los servidores web (Apache). Como habitualmente la respuesta que devuelve el servidor tras el procesamiento del script PHP es HTML, ambos conviven en simbiosis de manera que el código PHP puede aparecer en cualquier parte de una página web; pero también dentro de los scripts de PHP pueden aparecer etiquetas HTML como iremos viendo a lo largo del resto de secciones. El código antes visto sería un fichero PHP puro, que iría en el archivo index.php para ser tratado por el servidor web Apache. La integración HTML+PHP se puede ver claramente en el siguiente ejemplo, en el que tenemos una página web HTML5 con código PHP intercalado: <!DOCTYPE html> <html> <head> <title>Página Web</title> </head> <body> <?php echo "<h1>Hola mundo</h1>"; ?> </body> </html> Este fichero es en su mayoría HTML versión 5. Pero en su sección <body> tiene intercalado código PHP, que su vez, tiene en su interior más código HTML. El código PHP se puede insertar en cualquier parte del HTML. Si queremos que tenga efectos visibles en la propia web de respuesta, debe ir en <head> o en <body>. Pero para cualquier otra funcionalidad puede ir donde sea necesario, como veremos en ejemplos posteriores. Tampoco debemos abusar de mezclar código HTML con PHP. Lo ideal sería tener todo el script PHP en una única parte del HTML, pero esto, muchas veces no es del todo posible. Página 13 de 59 Programación Web Comentarios Los comentarios en PHP son idénticos a los de JAVA. Se usan las dos barras // para comentar lo que viene a continuación hasta el final de la línea y el conjunto /* */ para comentarios en más de una línea. <?php echo "<h1>Hola mundo</h1>"; // Comentario hasta el final de línea /* Este otro comentario ocupa varias líneas */ ?> Variables Una variable es un contenedor de información, en el que podemos meter números enteros, números decimales, caracteres, ... El contenido de las variables se puede leer y se puede cambiar durante la ejecución de una página PHP. En PHP todas las variables comienzan con el símbolo del dólar $ y no es necesario definir una variable antes de usarla. Tampoco tienen tipos, es decir que una misma variable puede contener un número y luego puede contener caracteres. Aunque esto está totalmente desaconsejado por motivos de eficacia y eficiencia. PHP hace diferencias entre Mayúsculas y Minúsculas, de forma que $a y $A son variables diferentes. Página 14 de 59 Programación Web Veamos un sencillo ejemplo3 en el que usamos tres variables para darles en primer lugar un valor y luego mostrar dicho valor por pantalla: <!DOCTYPE html> <html> <head> <title>Página Web</title> </head> <body> <?php $a = 1; $b = 3.34; $c = "Hola Mundo"; echo $a,"<br/>",$b,"<br/>",$c; ?> </body> </html> El resultado sería algo tal que así: Existen 2 tipos de variables, las variables locales que solo pueden ser usadas dentro de bloques delimitados por llaves { } y las variables globales que tienen su ámbito de uso fuera de los bloques. Podemos acceder a una variable global desde un bloque anteponiendo la partícula global al nombre de la variable. Veamos un ejemplo: echo global var1; 3 Este será el último ejemplo en el que se muestra todo el código HTML5. En sucesivos ejemplos solamente se pondrá el script PHP y la parte de HTML necesaria Página 15 de 59 Programación Web Operadores Aritméticos Estos son los operadores aritméticos que se pueden aplicar a las variables y constantes numéricas: Operador + * / % Nombre Suma Resta Multiplicación División Módulo Ejemplo 5+6 7-9 6*3 4/8 7%2 ++ -- Suma 1 Resta 1 $a++ $a-- Trabajemos estos operadores: <?php $a = 8; $b = 3; echo $a + $b,"<br/>"; echo $a - $b,"<br/>"; echo $a * $b,"<br/>"; echo $a / $b,"<br/>"; $a++; echo $a,"<br/>"; $b--; echo $b,"<br/>"; ?> Y obtendremos: Página 16 de 59 Descripción Suma dos números Resta dos números Multiplica dos números Divide dos números Devuelve el resto de dividir ambos números, en este ejemplo el resultado es 1 Suma 1 al contenido de una variable Resta 1 al contenido de una variable Programación Web Operadores de Comparación Los operadores de comparación son usados para comparar valores y así poder tomar decisiones. Operador == != < > <= >= Nombre Igual Distinto Menor que Mayor que Menor o igual Mayor o igual Ejemplo $a = = $b $a != $b $a < $b $a > $b $a <= $b $a >= $b Devuelve cierto cuando: $a es igual $b $a es distinto $b $a es menor que $b $a es mayor que $b $a es menor o igual que $b $a es mayor o igual que $b <?php $a = 8; $b = 3; $c = 3; echo $a == $b,"<br/>"; echo $a != $b,"<br/>"; echo $a < $b,"<br/>"; echo $a > $b,"<br/>"; echo $a >= $c,"<br/>"; echo $b <= $c,"<br/>"; ?> Y el resultado sería: Como se puede observar, los resultados verdaderos se representan con el número 1, los falsos con la nada. Página 17 de 59 Programación Web Operadores Lógicos Los operadores lógicos son usados para evaluar varias comparaciones, combinando los posibles valores de estas. Operador && Nombre Y Ejemplo (7>2) && (2<4) and Y (7>2) and (2<4) || O (7>2) || (2<4) or O (7>2) or (2<4) ! No ! (7>2) <?php $a = 8; $b = 3; $c = 3; echo ($a == $b) && ($c > $b),"<br/>"; echo ($a == $b) || ($b == $c),"<br/>"; echo !($b <= $c),"<br/>"; ?> Obteniéndose: ¡Atentos a la nada! Página 18 de 59 Devuelve cierto cuando: Devuelve verdadero cuando ambas condiciones son verdaderas Devuelve verdadero cuando ambas condiciones son verdaderas Devuelve verdadero cuando al menos una de las dos es verdadera Devuelve verdadero cuando al menos una de las dos es verdadera Niega el valor de la expresión Programación Web Condicionales Las sentencias condicionales nos permiten ejecutar o no, ciertas instrucciones dependiendo del resultado de evaluar una condición. Las más frecuentes son la instrucción if y la instrucción switch. Sentencia if ... else La sentencia condicional más básica. Sirve para discernir entre hacer unas tareas u otras. <?php if (condición) { // Sentencias a ejecutar cuando la condición es cierta. } else { // Sentencias a ejecutar cuando la condición es falsa. } ?> La sentencia if ejecuta una serie de instrucciones u otras dependiendo de la condición que le pongamos. Probablemente sea la instrucción más importante en cualquier lenguaje de programación. <?php $a = 8; $b = 3; if ($a < $b) { echo "a es menor que b"; } else { echo "a no es menor que b"; } ?> En este ejemplo la condición no es verdadera por lo que se ejecuta la parte de código correspondiente al else. Página 19 de 59 Programación Web Sentencia switch ... case La otra estructura básica de comparación en muchos lenguajes de programación. <?php $posicion = "arriba"; switch($posicion) { case "arriba": // Bloque 1 echo "La variable contiene"; echo " el valor arriba"; break; case "abajo": // Bloque 2 echo "La variable contiene"; echo " el valor abajo"; break; default: // Bloque 3 echo "La variable contiene otro valor"; echo " distinto de arriba y abajo"; } ?> Con la sentencia switch podemos ejecutar unas u otras instrucciones dependiendo del valor de una variable. En el ejemplo anterior, dependiendo del valor de la variable $posicion se ejecuta el bloque 1 cuando el valor es "arriba", el bloque 2 cuando el valor es "abajo" y el bloque 3 si no es ninguno de los valores anteriores. Solamente se puede usar con comparación. Bucles Los bucles nos permiten iterar conjuntos de instrucciones, es decir repetir la ejecución de un conjunto de instrucciones mientras se cumpla una condición. Sentencia while SE usa cuando desconocemos el total de vueltas o iteraciones tenemos que dar. Puede ser entre ninguna iteración e infinitas. <?php while (condición) { // Instrucciones a ejecutar } ?> Página 20 de 59 Programación Web Mientras la condición sea cierta se repetirá la ejecución de las instrucciones que están dentro del while. <?php $i=0; while ($i<10) { echo "El valor de i es ", $i,"<br/>"; $i++; } ?> En este ejemplo, el valor de $i al comienzo es 0, durante la ejecución del bucle, se va sumando 1 al valor de $i de manera que cuando $i vale 10 ya no se cumple la condición y se termina la ejecución del bucle. Sentencia for Usada para repetir un conjunto de instrucciones una cantidad de veces conocida. <?php for (valor inicial ; condición ; ejecutar en iteración) { // Instrucciones a ejecutar. } ?> Página 21 de 59 Programación Web Veamos el mismo ejemplo anterior: <?php for($i=0 ; $i<10 ; $i++) { echo "El valor de i es ", $i,"<br/>"; } ?> La instrucción for es la instrucción de bucles más completa. En una sola instrucción nos permite controlar todo el funcionamiento del bucle. El primer parámetro del for, es ejecutado la primera vez y sirve para inicializar la variable del bucle; el segundo parámetro indica la condición que se debe cumplir para que el bucle siga ejecutándose y el tercer parámetro es una instrucción que se ejecuta al final de cada iteración y sirve para modificar el valor de la variable de iteración. Instrucciones de Salida Hasta ahora hemos usado la instrucción echo para realizar la respuesta de la petición, que normalmente será una salida a pantalla. Esta instrucción es bastante limitada ya que no nos permite formatear la salida. Ahora veremos la instrucción printf que nos da mucha más potencia: <?php printf(cadena formato, variable1[, variable2, ...]); ?> La cadena de formato indica cómo se han de representar los valores que posteriormente le indicaremos. La principal ventaja es que además de poder formatear los valores de salida, nos permite intercalar texto entre ellos. Ejemplo: <?php printf("El numero dos con diferentes formatos: %d %f %.2f",2,2,2); ?> Página 22 de 59 Programación Web La cadena de formato puede incluir una serie de caracteres especiales que indican cómo formatear las variables que se incluyen en la instrucción. Elemento Tipo de variable %s Cadena de caracteres %d Número sin decimales %f Número con decimales %c Carácter ASCII Aunque existen otros tipos, estos son los más importantes. Otro ejemplo: <?php $var="texto"; $num=3; printf("Puede fácilmente intercalar <b>%s</b> con números <b>%d</b> <br/>",$var,$num); printf("<table border=1 cellpadding=20>"); for ($i=0;$i<10;$i++) { printf("<tr><td>%10.d</td></tr>",$i); } printf("</table>"); ?> Página 23 de 59 Programación Web Obteniendo la siguiente respuesta: Cadenas En el lenguaje PHP el tratamiento de cadenas es muy importante, y, por tanto, existen bastantes funciones para el manejo de cadenas. A continuación, explicaremos las más usadas: • Podemos conseguir la concatenación de cadenas bien usando el operador punto (.) bien usando el operador coma (,). • strlen(cadena): Nos devuelve el número de caracteres de una cadena • explode(separador,cadena): Divide una cadena en varias usando un carácter separador • sprintf(cadena de formato, var1, var2...): Formatea una cadena de texto al igual que printf pero el resultado es devuelto como una cadena • substr(cadena, inicio, longitud): Devuelve una subcadena de otra, empezando por inicio y de longitud longitud Página 24 de 59 Programación Web • chop(cadena): Elimina los saltos de línea y los espacios finales de una cadena • strpos(cadena1, cadena2): Busca la cadena2 dentro de cadena1 indicándonos la posición en la que se encuentra • str_replace(cadena1, cadena2, texto): Reemplaza la cadena1 por la cadena2 en el texto. • strtoupper(cadena): Devuelve la cadena introducida con todos sus caracteres en mayúsculas. • strtolower(cadena): Devuelve la cadena introducida con todos sus caracteres en minúsculas. Veamos con ejemplos concretos: <?php echo strlen("12345"),"<br/>"; $palabras=split(" ","Esto es una prueba"); for($i=0;$palabras[$i];$i++) { echo $palabras[$i],"<br/>"; } $resultado=sprintf("8x5 = %d",8*5); echo $resultado,"<br/>"; echo substr("Devuelve una subcadena de otra",9,3),"<br/>"; if (chop("Cadena \n\n ") == "Cadena") { echo "Iguales<br/>"; } echo strpos("Busca la palabra dentro de la frase", "palabra"),"<br/>"; echo str_replace("verde","rojo","Un pez de color verde."),"<br/>"; ?> En pantalla: Página 25 de 59 Programación Web Funciones y Procedimientos El uso de funciones y procedimientos nos da la capacidad de agrupar varias instrucciones bajo un solo nombre y poder llamarlas a estas varias veces desde diferentes sitios, ahorrándonos la necesidad de escribirlas de nuevo. <?php function Nombre(parametro1, parametro2...) { instrucción1; instrucción2; instrucción3; instrucción4; return valor_de_retorno; } ?> Opcionalmente podemos pasarle parámetros a las funciones que se trataran como variables locales y así mismo podemos devolver un resultado con la instrucción return valor; Esto produce la terminación de la función retornando un valor. Si la función no devuelve nada (null) se suele denominar procedimiento, en vez de función, pero su definición sigue siendo la misma con la palabra reservada function. <?php function media_aritmetica($a, $b) { return ($a+$b)/2; } echo media_aritmetica(4,6),"<br/>"; echo media_aritmetica(3242,524543),"<br/>"; ?> Librerías El uso de librerías es tremendamente útil porque nos permiten agrupar varias funciones y variables en un mismo fichero, de manera que luego podemos incluir esta librería en distintas páginas y disponer de esas funciones fácilmente. Las librerías pueden ser de producción propia o importadas de otras personas. En el siguiente ejemplo, crearemos una librería propia que guardaremos en un fichero llamado formato.php. en dicho fichero se definirán dos funciones: una para la cabecera de todas nuestras páginas webs y otra función para los pies de página. Página 26 de 59 Programación Web <?php function CabeceraPagina() { echo “<font size=’+1’>Esta cabecera estará en todas sus páginas.</font>”; echo “<br/>”; echo “<hr/>”; } function PiePagina() { echo “<hr/>”; echo “<font size=’-1’>Este es el pie de página.</font><br/>”; echo “Autor: Jorge Rodríguez”; } ?> Ahora vamos a crear 2 páginas que usen la librería definida anteriormente para conseguir que las dos páginas tengan la misma cabecera y el mismo pie de página. La instrucción para incluir una librería en nuestra página es: include("nombre de librería"); Fichero uno.php: <!DOCTYPE html> <html> <head> <title>Página Uno</title> </head> <body> <?php include("formato.php"); ?> <?php CabeceraPagina(); ?> Página 1 <br/><br/><br/><br/><br/> Contenido bla bla bla<br/><br/> Más cosas...<br/><br/> Fin<br/><br/> <?php PiePagina(); ?> </body> </html> Página 27 de 59 Programación Web Fichero dos.php: <!DOCTYPE html> <html> <head> <title>Página Dos</title> </head> <body> <?php include("formato.php"); ?> <?php CabeceraPagina(); ?> Esta es otra página <br/><br/><br/><br/><br/> Completamente distinta <br/><br/> Pero comparte el pie y la cabecera con la otra...<br/><br/> <?php PiePagina(); ?> </body> </html> El resultado es el siguiente: Página 28 de 59 Programación Web Programación Orientada a Objetos Como cualquier lenguaje de programación moderno, PHP se puede programar siguiendo el paradigma de programación Orientado a Objetos. Aunque esto no ha sido siempre así. En las primeras versiones no lo soportaba. Lo mejor de todo es que cuando se implementó, se respetó absolutamente todo el código anterior, con lo cual pueden convivir sin problemas partes orientadas a objetos con otras partes tradicionales. A partir de PHP 5, el modelo de objetos ha sido reescrito para tener en cuenta un mejor rendimiento y mayor funcionalidad. Este fue un cambio importante a partir de PHP 4. PHP 5 tiene un modelo de objetos completo. class La definición básica de una clase comienza con la palabra reservada class, seguida de un nombre de clase, y continuando con un par de llaves que encierran las definiciones de las propiedades y métodos pertenecientes a dicha clase. El nombre de clase puede ser cualquier etiqueta válida, siempre que no sea una palabra reservada de PHP. Un nombre válido de clase comienza con una letra o un guión bajo, seguido de una cantidad arbitraria de letras, números o guiones bajos. Una clase puede tener sus propias constantes, variables (llamadas "propiedades"), y funciones (llamados "métodos"). <?php class Persona { // Declaración de un atributo o propiedad public $nombrePersona; public $apellidosPersona; public $fechaNacimientoPersona; // Constructor public function Persona() { $this->$nombrePersona = “”; $this->$apellidosPersona = “”; $this->$fechaNacimientoPersona = “”; } Página 29 de 59 Programación Web // Inspectores public function setNombre($nombre) { $this->$nombrePersona = $nombre; } public function getNombre() { return ($this->$nombrePersona); } } ?> La pseudovariable $this está disponible cuando un método es invocado dentro del contexto de un objeto. $this es una referencia al objeto invocador, como veremos en el siguiente ejemplo que hace uso de la clase Persona. El operador objeto ->es usado para acceder a atributos y métodos de un objeto de una clase. new Para crear una instancia de una clase, se debe emplear la palabra reservada new. Un objeto se creará siempre a menos que el objeto tenga un constructor que arroje una excepción en caso de error. Las clases deberían ser definidas antes de la instanciación (y en algunos casos esto es un requerimiento). Supongamos que la clase Personas se ha guardado en un fichero llamado persona.php. Entonces, para trabajar con objetos de dicha clase, podríamos tener este otro código en otro fichero: <?php include(“persona.php”); $persona1 = new Persona(); $persona1->setNombre(“Ana”); echo $persona->getNombre(); ?> extends Una clase puede heredar los métodos y propiedades de otra clase empleando la palabra reservada extends en la declaración de la clase. No es posible la extensión de múltiples clases; una clase sólo puede heredar de una clase base. Página 30 de 59 Programación Web <?php include(“persona.php”); class Empleado extends Persona { // Declaración de un atributo o propiedad public $salarioEmpleado; // Constructor public function Empleado() { $this->$salarioEmpleado = 0; } // Inspectores public function setSalario($salario) { $this->$salarioEmpleado = $salario; } public function getSalario() { return ($this->$salarioEmpleado); } } ?> Para probarlo Podemos usar el siguiente script de PHP: <?php include(“empleado.php”); $empleado1 = new Empleado(); $empleado1 ->setNombre(“Ana”); echo $empleado1->getNombre(); $empleado1 ->setSalario(1200); echo “ tiene un salario de “.($empleado1->getSalario()); ?> Página 31 de 59 Programación Web Ficheros Para trabajar con ficheros tenemos mucha funcionalidad prácticamente desde las primeras versiones. Evidentemente estamos hablando de ficheros alojados en el mismo servidor donde se encuentra el script y nunca en el ordenador del cliente. Comenzamos creando un fichero de texto plano: <?php $file = fopen("archivo.txt", "w"); fwrite($file, "Esto es una nueva línea de texto" . PHP_EOL); fwrite($file, "Otra más" . PHP_EOL); fclose($file); ?> Unas cuestiones: 1. PHP_EOL (end of line) introduce un salto de línea en PHP. Mediante la concatenación con un punto forzamos el salto de línea después del texto introducido. 2. Tener en cuenta que el modo de apertura de archivo que hemos usado es w: Abre el archivo sólo para escritura. La escritura comienza al inicio del archivo, y elimina el contenido previo del archivo. Si el archivo no existe, intenta crearlo. 3. Para evitar corrupción de la información del fichero, se recomienda siempre, siempre, cerrar el fichero con fclose(). Página 32 de 59 Programación Web ¿Y si queremos respetar el contenido que haya previamente a la inserción de nuestros datos nuevos? Pues debemos abrir el fichero en modo añadir con el parámetro a: <?php $file = fopen("archivo.txt", "a"); fwrite($file, "Añadimos otra línea" . PHP_EOL); fwrite($file, "Añadimos otra más" . PHP_EOL); fclose($file); ?> Pasemos ahora a leer el contenido de dichos ficheros creados con anterioridad: <?php $file = fopen("archivo.txt", "r"); while(!feof($file)) { echo fgets($file). "<br />"; } fclose($file); ?> Si nos fijamos, el contenido se lee línea a línea gracias al bucle while(). Página 33 de 59 Programación Web Sistema Operativo En este apartado vamos a estudiar algunas funciones importantes en PHP que interactúan con el propio sistema operativo para consultar diferentes valores. Comenzaremos obteniendo la fecha y la hora del sistema. Se usa la función Date() que tiene multitud de constructores, parámetros de configuración y un sinfín de funciones asociadas4. El siguiente programa obtiene la fecha y hora del sistema y lo muestra: <?php $hoy = Date("d/m/Y H:i:s"); echo $hoy,"<br/>"; ?> Pero si nos fijamos bien, la hora que nos muestra estará desfasada con respecto a la nuestra. ¿Qué ha ocurrido? Que primero debemos indicar la Zona Horaria en la que estamos. La función Date no coge exactamente la hora de nuestro sistema, sino que coge la hora UTC. Esta hora está desfasada dos horas con respecto a la española. El programa quedaría mejor de la siguiente manera: <?php date_default_timezone_set("Europe/Madrid"); $hoy = Date("d/m/Y H:i:s"); echo $hoy,"<br/>"; ?> El formato de Date lo tenemos que formar con una serie de letras y signos que definirán el resultado final. En nuestro caso hemos indicado día (d), mes (m), año con cuatro cifras (Y), la hora en formato 24 (H), minutos (i) y segundos (s). existen más posibilidades. Las barras / y los dos puntos : se pueden sustituir por guiones, o lo que queramos. 4 http://php.net/manual/es/function.date.php Página 34 de 59 Programación Web Otra funcionalidad muy interesante con las fechas y las horas es obtener la diferencia entre dos fechas dadas. El resultado se podrá expresar luego en segundos, minutos, días, lo que sea necesario: <?php $datetime1 = new DateTime('2018-10-11'); $datetime2 = new DateTime('2018-10-13'); $intervalo = $datetime1->diff($datetime2); echo $intervalo->format('%R%a días'); ?> Aquí se usa otra función DateTime()5 que obtiene otra representación de las fechas y las horas, más manejable para estos menesteres de cálculos entre diferentes fechas, por ejemplo, teniendo en cuenta los años bisiestos. La función format()6 da formato a los datos que se le envían. Se puede aplicar sobre muchos tipos de datos. En este ejemplo se formatea un objeto de la clase Interval, que es la que se obtiene con la función diff(). Por último, veremos unos cuantos de ejemplos para interactuar con el sistema de archivos del sistema operativo. Obviamente todo este trabajo se hace en el disco duro del servidor, nunca del cliente. Crear un directorio en el directorio actual con todos los permisos: <?php echo "Creando Carpeta con todos los permisos…"; mkdir("./Carpeta", 0777); ?> Crear varios directorios de forma recursiva: <?php // Estructura de la carpeta deseada $estructura = './nivel1/nivel2/nivel3/'; // Para crear una estructura anidada se debe especificar // el parámetro $recursive en mkdir(). if(!mkdir($estructura, 0777, true)) { die('Fallo al crear las carpetas...'); } ?> 5 6 http://php.net/manual/es/class.datetime.php http://php.net/manual/es/dateinterval.format.php Página 35 de 59 Programación Web Eliminar un directorio: <?php if (is_dir('./Carpeta')) { echo "Borrando directorio Carpeta..."; rmdir('./Carpeta'); } ?> Copiar el fichero “ejemplo.txt” de la ubicación actual a otra llamada “Copia”, cambiando el nombre del fichero copia a la vez: <?php $fichero = './ejemplo.txt'; $nuevo_fichero = './Copia/ejemplo.txt.bak'; if (!copy($fichero, $nuevo_fichero)) { echo "Error al copiar $fichero...\n"; } ?> Borrar un fichero: <?php $fichero = './ejemplo.txt'; if (!unlink($fichero)) { echo "Error al borrar $fichero...\n"; } ?> Página 36 de 59 Programación Web Envío y Recepción de Información (Formularios) La mejor manera de desarrollar aplicaciones de cara al cliente es interactuando con ellos a través de los diferentes controles de los Formularios. A través de ellos los usuarios seleccionan opciones, introducen datos, eligen parámetros o propiedades, se envían a uno o varios scripts de PHP, se tratan los datos y se devuelve una respuesta en formato HTML o XML. Suponemos que el lector ya conoce cómo crear formularios en HTML y darle estilo con CSS. En HTML5 se introdujeron una gran cantidad de controles para usar en los formularios, sobre todo en el caso de los <input>. Para abarcar al completo la interacción de estos controles con el usuario, los agruparemos en los ejemplos para no repetir idénticos comportamientos. Por ejemplo, visto el control “text”, ya tendremos el comportamiento para muchos otros similares como “password”. Los datos se recogen en un fichero HTML con extensión .html o .php. Dichos datos se envían a otro fichero que contiene el script de PHP. Allí son recogidos y procesados, obteniéndose una respuesta que es devuelta al mismo fichero que inició la comunicación o a otro. Comenzaremos con el ejemplo más sencillo posible: un formulario que recoge una cadena, se envía a un fichero PHP que pone todo en mayúsculas y devuelve el resultado en otra página web. En total vamos a trabajar con dos ficheros: el del formulario y el programa de PHP. Página 37 de 59 Programación Web Comenzamos con formulario.php7: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="GET"> <p>Escribir una cadena:</p> <p><input type="text" name="cadena"/></p> <p><input type="submit" value="Aceptar"/></p> </form> </body> </html> Obteniendo la siguiente pantalla: El atributo action de la etiqueta <form> indica a dónde “saltar” al pulsar el control “submit”. El atributo method indica cómo se enviará la información. El valor GET es el que se da por defecto si no se pone y envía la información directamente en la propia línea de dirección tras el nombre del fichero como veremos ahora. El valor POST envía los datos en la propia petición, como también veremos en otro ejemplo. Ahora escribiremos el fichero “procesa.php” con el siguiente código: <?php $valor = $_GET['cadena']; echo strtoupper($valor); ?> Aquí se “captura” el valor introducido en el formulario gracias a $_GET[‘cadena’]. Dentro de las comitas simples tenemos el nombre que se le dio al control en el atributo name. 7 En este caso también podría ser formulario.html pues no contiene nada de PHP Página 38 de 59 Programación Web Ejecutando todo esto junto… Obtenemos… Si nos fijamos en la url, el dato ha sido enviado en la propia línea: localhost/procesa.php?cadena=Hola La forma de enviar así la información consiste en poner el nombre del fichero (procesa.php), seguido de un signo de interrogación para indicar inicio de datos (?). Y a continuación pasaremos parejas de parámetros con sus valores asignados con un signo igual (cadena=Hola). Si necesitamos enviar más valores, se separan con un ampersand (&). Para ilustrar este caso haremos ahora otro ejemplo en el que nos piden dos números y al pulsar el botón, obtendremos su suma. <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="GET"> <p>Escribir dos números:</p> <p><input type="number" name="numero1"/></p> <p><input type="number" name="numero2"/></p> <p><input type="submit" value="Sumar"/></p> </form> </body> </html> Página 39 de 59 Programación Web Y ahora el script PHP sería de la forma: <?php $numero1 = $_GET['numero1']; $numero2 = $_GET['numero2']; echo "La suma vale:".($numero1+$numero2); ?> Al ejecutarlo, obtendríamos: Fijarse ahora en la url: http://localhost/procesa.php?numero1=5&numero2=8 Si trabajamos con method=”POST” no veremos los datos en la línea de dirección, pero igualmente se enviarán. Es más seguro. De usar este método, ahora en el script PHP cogeremos los datos con $_POST[‘’]. Veamos el último ejemplo con esta forma de trabajar: El formulario: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="POST"> <p>Escribir dos números:</p> <p><input type="number" name="numero1"/></p> <p><input type="number" name="numero2"/></p> <p><input type="submit" value="Sumar"/></p> </form> </body> </html> El script PHP: <?php $numero1 = $_POST['numero1']; $numero2 = $_POST ['numero2']; echo "La suma vale:".($numero1+$numero2); ?> Página 40 de 59 Programación Web El resultado es igual, pero fijarse en la url: http://localhost/procesa.php Los siguientes controles8 tienen el mismo comportamiento que “text”: • password: Cuidado con este control. Si usamos el método GET, lo que pongamos aquí en el control se ocultará en la página web con puntos o asteriscos (*************), pero en la url aparecerá tal cual. • color: Con la particularidad que la información que se envía es el código RGB del color elegido en la forma: #00ff00 • date • datetime-local • email • month • number • range • search • tel • textarea • time • url • week Otros controles como select, radio, checkbox y file tienen un comportamiento ligeramente diferente. Veamos cada uno de ellos con un ejemplo. 8 No todos los navegadores soportan YA estas nuevas características de HTML5 Página 41 de 59 Programación Web Comencemos con el select, que envía el valor del atributo value asociado al elemento que elige el usuario (uno solamente). Primero vemos el formulario: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="POST"> <p>Elige tu marca favorita:</p> <p> <select name="coches"> <option value="volvo">Volvo</option> <option value="saab">Saab</option> <option value="fiat">Fiat</option> <option value="audi">Audi</option> </select> </p> <p><input type="submit" value="Procesar"/></p> </form> </body> </html> Ahora el script de PHP: <?php $coches = $_POST['coches']; echo "Has seleccionado:".($coches); ?> Con el control radio pasa algo similar. Se envía la información indicada por el atributo value del elemento elegido por el usuario. Página 42 de 59 Programación Web Formulario: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="POST"> <p>Elige tu marca favorita:</p> <p><input type="radio" name="genero" value="hombre" checked> Hombre</p> <p><input type="radio" name="genero" value="mujer"> Mujer</p> <p><input type="radio" name="genero" value="otro"> Otro</p> <p><input type="submit" value="Procesar"/></p> </form> </body> </html> PHP: <?php $genero = $_POST['genero']; echo "Has seleccionado:".($genero); ?> El tratamiento del siguiente control, el checkbox tiene una dificultada añadida: se pueden elegir más de un elemento. Ahora el procesamiento no es sobre un único valor. Es por ello por lo que en PHP asimilaremos todos los elementos marcados a un array o tabla. Los valores de este objeto serán los que trataremos. Página 43 de 59 Programación Web Formulario: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="POST"> <p>Elige tu marca favorita:</p> <p><input type="checkbox" name="aficion[]" value="Correr"> Correr</p> <p><input type="checkbox" name="aficion[]" value="Leer"> Leer</p> <p><input type="checkbox" name="aficion[]" value="Series"> Series</p> <p><input type="submit" value="Procesar"/></p> </form> </body> </html> Hay que fijarse que el nombre del control ya lleva implícito el uso posterior de un array indicado por los corchetes []. PHP: <?php $aficiones = $_POST['aficion']; foreach($aficiones as $aficion) { echo "Has seleccionado: ".($aficion)."<br/>"; } ?> El uso de foreach permite procesar todo el array, con independencia de la cantidad de controles que se hayan enviado marcados. Finalizamos este apartado con el control file. El que envía más información al script de procesamiento, como veremos en el ejemplo: Página 44 de 59 Programación Web Formulario: <!DOCTYPE html> <html> <head> <title>Formularios</title> </head> <body> <form action="procesa.php" method="POST" enctype="multipart/form-data"> <p>Selecciona un fichero:<input type="file" name="fichero"/></p> <p><input type="submit" value="Procesar"/></p> </form> </body> </html> PHP: <?php // Capturamos el nombre del archivo $nombre_archivo_original = $_FILES['fichero']['name']; // Capturamos el tipo del archivo $tipo_archivo = $_FILES['fichero']['type']; // Capturamos el tamaño del fichero $tamano_archivo = $_FILES['fichero']['size']; // Montamos la ruta del fichero donde se subirá // La carpeta debe existir previamente a la subida, // o si no, se producirá error $nombre_archivo="./documentos/".$nombre_archivo_original; if (move_uploaded_file($_FILES['fichero']['tmp_name'], $nombre_archivo)) { // Correcto echo "Archivo subido correctamente!<br/>"; echo "Su nombre es: ".$nombre_archivo_original."<br/>"; echo "Su extensión es: ".$tipo_archivo."<br/>"; echo "Su tamaño es: ".$tamano_archivo."<br/>"; echo "Su ubicación destino es: ".$nombre_archivo."<br/>"; } else { // Error echo "Se ha producido un error al subir el archivo!"; } ?> Página 45 de 59 Programación Web NOTA: Para que todo funcione correctamente, la subida de ficheros en PHP tiene unas limitaciones indicadas en el fichero de configuración php.ini que son las siguientes: • El parámetro file_uploads debe valer On • El parámetro upload_max_filesize indica el tamaño máximo soportado por el sistema, aunque en nuestro código PHP podemos cambiar el valor temporalmente. 2M indicarán 2 Megabytes. • El parámetro max_file_uploads indica el número máximo de ficheros que se pueden subir de una vez. Analizando el código, podemos indicar que nos hace falta en el formulario un nuevo atributo llamado enctype que indica el tipo de datos binarios que serán enviados adjuntos a los datos que ya hemos trabajado en anteriores ejemplos. Por otro lado, independientemente de que el atributo method del formulario sea POST o GET, en el script PHP se procesa la información de los ficheros a través de otra variable global llamada $_FILE, que contiene todos esos datos vistos en el ejemplo: nombre del fichero, tipo, tamaño, etc. Por último, indicar que la subida se hace en dos pasos con el método move_uploaded_file, moviendo primero el fichero a una ubicación temporal y luego a la ubicación definitiva si esta ha tenido éxito. Página 46 de 59 Programación Web Conexión a Bases de Datos PHP y MySQL son primos hermanos. Con esto queremos indicar que la forma de conectar los scripts de PHP para tener acceso a los datos de MySQL es una forma muy fácil y con múltiples variantes. No obstante, también veremos los fundamentos para conectar PHP con MongoDB. Comencemos con la base de datos con la que vamos a trabajar. Partiremos de una base de datos llamada “phpbasico” a la que accederemos con un “usuario” llamado remoto con clave “Studium2018;”. En dicha base de datos podremos encontrar dos tablas: socios y accesos. La primera tendrá los datos de los socios de cierto club on-line. En la segunda se guardará todo el historial de entradas y salidas de dichos socios al sistema. Una vez tenemos esto montado, vamos a proceder a detallar una estrategia para trabajar con MySQL desde PHP que puede ser tan válida como cualquier otra, pero que, por lo menos, funciona. Comenzaremos con un fichero llamado conexion.php donde guardaremos toda la información relativa a la conexión con la base de datos. Este fichero se incorporará en cada fichero que necesite acceso a la base de datos. Lo cómodo de este método es que, si hay algún cambio de servidor, usuario, clave, etc. solamente con cambiar dichos valores en este único fichero, el resto de ficheros no hay que tocarlos. Página 47 de 59 Programación Web <?php // Datos de conexión $user = 'usuario'; $password = 'Studium2018;'; $db = 'phpbasico'; $host = 'localhost'; $port = 3307; // Datos generales date_default_timezone_set('Europe/Madrid'); ?> También se suele usar para incorporar información común a todos los ficheros o scripts de PHP. En este caso, definimos la zona horaria porque al trabajar con fechas y horas, necesitamos que aparezcan los datos según nuestra zona horaria. En este ejemplo no vamos a ver la parte “visible” o Front-End, es decir, páginas web que interactúan con los usuarios. Nos centraremos en la parte funcional de PHP atendiendo al CRUD9. Para probar, simplemente tendremos otro fichero (crud.php) con las funciones correspondientes para la inserción, borrado, consulta y modificación. Comenzaremos por la tabla socios. Y se deja como práctica la realización de la tabla accesos. 9 Create, Read, Updated y Delete Página 48 de 59 Programación Web Comenzamos por el ALTA: function altaSocio($nombreSocio, $apellidosSocio, $correoElectronicoSocio) { include("conexion.php"); // Variable devuelta como resultado del INSERT $resultado = false; // Conectar $link = mysqli_init(); $exitoConexion = mysqli_real_connect($link, $host, $user, $password, $db, $port); if($exitoConexion) { // Montamos la sentencia SQL para el INSERT $sql = "INSERT INTO socios VALUES(null,'$nombreSocio','$apellidosSocio','$correoElectronicoSocio')"; // Ejecutamos la sentencia if($link->query($sql)===TRUE) { $resultado = true; } } else { echo mysqli_connect_error(); } $link->close(); return ($resultado); } Comentamos varios detalles: • La función altaSocio() recibe los datos necesarios para el alta de un registro en la tabla socios, a saber, el nombre, los apellidos y el correo electrónico del socio. • Incluimos el fichero conexión.php para tener acceso a las variables necesarias para la conexión a la base de datos, como son, usuario con el que acceder, su clave, la base de datos a la que conectar, la dirección donde se encuentra dicha base de datos y por qué puerto se realizará la conexión. • Creamos la conexión $link con la función mysqli_init(). • Realizamos la conexión con mysqli_real_connect(). Página 49 de 59 Programación Web • Si tenemos éxito en la conexión, ejecutamos la instrucción SQL contenida en la variable $sql con el método query() del objeto $link. Todo esto se expresa del modo $link->query($sql). • Si todo ha ido bien, cerramos la conexión con el método close() del objeto $link, o lo que es lo mismo, $link->close(). • Finalmente devolvemos el valor (true o false) de la variable $resultado para que, allá donde se haya usado este método de altaSocio sepa si la operación ha sido exitosa o, todo lo contrario. Procedamos ahora a la BAJA de un socio: function bajaSocio($idSocio) { include("conexion.php"); // Variable devuelta como resultado del DELETE $resultado = false; // Conectar $link = mysqli_init(); $exitoConexion = mysqli_real_connect($link, $host, $user, $password, $db, $port); if($exitoConexion) { // Montamos la sentencia SQL para el DELETE $sql = "DELETE FROM socios WHERE idSocio = $idSocio"; // Ejecutamos la sentencia if($link->query($sql)===TRUE) { $resultado = true; } } else { echo mysqli_connect_error(); } $link->close(); return ($resultado); } Destacar que: • En este caso, la función bajaSocio() solamente recibe el identificador del socio al que queremos eliminar. • Muy importante no olvidar el WHERE en la sentencia SQL. • El resto es similar al ALTA. Página 50 de 59 Programación Web Para la ACTUALIZACIÓN, tenemos algo muy parecido al alta: function modificaSocio($idSocio, $nombreSocio, $apellidosSocio, $correoElectronicoSocio) { include("conexion.php"); // Variable devuelta como resultado del UPDATE $resultado = false; // Conectar $link = mysqli_init(); $exitoConexion = mysqli_real_connect($link, $host, $user, $password, $db, $port); if($exitoConexion) { // Montamos la sentencia SQL para el UPDATE $sql = "UPDATE socios SET nombreSocio = '$nombreSocio', apellidosSocio = '$apellidosSocio', correoElectronicoSocio = '$correoElectronicoSocio' WHERE idSocio = $idSocio"; // Ejecutamos la sentencia if($link->query($sql)===TRUE) { $resultado = true; } } else { echo mysqli_connect_error(); } $link->close(); return ($resultado); } Comentar que: • Ahora, junto a los datos como el ALTA, necesitamos el identificador idSocio, como en la BAJA para saber a qué socio estamos haciendo referencia para realizarle los cambios. • No olvidar el WHERE en el SQL. • El resto, casi idéntico. Página 51 de 59 Programación Web Por último, vamos con la CONSULTA. En este caso, la función consultaSocios() no devolverá un booleano, sino que con ella obtendremos lo que estamos buscando, o bien, nada si no lo encuentra. Lo más genérico es que busque todo en una tabla. Lo más particular es que busque lo que le pasemos a la función como condición. Veamos en primer lugar el código del primer caso y luego lo analizamos: function consultaSocios() { include("conexion.php"); // Variable devuelta como resultado del SELECT $resultado = null; // Conectar $link = mysqli_init(); $exitoConexion = mysqli_real_connect($link, $host, $user, $password, $db, $port); if($exitoConexion) { // Montamos la sentencia SQL para el SELECT $sql = "SELECT * FROM socios"; // Ejecutamos la sentencia y guardamos lo obtenido en $resultado $resultado = $link->query($sql); } else { echo mysqli_connect_error(); } $link->close(); return ($resultado); } Lo analizamos: • En primer lugar destacar que la función consultaSocios() no lleva ningún parámetro, pues vamos a obtener TODO lo que haya en la tabla socios, sin restricciones. • En segundo lugar, al ejecutar la sentencia con $link->query($sql) obtenemos información de la base de datos y la guardamos en la variable $resultado, que será lo que devuelva la función. • Más adelante, cuando veamos el ejemplo que usa todos esto, profundizaremos en cómo tratar la información contenida en $resultado y devuelta a la llamada de la función consultaSocios(). Página 52 de 59 Programación Web Ahora veremos otra función, que recibe una condición o una restricción, con lo cual, la consulta puede darnos una cantidad diferente al total de los registros contenidos en la tabla a la que estamos sacando información. function consultaSociosCondicion($condicion) { include("conexion.php"); // Variable devuelta como resultado del SELECT $resultado = null; // Conectar $link = mysqli_init(); $exitoConexion = mysqli_real_connect($link, $host, $user, $password, $db, $port); if($exitoConexion) { // Montamos la sentencia SQL para el SELECT $sql = "SELECT * FROM socios WHERE $condicion"; // Ejecutamos la sentencia y guardamos lo obtenido en $resultado $resultado = $link->query($sql); } else { echo mysqli_connect_error(); } $link->close(); return ($resultado); } A destacar: • Se ha enviado una condición al método. Hay que tener en cuenta que dicha variable debe contener una cadena que represente una condición válida de SQL. Si no se hace así, se devolverá error, como veremos más adelante cuando probemos esta función. • El resto es igual que en consultaSocios() salvo que ahora se ha modificado la cadena $sql para incluir la condición después de la cláusula WHERE. • Podríamos pensar en multitud de posibilidades: o Solamente un método de consulta enviando como condición un 1, por ejemplo, y ya tendríamos el mismo comportamiento consultaSocios(). Página 53 de 59 en consultaSociosCondicion() y en Programación Web o La posibilidad de incluir un segundo parámetro que indique la tabla sobre la que se va a hacer la consulta, y así nos evitamos tener una función de consulta por cada tabla. Esto conlleva el plantearse la cantidad variable de campos que se obtienen según la tabla que se consulta. Pero hay formas de averiguarlo, con lo cual no es un problema, es una dificultada añadida pero fácilmente solventable. NOTA IMPORTANTE: Para evitar problemas con las tildes debemos tomar las siguientes precauciones: • Tanto la base de datos como las tablas deben estar codificadas en utf8 y colación utf8_spanish2_ci. • Los ficheros php deben estar codificados en utf8 sin BOM 10. Ahora, si lo ponemos todo junto quedaría algo tal que así: <?php function altaSocio($nombreSocio, $correoElectronicoSocio) { … } function bajaSocio($idSocio) { … } function modificaSocio($idSocio, $nombreSocio, $correoElectronicoSocio) { … } function consultaSocios() { … } function consultaSociosCondicion($condicion) { … } ?> 10 BOM: Bit Of Mask Página 54 de 59 $apellidosSocio, $apellidosSocio, Programación Web Para poder probar todo esto, vamos a usar otro fichero en el que una tras otra, será probadas las funciones antes descritas. <?php include("crud.php"); // Dar de alta al socio Fulanito con los datos correspondientes $resultado = altaSocio("Fulanito", "Rodríguez", "[email protected]"); if($resultado) { echo "Alta correcta!"; echo "<br/>"; } else { echo "Error en Alta..."; echo "<br/>"; } // Eliminar al socio con identificador igual a 4 $resultado = bajaSocio(4); if($resultado) { echo "Baja correcta!"; echo "<br/>"; } else { echo "Error en Baja..."; echo "<br/>"; } // Modificar los datos del socio identificado con el 3 $resultado = modificaSocio(3, "Belén", "Rodríguez", "[email protected]"); if($resultado) { echo "Modificación correcta!"; echo "<br/>"; } else { echo "Error en Modificación..."; echo "<br/>"; } Página 55 de 59 Programación Web // Obtener y mostrar todos los socios de la base de datos $valores = consultaSocios(); echo "<table>"; while ($filas = $valores->fetch_array()) { echo "<tr>"; // Mostrar idSocio echo "<td>".$filas[0]."</td>"; // Mostrar nombreSocio echo "<td>".$filas[1]."</td>"; // Mostrar apellidosSocio echo "<td>".$filas[2]."</td>"; // Mostrar correoElectronicoSocio echo "<td>".$filas[3]."</td>"; echo "</tr>"; } echo "</table>"; // Obtener los datos de los socios que cumplen la condición indicada // En este caso, que su identificador sea superior a 3 $valores = consultaSociosCondicion("idSocio>3"); echo "<table>"; while ($filas = $valores->fetch_array()) { echo "<tr>"; // Mostrar idSocio echo "<td>".$filas[0]."</td>"; // Mostrar nombreSocio echo "<td>".$filas[1]."</td>"; // Mostrar apellidosSocio echo "<td>".$filas[2]."</td>"; // Mostrar correoElectronicoSocio echo "<td>".$filas[3]."</td>"; echo "</tr>"; } echo "</table>"; ?> Página 56 de 59 Programación Web Si lo ejecutamos, obtendremos algo similar a esto: Para practicar, se puede ahora realizar toda la funcionalidad para la tabla accesos. Salir del atasco Para acabar esta introducción al lenguaje de programación PHP, no podemos dejar de comentar sobre los ficheros de log que se van generando cuando programamos. Estos ficheros de log contienen información muy interesante de acceso, de errores, advertencias y toda una serie de informaciones que nos puede ayudar cuando las cosas no salen como queremos. La ubicación de dichos ficheros depende del servidor web que tengamos instalados. En nuestro caso, estamos trabajando con MAMP, así que debemos buscar dichos ficheros en la ubicación de instalación de dicho paquete, en la carpeta \logs. Si disponemos de otro tipo de instalación (Apache, Nginx, IIS, WAMP, …) tendremos que averiguar cuál es la ruta correcta donde se guardan los ficheros de log. Página 57 de 59 Programación Web Ahí podemos ver varios ficheros: Son ficheros de texto plano, con lo cual son fáciles de abrir y podemos “mirar” en su interior en busca de pistas de qué está ocurriendo para que nuestro proyecto no salga como queremos. Por ejemplo, si al ejecutar nuestra ampliación web, se genera en el fichero de log phperror.log una línea como esta… [10-Sep-2018 21:31:36 Europe/Madrid] PHP Notice: Array to string conversion in G:\MAMP\htdocs\aplicacion\crud.php on line 93 … nos indica que en la línea 93 del fichero crud.php se está haciendo una conversión incorrecta de tipos, más concretamente de Array a cadena. O esta otra… [28-Aug-2018 19:57:22 Europe/Madrid] PHP Notice: Undefined variable: port in G:\MAMP\htdocs\aplicacion\crud.php on line 10 … que indica que en la línea 10 se está haciendo referencia a una variable llamada port, que no está definida. Página 58 de 59 Programación Web Práctica Final Como práctica final, se pide que se realice una aplicación web completa que gestione los socios y los accesos, incluyendo HTML5, CSS3 o Bootstrap para el diseño, y se use PHP para gestionar la aplicación con acceso a MySQL. 09/11/2019 Página 59 de 59