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:
cd ~
git clone git@github.com:rafacabeza/entornods.git
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.
cd entornods
Iniciar servicio:
docker-compose up -d
Parar servicio:
docker-compose down
Ver máquinas corriendo:
docker-compose ps
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.127.0.0.1 web1.com 127.0.0.1 web2.com 127.0.0.1 phpmyadmin.docker
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{ "key": "ctrl+shift+d", "command": "editor.action.copyLinesDownAction", "when": "editorTextFocus" }
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"
cd ~/entornods git checkout --track origin/ejercicios
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.
cd data git clone git@github.com:USUARIO_ALUMNO_EN_GITHUB/ejerciciciosphp.git
Una vez clonado, nuestro repositorio local está vinculado al que guardamos en GitHub
Podemos comprobarlo ejecutando:
cd ejercicios git remote -v
El resultado indica algo así:
origin git@github.com:USUARIO_ALUMNO_EN_GITHUB/ejerciciciosphp.git (fetch) origin git@github.com:USUARIO_ALUMNO_EN_GITHUB/ejerciciciosphp.git (push)
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:
cd ejercicios git remote add rafa git@github.com:rafacabeza/ejerciciciosphp.git
Nos falta preparar el fichero
/etc/hosts
. Debemos añadir:127.0.0.1 ejercicios.local
Ya casí está. Vamos a "entornods", paramos los servicios y los vovemos a levantar:
cd ~/entornods docker-compose down docker-compose up -d
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.
<!DOCTYPE html>
<html>
<head>
<title>Ejemplo</title>
</head>
<body>
<?php
echo "¡Hola, soy un script de PHP!";
?>
</body>
</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
echo "Hola mundo!";
Las sentencias acaban en ";".
Los comentarios:
<?php echo 'Esto es una prueba'; // Comentario estilo de C de una línea // (o C++ o Java o ....) /* Esto es un comentario multilínea y otra lína de comentarios */ echo 'Una prueba final'; # Comentario estilo de consola de una línea /** * Comentario al estilo Phpdoc * Como en Javadoc .... */ ?>
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:
$foo = 10; // $foo es un integer $str = "$foo"; // $str es un string $fst = (string) $foo; // $fst es tambien un string
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:
isset($variable) //true si existe empty($variable) //true si no existe o su valor es 0 o ""
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:
define("MAXSIZE", 100); echo MAXSIZE; echo constant("MAXSIZE"); // lo mismo que la línea anterior // Funciona a partir de PHP 5.3.0 const CONSTANTE = 'Hola Mundo'; echo CONSTANTE;
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
.$frutas = ['manzana', 'naranja', 'uva']; $frutas = array('manzana', 'naranja', 'uva'); $frutas = [0 => 'manzana', 1 => 'naranja', 2 => 'uva']; $frutas = array(0 => 'manzana', 1 => 'naranja', 2 => 'uva'); //las cuatro sentencias son equivalentes
Ojo, podríamos combinar tipos de datos:
$array = [2, 'naranja', 3.1416];
Y acceder así:
echo "Me gusta la $frutas[2]";
Añadir y quitar elementos
Podemos añadir elementos. El array crece a demanda:
$frutas[] = 'manzana'; // si fruta está vacío, posición 0
$frutas[] = 'naranja'; // ahora posición 1
$frutas[2] = 'uva'; //ahora posición 2 porque lo ponemos, o cualquier otra.
Y podemos eliminar elementos:
unset($frutas[1]);
Recorrer un array
Lo ideal es usar un bucle
foreach
. Hay dos variantes://si no nos preocupa la clave de cada valor foreach ($frutas as $fruta){ echo $fruta . '<br>'; } foreach ($frutas as $clave => $fruta){ echo $clave . ": " . $fruta . '<br>'; }
Arrays asociativos
En un array asociativo las claves para referenciar cada valor son strings.
Para declarar un array o añadir elementos:
//podemos declarar un array: $alumno = array ( 'id' => 5, 'nombre' => 'Manuel', 'apellido' => 'García López', 'edad' => 23 ); $alumno['sexo'] = "V"; //y podemos 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.
$filas = [
0 => [11, 12],
1 => [21, 22],
3 => [31, 32]
];
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
<form action="/ruta_destino" method="get">
<input type="text" name="nombre" value="">
<input type="password" name="password" value="">
<input type="hidden" name="secreto" value="">
<input type="submit" value="enviar">
</form>
El método GET envía los datos en la cabecera.
Los datos se ven en la barra del navegador.
Pueden usarse en enlaces.
http://misitioweb.com/destino.php?nombre="juan"&edad="16"
El método POST envía los datos en el cuerpo. Es más seguro.
http://misitioweb.com/destino.php
Normalmente el formulario lo crea un fichero y recibe sus datos otro fichero indicado en el action.
El action puede:
Usar rutas absolutas (RECOMENDABLE)
action="/destino.php"
Usar rutas relativas
action="destino.php"
Hacer referencia al fichero actual
`action="#"`
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í:
$nombre = $_GET['nombre']; //si el método es GET $nombre = $_POST['nombre']; //si es POST $nombre = $_REQUEST['nombre'];//válido en ambos casos
Puede ser conveniente comprobar si existe la variable:
if (isset($_GET['nombre'])) {
$nombre = $_GET['nombre'];
} else {
$nombre = '';
}
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:
<input type="radio" name="sexo" value="male" checked> Varón <br> <input type="radio" name="sexo" value="female"> Mujer <br>
Select:
<select name="color"> <option>rojo</option> <option>azul</option> ... <option selected>blanco</option> </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:
<input type="text" name="ideas[]"> <input type="text" name="ideas[]">
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:
//Código del ejemplo 13 <form action=""> <input type="text" name="nombres[]"> <input type="submit" value="Nuevo"> <hr> <?php if (isset($_GET['nombres'])) { foreach($_GET['nombres'] as $nombre) { echo '<input type="text" name="nombres[]" value="' . $nombre . '"><br>'; } } ?> </form>
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:
<?php function factorial($numero) { $resultado = 1; for ($i=1; $i <= $numero; $i++) { $resultado = $resultado * $i; } return $resultado; } echo "El factorial de 5 es " . factorial(5); echo "<br>"; echo "Y el factorial de 10 es " . factorial(10); ?>
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
class ClaseSencilla
{
// Declaración de una propiedad
public $var = 'un valor predeterminado';
// Declaración de un método
public function mostrarVar() {
echo $this->var;
}
//NOTA: $this hace referenca a este objeto
//"->" se usa para acceder a métodos y atributos
}
?>
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
<?php
class Persona
{
public $nombre;
public $apellido;
public $edad;
public function __construct($nombre, $apellido, $edad)
{
$this->nombre = $nombre;
$this->apellido = $apellido;
$this->edad = $edad;
}
public function saludar()
{
echo "Buenos días!";
}
public function __toString()
{
return $this->nombre;
}
}
Y ahora la usamos:
<body>
<?php
require('Persona.php');
$juan = new Persona('Juan', 'García', 15);
echo $juan-> saludar();
echo "<br>";
echo "Soy $juan";
echo "<br>";
echo "Mi nombre completo es $juan->nombre $juan->apellido y tengo $juan->edad años";
?>
</body>
Una clase como aplicación web
El script de entrada:
<?php
require_once "App.php";
$app = new App;
$app->run();
La clase
<?php
class App
{
public function __construct($name = "Aplicación PHP")
{
echo "Consturyendo la app <hr>";
$this->name = $name;
$this->module = "Desarrollo Web en Entorno Servidor";
$this->teacher = "Rafael Cabeza";
$this->student = "Fulano De Tal";
}
public function run()
{
echo "Moneda al aire... <hr>";
$moneda = rand(0,1);
// if ($moneda == 1) {
if ($moneda) {
echo "<h3>Ha salido cara: </h3> <br>";
$this->index();
} else {
echo "<h3> Ha salido cruz: </h3> <br>";
$this->login();
}
}
public function index()
{
echo "Estamos en el index<br>";
echo "Estos es $this->name<br>";
echo "Me llamo $this->student<br>";
echo "Estamos estudiando $this->module con el profesor $this->teacher<br>";
}
public function login()
{
echo "Ahora podría mostrar un formulario de login <br>";
}
}
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í:
public function index()
{
echo "Estamos en el index<br>";
include('views/index.php');
}
public function login()
{
echo "Estamos en login <br>";
include('views/form.php');
}
Ojo. Necesiamos un carpeta views
Y nuestras vistas quedarían así:
...
<body>
<h1>Home de <?= $this->name ?></h1>
<div>
Estamos en el index
</div>
Me llamo <?= $this->student ?>
<br>
Estamos estudiando <?= $this->module ?> con el profesor <?= $app->teacher ?>
</body></html>
...
<body>
<h1>Login de <?= $this->name ?></h1>
<form action="">
<label for="">nombre</label>
<input type="text" name="name"> <br>
<label for="">contraseña</label>
<input type="password" name="password"> <br>
<input type="submit">
</form>
</body>
</html>
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.
http://ejercicios.local/ejemplos/18/index.php?method=index
http://ejercicios.local/ejemplos/18/index.php?method=login
//equivalente:
http://ejercicios.local/ejemplos/18?method=index
http://ejercicios.local/ejemplos/18?method=login
Debemos recoger esos argumentos en el run de App:
public function run()
{
if (isset($_GET['method'])) {
$method = $_GET['method'];
} else {
$method = 'index';
}
$this->$method();
}
Y debemos añadir enlaces en ambas páginas.
<header> <ul> <li><a href="/ejemplos/18?method=index">Inicio</a></li> <li><a href="/ejemplos/18?method=login">Login</a></li> </ul> </header>
¿Lo ponemos en cada vista?
Mejor creamos un header.php
Y lo incluímos en ambas vistas
<?php require('views/header.php'); ?>
Además podemos añadir un poco de CSS
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
}
li {
float: left;
}
li a {
display: block;
padding: 8px;
background-color: #dddddd;
}
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:
setcookie(x,y,time()-1)
Ejemplo de creación de cookies. Incluso arrays y objetos:
setcookie("user", "Fulanito de Tal", time() + 3600);
//ojo para guardar arrays:
$hobbies = ['futbol', 'música rock', 'tocar la guitarra con mis amigos'];
setcookie("hobbies", serialize($hobbies), time() + 3600);
setcookie("hobbies2", json_encode($hobbies), time() + 3600);
//y objetos:
$persona = new Persona("Juan", "Pérez", 21);
setcookie("persona", serialize($persona), time() + 3600);
setcookie("persona2", json_encode($persona), time() + 3600);
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
header('Location: direccion'); header('Location: /index.php'); header('Location: ?method=home'); header('Location: https://google.com');
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:
<?php foreach ($lista as $id => $element) { ?> <li> <?= $element ?> <a href="?method=ver&id=<?= $id ?>">Ver</a> - <a href="?method=borrar&id=<?= $id ?>">Borrar</a> </li> <?php } ?>
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:
$_SESSION['name'] = $name;
//añadir elementos a un array dentro de la sesión
$_SESSION['deseos'][] = $new;
//lo mismo pero más "pensado"
$deseos = $_SESSION['deseos'];
$deseos[] = $new;
$_SESSION['deseos'] = $deseos;
Se pueden elimnar elementos selectivamente o borar toda la sesión:
unset($_SESSION['elemento']); #borra un elemento
session_destroy(); #elimina toda la información de sesión.
Sobre las opciones de sesión. Sus parámetros se establecen en el php.ini: enlace.
Cookie o url.
Autostart, para requerir el uso de session_start() o no.
Tiempo de vida
Nombre (por defecto PHPSESSID)
otros...
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.
<?php
function dividir($dividendo, $divisor) {
if($divisor == 0) {
throw new Exception("División por cero");
}
return $dividendo / $divisor;
}
//esto funciona
echo dividir(5, 3);
//esto va a fallar porque no sabemos que hacer con la excepción
echo dividir(5, 0);
La sentencia try..catch
Su sintáxis es:
try {
//código que puede lanzar excepciones
} catch(Exception $e) {
//código que coge (catch) la excepción
//se ejecuta si se lanza una excepción
}
Ejemplo:
<?php
function dividir($dividendo, $divisor) {
if($divisor == 0) {
throw new Exception("División por cero");
}
return $dividendo / $divisor;
}
try {
echo dividir(5, 3) . "<br>";
echo dividir(5, 0) . "<br>";
} catch (Throwable $e) {
echo "Fallo: " . $e->getMessage();
}
Sentencia try...catch...finally
Permite añadir código que se ejecute siempre, haya o no excepción.
try {
//código que puede lanzar excepciones
} catch(Exception $e) {
//código que coge (catch) la excepción
//se ejecuta si se lanza una excepción
} finally {
//código que se ejecuta siempre,
//haya o no excepción
}
Ejemplo
<?php
function dividir($dividendo, $divisor) {
if($divisor == 0) {
throw new Exception("División por cero");
}
return $dividendo / $divisor;
}
try {
echo dividir(5, 3) . "<br>";
echo dividir(5, 0) . "<br>";
} catch (Throwable $e) {
echo "Fallo: " . $e->getMessage();
} finally {
echo "<hr>";
echo "divisiones acabadas";
}
El objeto "Exception"
Al crear un objeto exception podemos pasar 3 atributos:
new Exception(message, code, previous)
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:
<?php
class emailException extends Exception {
public function errorMessage() {
//error message
$errorMsg = 'Error en la línea '.$this->getLine().' del fichero '.$this->getFile()
.': <b>'.$this->getMessage().'</b> no es una dirección válida de correo';
return $errorMsg;
}
}
$email = "someone@example...com";
try {
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
throw new emailException($email);
}
}
catch (emailException $e) {
echo $e->errorMessage();
}
Incluso más de una:
<?php
class emailException extends Exception {
public function errorMessage() {
//error message
$errorMsg = 'Error en la línea '.$this->getLine().' del fichero '.$this->getFile()
.': <b>'.$this->getMessage().'</b> no es una dirección válida de correo';
return $errorMsg;
}
}
class ageException extends Exception {
public function errorMessage() {
$errorMsg = 'Error en la línea '.$this->getLine().' del fichero '.$this->getFile()
.': <b>'.$this->getMessage().'</b> no es una edad válida';
return $errorMsg;
}
}
$email = "someone@example...com";
$age = "-5";
try {
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
throw new emailException($email);
}
throw new ageException($age);
if($age < 0) {
}
}
catch (emailException $e) {
echo $e->errorMessage();
}
catch (ageException $e) {
echo $e->errorMessage();
}
Podríamos incluso añadir un catch por defecto:
$email = "someone@example...com";
$age = "-5";
$condition = true;
try {
if ($condition) {
throw new Exception("excepción por que sí!");
}
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
throw new emailException($email);
}
throw new ageException($age);
if($age < 0) {
}
}
catch (emailException $e) {
echo $e->errorMessage();
}
catch (ageException $e) {
echo $e->errorMessage();
}
catch ($e) {
echo $e;
}
Ficheros
Abrir un fichero: fopen(ruta, modo)
La función devuelve 0 si no se puede abrir:
if (!$fp = fopen("miarchivo.txt", "r")){
echo "No se ha podido abrir el archivo";
}
El fichero puede ser incluso una url:
$fp = fopen("http://localhost/miarchivo.txt", "r");
Donde modo:
r Apertura para lectura. Puntero al principio del archivo
r+ Apertura para lectura y escritura. Puntero al principio del archivo
w Apertura para escritura. Puntero al principio del archivo y lo sobreescribe. Si no existe se intenta crear.
w+ Apertura para lectura y escritura. Puntero al principio del archivo y lo sobreescribe. Si no existe se intenta crear.
a Apertura para escritura. Puntero al final del archivo. Si no existe se intenta crear.
a+ Apertura para lectura y escritura. Puntero al final del archivo. Si no existe se intenta crear.
x Creación y apertura para sólo escritura. Puntero al principio del archivo. Si el archivo ya existe dará error E_WARNING. Si no existe se intenta crear.
x+ Creación y apertura para lectura y escritura. Mismo comportamiento que x.
c Apertura para escritura. Si no existe se crea. Si existe no se sobreescribe ni da ningún error. Puntero al principio del archivo.
c+ Apertura para lectura y escritura. Mismo comportamiento que C.
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
<?php
$file = fopen("archivo.txt", "w");
fwrite($file, "Esto es una nueva linea de texto" . PHP_EOL);
fwrite($file, "Otra más" . PHP_EOL);
fclose($file);
echo "texto escrito!!";
Ejemplo de añadir texto:
<?php
$file = fopen("archivo.txt", "a");
fwrite($file, "Linea anexada en: " . time() . PHP_EOL);
fclose($file);
echo "texto escrito!!";
echo "<hr>";
Ejemplo de lectura completa:
<?php
$file = "miarchivo.txt";
$fp = fopen($file, "r");
$contents = fread($fp, filesize($file));
fclose($fp);
var_dump($contents);
<<<<<<< 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.
<?php
$fp = fopen("archivo.txt", "r");
if ($fp) {
while (($line = fgets($fp)) !== false) {
$lista[] = $line;
}
if (!feof($fp)) {
echo "Error: fallo inesperado de fgets()\n";
}
fclose($fp);
foreach ($lista as $key => $item) {
echo "$key: $item <br>";
}
} else {
echo "datos no disponibles";
}
=======
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
Was this helpful?