PHP
Entorno de desarrollo.
El enfoque tradicional sería usar una máquina con windows o linux y:
Servidor web. Típicamente Apache 2.
Servidor de bases de datos. Típicamente Mysqsl.
Entorno de administración de bases de datos. Típicamente PhpMyAdmin.
Yo opto por usar
docker
. Esto me da más seguridad respecto al entorno usado por los alumnos.Vamos a partir del entorno de desarrollo preparado con docker:
https://github.com/rafacabeza/entornods
Debemos clonar dicho repositorio en nuestro espacio de trabajo:
Obtenemos un entorno docker para desarrollar en php:
Uno o más servicios web.
Un servicio de base de datos Mysql
Un servicio PhpMyAdmin para administrar las bases de datos.
Para gestionarlo necesitamos la consola y necesitamos ir a la carpeta que lo contine.
Iniciar servicio:
Parar servicio:
Ver máquinas corriendo:
En este entorno se van a usar tres sitios web de prueba. Para poder usarlos debemos engañar al DNS.
Debes editar tu fichero
/etc/hosts
para acceder a los dos sitios web creados por el mismo.Prueba a hacer ping a estos sitios.
Este entorno creo los siguientes contendedores en su rama master:
proxy: Es un proxy nginx para poder mantener simultaneamente múltiples contenedores con diferentes sitios web.
db: Contenedor mysql para uso de bases de datos.
phpmyadmin: Contenedor para administración web del anterior.
web1: sitios web1.com apache y php (Dockerfile web1)
web2: sitio web2.com con apache y php (php:7.4-apache)
Pruebe en su navegador las siguientes url's:
El último sitio nos permite accede a
phpmyadmin
Este entorno incorpora un script para inicializar una base de datos en
./data/init-db
Conectese a http://phpmyadmin.docker e importe el script citado.
Pruebe a acceder ahora de nuevo a http://web1.com/
Analiza lo ocurrido y crea otro sitio web en el mismo entorno llamado web3 (web3.com).
A trabajar!
Visual Studio Code
Vamos a añadir algunos complementos:
PHP IntelliSense
PHP Intelephense
PHPml (PHP in Html)
Atajo JSON:
ctrl+shift+P
+ shotcut
Entorno
El repositorio entornods está en su rama master. Ahí tenemos los servicios que hemos explicado.
Pero ahora no necesitamos web1 ni web2. Necesitamos un servicio para hacer ver ejemplos y hacer ejercicios.
El uso de ramas en git me permite hacer esto fácilmente
Vamos a cambiar a la rama ejercicios de nuestro "entornods"
Nuestro docker-compose ya está preparado para servir el contendio de "data/ejercicios". Examina el fichero docker-composer.yml para comprobarlo.
Lo siguiente es crear ese directorio data/ejercicios.
Podríamos hacerlo desde 0 pero vamos a usar el repositorio que a hemos preparado para eso.
Ese repositorio es propiedad del profesor. Me sirve para descargarme cosas pero no para guardar mis soluciones.
Por eso no me interesa hacer un "clon" sino un "fork".
Hacer un clon consiste en descargar el código del profesor (no me intereasa).
Hacer un fork consiste en copiar el repositorio del profesor en el espacio de GitHub del alumno.
Ese repositorio resultante es el que debe ser clonado.
Una vez clonado, nuestro repositorio local está vinculado al que guardamos en GitHub
Podemos comprobarlo ejecutando:
El resultado indica algo así:
Como vermos más adelante, me puede interesar vincular un repositorio local a dos remotos:
El mío (alumno) con mis ejercicios.
El del profesor, por si añade ejemplos o enunciados de problemas.
Para hacerlo:
Nos falta preparar el fichero
/etc/hosts
. Debemos añadir:Ya casí está. Vamos a "entornods", paramos los servicios y los vovemos a levantar:
Y vamos a nuestro navegador: http://ejercicios.local
Primeros pasos
Damos por hecho que el alumno tiene una base de programación y de orientación a objetos.
Vamos a hacer un recorrido rápido sobre las bases de PHP.
Para completar información respecto a lo que aquí se cuenta el mejor sitio
es la documentación oficial php.net/manual/es/
¿Qué es PHP?
PHP (acrónimo recursivo de "PHP: Hypertext Preprocessor") es un lenguaje de código abierto muy popular especialmente adecuado para el desarrollo web y que puede ser incrustado en HTML.
PHP está construído a partir de Perl
Perl está basado en C.
Las variables son al estilo Perl
La sintáxis es muy similar a C (y por tanto a Java)
Sintáxis básica:
Los ficheros php deben tener extensión ".php"
El php puede estar embebido en código html
Los fragmentos de php deben ir etiquetasdos entre
<?php ?>
O pueden ser ficheros código php puro.
Sólo debe aparecer al inicio la marca de apertura:
<?php
Las sentencias acaban en ";".
Los comentarios:
Tipos
Los tipos básicos son:
Entero: número entero con signo
Flotante: número decimal con signo
Booleano: vale true o false
Cadena de caracteres: cadena de caracteres delimitada por comillas simples o dobles.
Existen otros más complejos que iremos viendo:
Arrays
Objetos
Recursos
....
Podemos consultar el tipo de una variable con
gettype()
.Y hacer casting para cambiar el tipo:
Casting o forzados permitidos
(int), (integer) - forzado a integer
(bool), (boolean) - forzado a boolean
(float), (double), (real) - forzado a float
(string) - forzado a string
(array) - forzado a array
(object) - forzado a object
(unset) - forzado a NULL (PHP 5)
Variables
Las variables deben comenzar por dolar:
$miVariable
No necesitan ser declaradas, basta inicializarlas.
No tienen un tipo fijo.
Deben segir notación de estilo
$camelCase
;Podemos consultar si una variable está definida y su tipo de dato:
El ámbito de las variables es:
Global si está fuera de una función o una clase
Local dentro de funciones
Podemos definir variables estáticas dentro de las funciones. Su valor no cambia entre invocaciones.
El ámbito es compartido con ficheros incuídos.
Constantes
Las constantes se crear usarndo
define
oconst
El estándar dice que deben ser en mayúsculas:
Operadores
Los operadores lógicos y matemáticos son casi ideńticos a C o Java.
Rseñar:
Concatenación
.
.Asignación y concatenacion
.=
, similar a+=
.
Hay alguna curiosidad en los los de comparación
Estructuras de control
Las estructuras de control son muy similares a Java
Podemos empezar a codificar con lo que sabemos.
Podemos importar el contenido de otros ficheros de código con
include, include_once, require, require_once
Require para la ejecución si no encuentra el fichero.
La variante "_once" comprueba que no se ha requerido/incluído el mismo fichero antes. Importante al importar clases.
La estructura foreach permite recorrer arrays (y otros objetos iterables).
Arrays
En Php un array es un tipo de dato compuesto. Es una colección de datos.
En un array hay una asociación entre cada valor y su clave de acceso.
Las claves pueden ser:
Números: arrays ordenados.
Cadenas de texto: arrays asociativos (mapas).
Declarar un array ordenado:
Podemos usar los corchetes o la función
array
.Ojo, podríamos combinar tipos de datos:
Y acceder así:
Añadir y quitar elementos
Podemos añadir elementos. El array crece a demanda:
Y podemos eliminar elementos:
Recorrer un array
Lo ideal es usar un bucle
foreach
. Hay dos variantes:
Arrays asociativos
En un array asociativo las claves para referenciar cada valor son strings.
Para declarar un array o añadir elementos:
Igualmente podemos usar foreach en cualquiera de sus variantes.
Y podemos acceder a un valor usando corchetes: $alumno['nombre'] = "Juan";
Arrays multidimensionales
Un elemento de un array puede ser otro array.
Esto nos permite definir arrays de dos o más dimensiones.
Formularios
Los formularios son la forma más común de enviar información del cliente al servidor.
Vamos a ver en qué consiste.
HTML
¿Qué puedo encontrar en un formulario?
La etiqueta form que define el método (method get o post)
El destinatario (action)
Y los datos a rellenar o inputs
El método GET envía los datos en la cabecera.
Los datos se ven en la barra del navegador.
Pueden usarse en enlaces.
El método POST envía los datos en el cuerpo. Es más seguro.
Normalmente el formulario lo crea un fichero y recibe sus datos otro fichero indicado en el action.
El action puede:
Usar rutas absolutas (RECOMENDABLE)
Usar rutas relativas
Hacer referencia al fichero actual
Los input que debéis usar son los del ejemplo: text, password, hidden y submit.
No debéis usar tipos como numeric o date. Estos tipos mejoran la esperiencia de usuario pero no permiten probar algunas cosas en el servidor. No nos interesa usarlos en este módulo
Variables superglobales
Las variables superglobales son creadas por el sistema.
Las variables que podemos encontrar son:
$_SERVER. Inf. del script actual y del servidor.
$_GET. Datos formulario con método GET.
$_POST. Idem con método POST.
$_FILES. Ficheros enviados en un formulario.
$_COOKIE. Cookies (para más adelante)
$_REQUEST. Combina las tres anteriores.
$_SESSION. Datos de sesión (para más adelante)
</small>
Recepción de datos
Los datos se reciben así:
Puede ser conveniente comprobar si existe la variable:
Elegir entre varias opciones:checkbox, radio y select
Para entender las posibilidades debes analizar el ejemplo 11.
Si queremos elegir uno entre varios podemos usar
Radio:
Select:
MIRA BIEN: para preseleccionar una opción debemos usar checker o selected.
Si queremos seleccionar varios entre varios debemos usar checkbox (o select multiple).
En ambos casos nos interesa recibir un array con la colección de varios elegida.
En PHP, debemos nombrar a nuestros inputs (o select) con corchetes:
Otra cosa interesante es que un script puede enviarse los datos a sí mismo. Basta con poner en el action del formulario el propio script, o más fácil todavía, dejando el action en blanco:
Ejercicio
Crea un formulario para enviar los datos de registro de un libro: título, autor, editorial, páginas.
Ejercicio
Crea un formulario para enviar campo nombre. Si el nombre existe se da un saludo. Si no existe se vuelve atrás indicando que el campo es obligatorio.
Ejercicio
Envío del script al mismo script. Crea un formulario para enviar campo nombre. El nombre debe existir y debe tener un tamaño mínimo de 3 caracteres. Si es válido se da un saludo. Si no lo es se vuelve a mostar el formulario indicando que el campo es obligatorio y mostrando en el "input" el valor anterior no válido.
Ejercicio
Envío del script al mismo script. Crea un formulario que funcione como calculadora. Debe contener dos input como operandos y un select para elegir operador.
Si se reciben los datos muestra el resultado.
Si no son válidos o no existen debe devolver a la página anterior.
Ejercicio
Crea un formulario que envíe un array de 3 nombres. Para hacerlo debes usar el mismo nombre en todos los input (name="nombres[]").
Ejercicio
Crea una lista usando etiquetas ul y li. La lista inicialmente estará vacía pero un formulario con un input servirá para añadir los elementos. Usa input de tipo hiddens para que no "olvidar" los elementos ya añadidos a la lista.
Funciones
Php es un lenguaje de scripting. El punto de entrada es la primera línea de un script siempre.
Pero soporta programación estructurada, por tanto funciones, y programación orientada a objetos, por tanto clases.
No vamos a poner mucha energía en las funciones (sí en POO), pero veamos un ejemplo:
POO
Php soporta POO desde la versión 5
En las versiones 7.* las posibilidades son muy completas.
Vamos a ver las cuestiones básicas.
Conceptos base: clases, objetos, atributos y métodos.
Visibilidad: public, protected, private
Métodos mágicos: constructor, destructor, toString, ...
Herencia, interfaces, métodos y atributos estáticos y finales
Muchas cosas y algunas de ellas no las emplearemos nunca.
Vamos a ir explicando conceptos ya conocidos segun nos haan falta.
Notación
Nombre de la clase CamelCase.
Una clase - un fichero, y ambos con el mismo nombre.
Atributos y funciones con nombres camelCase
Métodos mágicos
Reciben este nombre los que se ejecutan de foma "mágica". Sin petición explícita.
Siempre empiezan por doble guión bajo. Los más destacables:
__construct()
: constructor. Se ejecuta al crear un objeto.__destruct()
: destructor. Se ejecuta al eliminar un objeto.__toString()
: se ejecuta cuando imprimimos un objeto. Lo convierte a string.
Particularidades
Para acceder a métodos y atributos usamos "->".
Para acceder a constantes de clase y métodos estáticos usamos "::"
Para referirnos al propio objeto usamos $this
Mi primera clase
Y ahora la usamos:
Una clase como aplicación web
El script de entrada:
La clase
Separar vista de lógica
Pero podemos ser un poco formales en nuestro código:
Los cálculos que debamos hacer los hacemos dentro de un método de la clase. Un fichero php puro.
El html lo generaremos en un fichero mixto html/php.
Esto no es obligatorio. No es requisito del lenguaje. Pero nos ayudará a crear código limpio.
Podríamos trasformar nuestra clase así:
Ojo. Necesiamos un carpeta views
Y nuestras vistas quedarían así:
Vamos a refinar un poco más nuestra aplicación
Dejemos de jugar al azar. ¿Cómo decidimos qué método?
Podemos hacerlo de muchas maneras. Vamos a optar por argumentos GET.
Debemos recoger esos argumentos en el run de App:
Y debemos añadir enlaces en ambas páginas.
¿Lo ponemos en cada vista?
Mejor creamos un header.php
Y lo incluímos en ambas vistas
Además podemos añadir un poco de CSS
Ejercicio.
Crea una aplicación web con una clase App y varios métodos. En todos los casos se trata de obtener una serie numérica. El método debe calcular la serie y guardarla en un array, después hay que incluir una vista que muestre la serie. Puede ser que necesites crear métodos auxiliares (private) para el cálculo del array, por ejemplo: esPrimo(). Los métodos necesarios son:
Index (index). Presentación de la App y enlaces.
Fibonacci (fibonacci). Muestra la serie de Fibonacci. Debe mostrar todos los términos menores a un millón.
Potencias de 2 (potencias2). Debe mostrar los valores de las potencias de 2 hasta 2 elevado a 24 (nº de colores True Color, por ejemplo).
Factorial (factoriales). Debe mostar los factoriales desde 1 hasta n de tal manera que el último término sea el más próximo cercano al millón.
Nº. primos (primos). Debe encontrar los números primos entre 1 y 10.000.
Cookies
Una cookie es un fichero de texto que se guarda en el equipo del cliente.
Este fichero está ligado al sitio web que lo crea y al navegador usado.
En él se almacena el contenido de un array de variables.
Se crea mediante la función setcookie(). La función necesita:
Clave: nombre de la variable.
Valor: contenido de la misma. Debe ser texto (o convertible).
Tiempo unix de vida (en segundos). Por defecto, 0, se elimina al cerrar el navegador.
Se accede a su contenido mendiante la variable superglobal $_COOKIE
Para eliminar una cookie usa setcookie con tiempo menor al actual:
Ejemplo de creación de cookies. Incluso arrays y objetos:
Arrays y objetos deben tratarse con:
serialize/unserialize: nativo php. Los objetos se recrean en su clase.
json_encode/json_decode: estándar. Los objetos se recrean como stdClass.
Reenvío
Habitualmente una petición acaba con la construcción de una vista html.
home: página de inicio de una apliación
login: página con formulario de entrada, ...
Pero otras veces queremos que el servidor haga una tarea y después el navegador vaya a una dirección determinada. Por ejemplo:
auth: toma los datos de login. Si son "buenos" reenvía a "home" y si son malos reenvía a "login" de nuevo.
Para hacer esto hay que usar el status 302 de HTTP.
Con php debemos hacer esto con la función header. Veamos ejemplos
Siempre que te pidan reenvío usa header() y no include()
Ejercicio
Vamos a crear una App con estos métodos:
login: muestra un formulario de login (usuario y contraseña).
auth: guarda el usuario y su contraseña en una cookie. Después reenvía la petición a home.
home: Muestra un saludo y un enlace para cerrar sesión.
logout: elimina las cookies (setcookie(...., time() - 1)) y reenvía a login.
Depura tu código. En login, comprueba que no hay ya un usuario. Si lo hay reenvía a home.
Enlaces que aportan información
Ya hemos visto que los enlaces pueden incluir parámetros "GET".
Cuando manejamos listas podemos definir enlaces con mucha información. Veamos un ejemplo para luego usarlo en un ejercicio:
Ejercicio 19
Se trata de crear una lista de deseos Usaremos la clase App con los siguietens métodos:
login método que muestra formulario de entrada.
auth método que toma el nombre de usuario tras el login. Tras hacer esto reenvía a home.
home método que muestra la lista de deseos. Además muestra un formulario de nuevos deseos. El formulario envía al método new
new toma el nuevo deseo y lo incluye en la lista.
delete borra un deseo de la lista. Debe recibir el indice del deseo.
empty vacía la lista de deseos.
close Cierra sesión: borra la cookie.
Ejercicio 20
Colorear una página con ayuda de una cookie. Usaremos la clase App con los siguietens métodos:
home muestra un mensaje de bienvenida. Comprueba si hay una cookie llamada "color". Si existe la usa para darle color al fondo de la ágina.
colores muestra una lista de colores. Cada color tiene un enlace del estilo ?method=cambio&color=red . Al hacer clic cambiará el color del home.
cambio . Recibe el color de la página anterior, crea la cookie y reenvia ('header...') al método home.
NOTA: dos vistas (home y colores) y un reenvío (cambio).
Sesiones
También llamadas cookies del lado del servidor.
Guardan la información en el servidor (RAM, fichero, BBDD, ...).
Se apoyan en una cookie que se envía al navegador y que sirve de clave para recuperar la información almacenada.
Antes de agregar o acceder a las variables de sesión, debemos "avisar" con la función session_start().
Al iniciar la sesión se crea un id aleatorio para la sesión. Este id se puede transmitir en la url o guardar en una cookie de forma transparente al programador. La opción de la url es poco recomendaable por segurirdad.
La información se guarda en la variable superglobal $_SESSION. Es un array al que podemos añadir elementos según necesitamos y que podemos leer como es habitual.
Añadir elementos a sesión:
Se pueden elimnar elementos selectivamente o borar toda la sesión:
Sobre las opciones de sesión. Sus parámetros se establecen en el php.ini: enlace.
Ejercicio 21
Haz el ejercicio 19 pero usando sesiones en vez de cookies
Ejercicio 22
Haz el ejercicio 20 pero usando sesiones en vez de cookies
Excepciones
Una excepción es un objeto. Describe un error o comportamiento indeseado.
Existe en php como en otros muchos lenguajes, p.ej. Java.
Sirven para parar el funcionamiento normal ante situaciones indeseadas.
Muchas funciones y clases del lenguaje lanzan excepciones.
En nuestro código también podemos lanzar excepciones.
La sentencia try..catch
Su sintáxis es:
Ejemplo:
Sentencia try...catch...finally
Permite añadir código que se ejecute siempre, haya o no excepción.
Ejemplo
El objeto "Exception"
Al crear un objeto exception podemos pasar 3 atributos:
message es un texto. Parámetro principal
code un código numérico de error
previous se usa si lanzamos una excepción dentro de un catch
La excepción recibida dispone de los métodos:
getMessage(), getter del message.
getPrevious(), getter del previous
getCode(), getter del code
getFile(), devuelve el fichero que lanza la excepción
getLine(), devuelve la línea que lanza la excepción
getTrace(), devuelve array con la traza de la pila de llamadas.
getTraceAsString(), idem convertido a texto.
Excepciones a medida
Podemos crear nuestro propio tipo de excepciones:
Incluso más de una:
Podríamos incluso añadir un catch por defecto:
Ficheros
Abrir un fichero: fopen(ruta, modo)
La función devuelve 0 si no se puede abrir:
El fichero puede ser incluso una url:
Donde modo:
Ojo:
Si el archivo no es escribible, abrirlo con r+ fallará, incluso cuando sólo se intenta leer.
w y w+ eliminarán el contenido de cualquier archivo. Para sólo añadir y no borrar, se usa a y a+.
Si quieres crear nuevos archivos y evitar sobreescribir sin querer un archivo existente, utiliza x o x+.
Cuando se trabaja con archivos binarios, como imágenes, hay que añadir 'b' después del modo. Como rb o r+b
Ejemplo de escritura
Ejemplo de añadir texto:
Ejemplo de lectura completa:
<<<<<<< HEAD
Ejercicio 23.
Crea una aplicación para almacenar una lista de deseos
Lista de métodos:
home, método por defecto. Muestra la lista de deseos y un formulario para añadir nuevos.
new, toma la informacion del nuevo deseo y lo añade al fichero. Después reenvía a home.
clear, borra toda la lista de deseos y velve al home.
delete, borra selectivamente elementos de la lista de deseos. Mira el siguiente ejemplo para ver como cargar las líneas del fichero en un array. NOTA: debes, cargar el array, borrar el elemento y volver a escribir el fichero completo.
=======
Ejercicio 23
Realiza el ejercicio de la lista de deseos usando un fichero deseos.txt. Usa seriel
Método index, lee el contendio de la lista de deseos.
Método new, crea un
ea147b71ce3839cc9819e8b4cb1db6c0151c0319
Last updated