Académique Documents
Professionnel Documents
Culture Documents
Introducción a PHP5
Página 1 de 164
Kinética Mobile Development Curso de PHP5.
Página 2 de 164
Kinética Mobile Development Curso de PHP5.
ÍNDICE
Referencias.............................................................................................................. 150
Página 3 de 164
Kinética Mobile Development Curso de PHP5.
Página 4 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
ARCHIVO index.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H>Hola</H>
<br/>
<p>
Bienvenido/a a su página de contactos.
</p>
<p>
<a href=”contactos.html”>Entrar</a>
</p>
</body>
</html>
ARCHIVO contactos.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H> Mis Contactos</H>
<br/>
<p>
<a href=”JAniston.html”>Jennifer Aniston</a>
<br/>
<a href=”MEsparcia.html”>Manolo Esparcia</a>
<br/>
<br/>
</p>
<p>
Total: 2 contactos.
</p>
</body>
</html>
ARCHIVO JAniston.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H> Mis Contactos</H>
<br/>
<p>
Nombre: Jennifer
<br/>
Apellidos: Aniston
<br/>
Página 5 de 164
Kinética Mobile Development Curso de PHP5.
ARCHIVO MEsparcia.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H> Mis Contactos</H>
<br/>
<p>
Nombre: Manuel
<br/>
Apellidos: Esparcia Montoya
<br/>
Teléfono: 924 007 557
<br/>
Correo: mesparcia@edu.juntaex.es
<br/>
Lugar de Trabajo: Secretaría General
<br/>
Imagen:
<br>
<img src=”mesparcia.jpg”>
</p>
<p>
<a href="contactos.html">Volver</a>
</p>
</body>
</html>
Comprobamos en el navegador.
Página 6 de 164
Kinética Mobile Development Curso de PHP5.
o Preparar el contexto.
Con una herramienta ftp subimos nuestros ficheros a un servidor web para comprobar
cómo se desarrolla el trabajo normal al crear y mantener un sitio web.
Nota: en nuestro caso a un servidor conectado a nuestra red local para hacer
comprobaciones. También es posible crear un servidor local pero no permite comprender
claramente el concepto cliente-servidor.
ARCHIVO contactos.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
Página 7 de 164
Kinética Mobile Development Curso de PHP5.
<body>
<H> Mis Contactos</H>
<br/>
<p>
<a ref=”JAniston.html”>Jennifer Aniston</a>
<br/>
<a ref=”MEsparcia.html”>Manolo Esparcia</a>
<br/>
<a ref=”BDoblador.html”>Bender Doblador</a>
<br/>
<a ref=”FSmith.html”>Fry Smith</a>
<br/>
<br/>
</p>
<p>
Total: 4 contactos.
</p>
</body>
</html>
ARCHIVO BDoblador.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H> Mis Contactos</H>
<br/>
<p>
Nombre: Bender
<br/>
Apellidos: Doblador
<br/>
Teléfono: 924 007 002
<br/>
Correo: bdoblador@edu.juntaex.es
<br/>
Lugar de Trabajo: Secretaría General
<br/>
Imagen:
<br>
<img src=”bdoblador.jpg”>
</p>
<p>
<a href="contactos.html">Volver</a>
</p>
</body>
</html>
ARCHIVO FSmith.html
<html>
<head>
<title>Mis Contactos</title>
<meta name=”AUTHOR” content=”PAKO”>
</head>
<body>
<H> Mis Contactos</H>
<br/>
<p>
Nombre: Fry
<br/>
Apellidos: Smith
<br/>
Teléfono: 924 007 003
<br/>
Correo: fsmith@edu.juntaex.es
<br/>
Lugar de Trabajo: Secretaría General
<br/>
Imagen:
<br>
<img src=”fsmith.jpg”>
</p>
<p>
Página 8 de 164
Kinética Mobile Development Curso de PHP5.
<a href="contactos.html">Volver</a>
</p>
</body>
</html>
Eliminamos un contacto.
Debemos no solo eliminar los ficheros que muestren información del contacto sino
también modificar el listado de contactos, eliminando las lineas correspondientes.
Modificamos un contacto.
Si queremos hacer algún cambio en el aspecto visual de nuestro sitio web, hay que
tener en cuenta que cada cambio tenemos que realizarlo en cada página.
Hay alternativas como las hojas de estilo en cascada (CSS), pero hay situaciones en
las que la apariencia se refiere a cómo se muestra la información, (como tablas, listas
etc.) y las CSS no evitan que cada cambio conlleve una gran cantidad de trabajo.
¿Mantenimiento?
¿Trabajo?
¿Posibilidad de errores?
¿Actualización engorrosa?¿Ver contactos por lugar de trabajo?¿Agrupar
contactos?¿Hacer búsquedas?
¿Mantenimiento de un aspecto uniforme?
¿Necesidades de acceso?
¿Posibilidades de la web dinámica?
- Evaluación:
Contenido html exclusivamente.
El contenido no cambia.
Tenemos tantas páginas web como contactos más el índice.
La interacción con el usuario se limita a mostrar las páginas web
según se navega por el sitio.
Para añadir un contacto tenemos que crear una nueva página y
subirla al servidor.
Para eliminar un contacto debemos acceder al servidor y eliminar el
archivo que contiene la información del contacto.
Para modificar la información de algún contacto, obtenemos la página
del contacto, la modificamos y la devolvemos al servidor.
Si modificamos el aspecto de la presentación de un contacto, el resto
no cambia, por lo que podemos encontrarnos muchas presentaciones
diferentes.
Muchos cambios provocan muchos problemas.
Muy difícil de mantener y actualizar.
Página 9 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Descripción PHP.
Página 10 de 164
Kinética Mobile Development Curso de PHP5.
• Una vez que el servidor web ha enviado de vuelta la página web generada al
cliente, PHP ya no interviene.
• Si la página contiene algo de Javascript, éste se ejecuta en el cliente y está
totalmente desconectado del programa PHP que ha generado la página.
o Repaso de HTML.
Etiquetas principales.
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<BR/>
<P></P>
<TABLE>
<TR><TD></TD></TR>
</TABLE>
</BODY>
</HTML>
URL
• Get
• Variables en una URL.
http://www.ejemplo.com?variable1=valor1&variable2=valor2
Formularios.
</FORM>
Atributo READONLY y DISABLED.
o Taller 1. Primer contacto con PHP. Uso con formularios. (Ver anexo)
Página 11 de 164
Kinética Mobile Development Curso de PHP5.
■ Se mezcla html con lenguajes de programación o scripts de alto nivel como PHP.
■ Una página inicial puede mostrar un índice con la lista de todos los contactos
(pej. 100 enlaces), pero mientras en una página estática hay que cambiarlo todo
a mano en la dinámica se puede generar a partir de un origen de datos.
■ Una sola página se usa para mostrar cada contacto, pero no una página html
por contacto, sino una en PHP para todos. En este caso, de forma automática,
se obtienen los datos del contacto y se muestran.
■ Las páginas se generan acorde a las instrucciones de esos scripts, por lo que se
reduce enormemente el tamaño de la página, así como el número de páginas. Lo
que antes tenía en 100 paginas web en html ahora lo tengo en 1.
■ Puedo crear páginas dinámicas con scripts que me permitan crear, eliminar y
modificar la información de la fuente de datos, teniendo actualizada la
información en todo momento y evitando modificar a mano el contenido del sitio
web.
■ La interacción con el usuario es total, ya que el usuario puede enviar información
para consultar o manipular los datos de la fuente de informacion.
Página 12 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Características generales.
<?php
?>
Resultado:
<?php
echo "¡Hola";
?>
<?php
Página 13 de 164
Kinética Mobile Development Curso de PHP5.
echo "¡Hola";
?>
PHP también ignora los espacios en blanco entre los comandos y los
parámetros.
<?php
echo"Sin espacios";
?>
echo number_format(285266237);
ECHO Number_Format(285266237);
Echo number_format(285266237);
eChO NUMBER_FORMAT(285266237);
Comentarios.
• Por línea:
o Comienzan con //.
o PHP tambien soporta # (Perl).
Página 14 de 164
Kinética Mobile Development Curso de PHP5.
// inicia un comentario
echo 'http://www.elpuchero.com';
echo 'http://www.elpuchero.com/menu.php#cena';
- Pollo al chilindrón
- Revuelto de ajetes
*/
*/
Cadenas de texto.
echo 'pollo';
Página 15 de 164
Kinética Mobile Development Curso de PHP5.
echo '06520';
El resultado será:
Resultado:
Mostrará:
echo '<ul>
<li>Filete de ternera</li>
<li>Ensalada especial</li>
<li>Cocktail de Mariscos</li>
</ul>';
Resultado:
<ul>
<li>Filete de ternera</li>
<li>Ensalada especial</li>
<li>Cocktail de Mariscos</li>
</ul>
Página 16 de 164
Kinética Mobile Development Curso de PHP5.
Tambien podemos usar las comillas dobles, que funcionan de forma similar a
las simples, pero añaden más caracteres especiales:
Caracter Significado
La mayor diferencia entre ambos tipos de acotados es que con las comillas
dobles podemos incluir en la cadena directamente una variable dibujando su
valor, algo que no ocurre con las simples:
$nombre='Florencio';
Resultado:
Vota $nombre
Vota Florencio
echo 'Harpo ' . ' Chico ' . ' Zeppo ' . ' y Groucho';
panfruta
Manipulando texto.
• Validando.
Página 17 de 164
Kinética Mobile Development Curso de PHP5.
$codigoPostal = trim($_POST['codigoPostal']);
$codigoPostal_longitud = strlen($codigoPostal);
if ( $codigoPostal_longitud != 5 ) {
• Formateando.
Página 18 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
Resultado:
Carmele Marchante
El resultado será:
acordarme...
echo str_replace('{clase}',$mi_clase,
'<span class="{clase}">Cochinillo</span>
<span class="{clase}">Bacalao al ajoarriero</span>');
Si $mi_clase es ‘comida’:
Página 19 de 164
Kinética Mobile Development Curso de PHP5.
Números.
echo 56; 56
echo 56.3; 56.3
echo 56.30; 56.3
echo 0.774422; 0.774422
echo 16777.216; 16777.216
echo 0; 0
echo -213; -213
echo 1298317; 1298317
echo -9912111; -9912111
echo -12.52222; -12.52222
echo 0.00; 0
Operadores Aritméticos.
echo 2 + 2; 4
echo 17 - 3.5; 13.5
echo 10 / 3; 3.3333333333333
echo 6 * 9; 54
echo 5 % 6; 5
Variables.
$platos = 5;
$cena = 'Solomillo a la pimienta';
$precioCena = 8.95;
$precioComida = $cost_of_dinner;
$cabeceraPagina = “
<html>
<head><title>Menú</title></head>
<body bgcolor="#fffed9">
<h1>Cena</h1>”;
$piePagina= “
</body>
</html>”;
Los nombres de variable tienen que empezar con una letra o un caracter de
subrayado. El resto puede ser cualquier carácter excepto los que coincidan
con algunos usados por PHP.
Aceptables No aceptables
$longitud $2maso
$bebida $numero-bebidas
$miBebida $bebdor@botellon.com
$_bebidas $bebe!mucho
$bebida 4mas2 $cena+bebida
<?php
$precio = 3.95;
$impuestos = 0.08;
$totalImpuestos = $precio * $impuestos;
$precioTotal = $precio + $totalImpuestos;
Página 20 de 164
Kinética Mobile Development Curso de PHP5.
$usuario= 'juan';
$dominio = '@cursophp.com';
$email = $usuario. $dominio;
?>
El resultado es:
Combinaciones:
///////////////////////////////////////
$usuario = 'juan';
$dominio = '@cursophp.com';
///////////////////////////////////////
// Restamos otro
--$restoEdad;
$email = 'florencio@analista.soy';
echo "Enviar mensaje a: $email";
Resultado:
Enviar mensaje a: florencio@analista.soy
$tituloPagina = 'Menú';
$carne = 'Cerdo';
$vegetal = 'Frijones';
echo "
<html>
<head><title>$tituloPagina</title></head>
<body>
<ul>
<li> $carne barbacoa
<li> $carne en lonchas
<li> $carne brasa con $vegetal
</ul>
</body>
Página 21 de 164
Kinética Mobile Development Curso de PHP5.
</html>";
Nos muestra:
<html>
<head><title>Menú</title></head>
<body>
<ul>
<li> Cerdo barbacoa
<li> Cerdo en lonchas
<li> Cerdo brasa con Frijones
</ul>
</body>
</html>
Ejercicios.
<? php
??>
Solución:
Solución:
$hamburguesa = 4.95;
$helado = 1.95;
$refresco = .85;
$comida = 2 * $hamburguesa + $helado + $refresco;
$descuento = $comida * .16;
$iva = $comida * .075;
$total = $comida + $iva - $descuento;
echo "El precio total de la comida es $total €";
3. Modifica la solución al ejercicio anterior mostrando una factura con formato. Para cada
elemento de la comida dibuja el precio, la cantidad y el total. Imprime la cantidad a descontar, la
cantidad de IVA y el precio total.
Solución:
4. Escribe un programa en PHP que ponga las variables $nombre y $apellidos con tu valores.
Muestre una cadena con tu nombre y apellidos separados por un espacio. Muestra también la
longitud de la cadena.
Solución:
$nombre = 'Juan';
$apellidos = 'Sanchez Sanchez';
$nombreYapellidos = "$nombre $apellidos";
echo $nombreYapellidos;
echo strlen($nombreYapellidos);
Página 22 de 164
Kinética Mobile Development Curso de PHP5.
$i = 1; $j = 2;
echo "$i $j";
$i++; $j *= 2;
echo "$i $j";
$i++; $j *= 2;
echo "$i $j";
$i++; $j *= 2;
echo "$i $j";
$i++; $j *= 2;
echo "$i $j";
Página 23 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Decisiones en PHP.
Usando elseif:
if ($entradaValida) {
// Esto solo se muestra si $entradaValida es true
echo "Bienvenido a bordo, mari … nero";
} elseif ($nuevosMensajes) {
// Este se ejecuta si $entradaValida es false pero $nuevosMensajes es true
echo "Intruso. Hay nuevos mensajes.";
} elseif ($emergencia) {
// Esto se ejecuta si $entradaValida y $nuevosMensajes son false
// y si $emergencia es true
echo "No tiene nuevos mensajes pero hay una emergencia.";
} else {
// Esto se ejecuta si $entradaValida, $nuevosmensajes y $emergencia son false
echo "No te conozco, no tiene mensajes y y no hay ninguna emergencia.";
}
o Decisiones complicadas.
Igualdad.
if ( $mensajesNuevos == 10 ) {
echo "Tienes 10 mensajes nuevos.";
}
if ( $mensajesNuevos == $maxMensajes) {
echo "Tienes el buzon lleno… cafre!";
}
if ( $cena == 'Escalopines') {
echo "¿Ein? ¿otra vez?";
}
Desigualdad.
if ( $mensajesNuevos != 10 ) {
echo "No tiene 10 nuevos mensajes.";
}
if ( $cena != 'Escalopines') {
Página 24 de 164
Kinética Mobile Development Curso de PHP5.
Menor y mayor.
if ( $edad > 17 ) {
echo "Demasiado jóven para ver a Nacho Vidal en acción.";
}
if ( $edad >= 65 ) {
edad "ATENCIÓN: Más de 3 viagras pueden provocar la ira.";
}
if ( $temperatura <= 0 ) {
echo "Cuando el grajo vuela bajo hace un frío del carajo.";
}
Resultado:
La cadena "x54321" no es mayor que la cadena "x5678".
La cadena "54321" es mayor que la cadena "5678".
La cadena "6 paquetes" no es menor que la cadena "55 tarjetas".
La cadena "6 paquetes" es menor que el número 55.
Usando strcmp()
Con strcmp() nos aseguramos que la comparación sea por órden alfabético.
strcmp($cadena1, $cadena2)
if ( $x > 0 ) {
echo 'La cadena "x54321" es mayor que la cadena "x5678".';
Página 25 de 164
Kinética Mobile Development Curso de PHP5.
} elseif ( $x < 0 ) {
echo 'La cadena "x54321" es menor que "x5678".';
}
$x = strcmp("54321","5678");
if ( $x > 0 ) {
echo 'La cadena "54321" es mayor que la cadena "5678".';
} elseif ( $x < 0 ) {
echo 'La cadena "54321" es menor que la cadena "5678".';
}
if ( $x > 0 ) {
echo 'La cadena "6 paquetes" es mayor que la cadena "55 tarjetas".';
} elseif ( $x < 0 ) {
echo 'La cadena "6 paquetes" es menor que la cadena "55 tarjetas".';
}
Negación.
// La expresión entera ($terminado == false)
// es true si $terminado es false
if ($finished == false) {
echo 'Aun no terminado.';
}
if (! strcasecmp($nombre,$apellido)) {
echo '$nombre y $apellido son iguales.';
}
Operadores lógicos.
if (($edad >= 13) && ($edad < 65)) {
echo "Eres demasiado viejo para descuento de niños y
demasiado joven para descuento por jubilado. ";
}
o Repeticiones en PHP.
While.
$i = 1;
echo “<select name=’personas’>”;
Página 26 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
<select name="personas">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
For:
echo “<select name=’personas’>”;
for ( $i = 1; $i <= 10; $i++ ) {
echo "<option>$i</option>";
}
echo “</select>”;
Resultado:
<select name="donuts">
<option> 1 - 10</option>
<option>11 - 20</option>
<option>21 - 30</option>
<option>31 - 40</option>
<option>41 - 50</option>
</select>
Ejercicios.
1. Sin usar PHP para comprobarlo, determinar si estas expresiones son true
or false:
Solución:
a. 100.00 - 100 a. false
b. "cero" b. true
c. "false" c. true
d. 0 + "true" d. false
e. 0.000 e. false
f. "0.0" f. true
g. strcmp("false","False") g. true
Solución:
Página 27 de 164
Kinética Mobile Development Curso de PHP5.
Solución:
$ini_fahr = -50;
$fin_fahr = 50;
echo “<table>”;
echo “<tr><th>Fahrenheit</th><th>Celsius</th></tr>”;
while ($ini_fahr <= $fin_fahr) {
$celsius = ($fahr - 32) * 5 / 9;
echo "<tr><td>$fahr</td><td>$celsius</td></tr>";
$fahr += 5;
}
echo '</table>';
echo “<table>”;
echo “<tr><th>Fahrenheit</th><th>Celsius</th></tr>”;
for ($fahr = -50; $fahr <= 50; $fahr += 5) {
$celsius = ($fahr - 32) * 5 / 9;
echo "<tr><td>$fahr</td><td>$celsius</td></tr>";
}
echo '</table>';
Página 28 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Arrays en PHP.
Los arrays se utilizan para almacenar datos, en la forma indice -> valor.
Indice Valor
manzana verde
limon amarillo
patata marron
berenjena negro
Un array solo puede contener un elemento por clave, es decir, la clave no se puede
repetir.
Un índice de array sólo puede ser un numero o cadena.
Un valor de un array puede ser una cadena, un número, true, false e incluso otro
array.
Crear arrays.
Para crear un array de forma simple solo hay que asignar un valor a un índice del
array.
Página 29 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
Yo quiero Ensalada de Manzana y Pollo al Limón.
o Manipulando arrays.
Resultado:
Hay 3 platos para cenar.
Resultado:
<table>
<tr><td>desayuno</td><td>Catalana</td></tr>
<tr><td>almuerzo</td><td> Cocido de Garbanzos </td></tr>
<tr><td>aperitivo</td><td>Patatas Fritas</td></tr>
<tr><td>cena</td><td> Ensalada Mixta </td></tr>
</table>
Resultado:
El nuevo precio de Catalana es 2.00 €.
El nuevo precio de Cocido de Garbanzos es 9.90 €.
Página 30 de 164
Kinética Mobile Development Curso de PHP5.
$cena = array(' Ensalada de Manzana ', ' Pollo al Limón ', ' Callos en salsa ');
foreach ($cena as $plato) {
echo "Puede comer: $plato";
}
Resultado:
Puede comer: Ensalada de Manzana
Puede comer: Pollo al Limón
Puede comer: Callos en salsa
Resultado:
Plato número 0 es Ensalada de Manzana
Plato número 1 es Pollo al Limón
Plato número 2 es Callos en salsa
// Esto es true
if (array_key_exists(' Gambas al ajillo ',$menu)) {
echo "Si, tenemos Gambas al Ajillo ";
}
// Esto es false
if (array_key_exists('Pepito de Ternera',$menu)) {
echo "Tenemos Pepitos de Ternera";
}
// Esto es true
if (array_key_exists(1, $libros)) {
echo "El elemento 1 es Cocina tradicional extremeña.";
}
Página 31 de 164
Kinética Mobile Development Curso de PHP5.
// Esto es true
if (in_array('Cocina tradicional extremeña', $libros)) {
echo "Tenemos el libro Cocina tradicional extremeña ";
}
Resultado:
Página 32 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Modificar Arrays
echo 'Has comido ' . $platos[' Pollo al Limón '] . ' platos de Pollo al Limón.';
Resultado:
Podemos incluirlos pero si el índice es texto no usamos las comillas para identificarlo.
$dieta['desayuno'] = 'Tostada Media Manchega';
$dieta['almuerzo'] = 'Guiso de Lentejas';
$cantidades= array(2, 1);
Resultado:
Esto no es lo mismo que poner el valor del elemento a 0 o a vacío, sino que se elimina
realmente el indice y el valor, no apareciendo al recorrerlo o al contarlo.
Esta función combina todos los elementos de un array en una cadena separados por
un carácter delimitador.
Resultado:
Página 33 de 164
Kinética Mobile Development Curso de PHP5.
$letras = array('A','B','C','D');
echo implode('',$letras);
Resultado:
ABCD
implode( ) puede ser útil para crear filas en una tabla HTMl.
Resultado:
<table>
<tr><td> Bonito en Salsa </td><td> Filete de Ternera </td><td> Tiramisu</td></tr>
</table>
Es la función inversa a implode( ). Divide una cadena en partes que componen un array
Resultado:
El segundo pescado es Carpa
o Arrays Multidimensionales
Página 34 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
Con for( )
$especiales =
array( array('Tarta de Queso','Bizcocho de Nueces','Bizcocho de Almendras'),
array('Ensalada con Almendras','Ensalada con Nueces', ‘Ensalada con Avellanas’));
Resultado:
o Ordenando Arrays
Se debe usar sólo en arrays con índices numéricos porque reinicia los índices cuando
ordena.
Página 35 de 164
Kinética Mobile Development Curso de PHP5.
sort($cena);
sort($dieta);
Resultado:
Antes de ordenar:
$cena: 0 Ensalada de Manzana
$cena: 1 Pollo al Limón
$cena: 2 Callos en salsa
$dieta: desayuno Donuts
$dieta: almuerzo Solomillo a la Pimienta y Macedonia
$dieta: aperitivo Cacahuetes
$dieta: cena Ensalada Mixta
Después de ordenar:
$cena: 0 Callos en salsa
$cena: 1 Ensalada de Manzana
$cena: 2 Pollo al Limón
$dieta: 0 Cacahuetes
$dieta: 1 Donuts
$dieta: 2 Ensalada Mixta
$dieta: 3 Solomillo a la Pimienta y Macedonia
Página 36 de 164
Kinética Mobile Development Curso de PHP5.
asort($dieta);
Resultado:
Antes de ordenar:
$dieta: desayuno Donuts
$dieta: almuerzo Solomillo a la Pimienta y Macedonia
$dieta: aperitivo Cacahuetes
$dieta: cena Ensalada Mixta
Después de ordenar:
$dieta: aperitivo Cacahuetes
$dieta: desayuno Donuts
$dieta: cena Ensalada Mixta
$dieta: almuerzo Solomillo a la Pimienta y Macedonia
Ejercicios.
1. Madrid: 3.128.600.
2. Barcelona: 1.605.602.
3. Valencia: 805.304.
4. Sevilla: 704.414.
5. Zaragoza: 649.181.
6. Málaga: 560.631.
7. Murcia: 416.996.
Página 37 de 164
Kinética Mobile Development Curso de PHP5.
$totalPoblacion = 0;
echo "<table><tr><th>Ciudad</th><th>Poblacion</th></tr>\n";
foreach ($poblacion as $ciudad => $personas) {
$totalPoblacion += $personas;
echo "<tr><td>$ciudad</td><td>$personas</td></tr>\n";
}
echo "<tr><td>Total</td><td>$totalPoblacion</td></tr>\n";
echo "</table>\n";
2. a) Modifica la solución al ejercicio anterior para que las filas en la tabla estén
ordenadas por población. b) Despúes modifica la solución para ordenar por el
nombre de la ciudad.
a)
$totalPoblacion = 0;
asort($poblacion);
echo "<table><tr><th>Ciudad</th><th>Poblacion</th></tr>\n";
foreach ($poblacion as $ciudad => $personas) {
$totalPoblacion += $personas;
echo "<tr><td>$ciudad</td><td>$personas</td></tr>\n";
}
echo "<tr><td>Total</td><td>$totalPoblacion</td></tr>\n";
echo "</table>\n";
b)
$totalPoblacion = 0;
ksort($poblacion);
echo "<table><tr><th>Ciudad</th><th>Poblacion</th></tr>\n";
foreach ($poblacion as $ciudad => $personas) {
$totalPoblacion += $personas;
echo "<tr><td>$ciudad</td><td>$personas</td></tr>\n";
}
echo "<tr><td>Total</td><td>$totalPoblacion</td></tr>\n";
echo "</table>\n";
3. Modifica la solución al primer ejercicio para que la tabla también contenga filas que
almacenen el total de habitantes por comunidad autónoma para cada comunidad
representada en la lista de ciudades.
$comunidadTotal = array( );
$totalPoblacion = 0;
echo "<table><tr><th>Comunidad</th></tr>\n";
Página 38 de 164
Kinética Mobile Development Curso de PHP5.
$totalPoblacion += $poblacion;
// incrementamosel total por comunidad
$comunidadTotal [$com] += $poblacion;
echo "<tr><td>$ciudad</td><td>$poblacion</td></tr>\n";
}
echo "<tr><td>$comunidadTotal[$com]</td></tr>\n";
}
echo "<tr><td>Total</td><td>$totalPoblacion</td></tr>\n";
echo "</table>\n";
4. Para cada uno de los siguientes tipos de información, muestra cómo almacenarlos
en un array y un ejemplo explicativo con varios elementos. Por ejemplo, para el
primer caso, podemos decir “Un array asociativo cuyo índice es el nombre del
estudiante y cuyo valor es otro array asociativo con el curso y un número
identificativo”. Ejemplo:
$estudiantes = array( 'Juan Sánchez Díaz' => array('curso' => '2','id' => 271231),
'Florencio Martinez' => array('curso' => '5', 'id' => 818211));
Un array asociativo cuyo índice es el nombre del elemento y cuyo valor es el número de
elementos en stock.
$stock = array('Cascos' => 5, 'Guantes' => 3, 'Martillos' => 2, 'Linternas' => 6);
c) Comidas escolares de una semana (cada comida se compone de primero, segundo y bebida) y
el coste por dia.
Un array asociativo cuyo índice es el día y cuyo valor es otro array asociativo describiendo
la comida. Este último array tiene un par índice/valor para el precio y un par índice/valor para
cada parte de la comida (primero, segundo y bebida).
Página 39 de 164
Kinética Mobile Development Curso de PHP5.
$familia = array('Bart','Lisa','Homer','Marge','Maggie');
$familia = array( 'Bart' => array('relacion' => 'hermano', 'edad' => 10),
'Lisa' => array('relacion' => 'hermana', 'edad' => 7),
'Homer' => array('relacion' => 'padre', 'edad' => 36),
'Marge' => array('relacion' => 'madre', 'edad' => 34),
'Maggie' => array('relacion' => 'yomisma', 'edad' => 1));
Taller 3. (Ver anexo)
Página 40 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Declarando Funciones.
function paginaCabecera( ) {
Los nombres de función siguen las mismas reglas que los nombres de variables: han de
comenzar con una letra o un caracter de subrayado; el resto pueden ser letras, números o
caracteres de subrayado.
paginaCabecera ( );
echo "</body></html>";
Resultado:
Las funciones pueden ser definidas antes o después de los lugares donde son llamadas.
function paginaCabecera( ) {
echo '<html><head><title>Bienvenid@s a mi sitio web</title></head>';
echo '<body bgcolor="#ffffff">';
}
paginaCabecera( );
echo "Bienvenido, $usuario";
paginaPie ( );
function paginaPie ( ) {
echo '<hr>Gracias por su visita.';
echo '</body></html>';
}
paginaCabecera2('cc00cc');
Resultado:
<html><head><title>Bienvenido a mi sitio web</title></head><body bgcolor="#cc00cc">
Página 41 de 164
Kinética Mobile Development Curso de PHP5.
Si llamamos a la función sin pasarle el parámetro definido, PHP lanza una advertencia
indicando el error. Por ejemplo:
paginaCabecera2( );
El resultado será:
Para evitar esta situación se define el parámetro de la función con un valor por defecto.
Así, si no se pasa ningún parámetro la función siempre tomará el definido por defecto. Los
valores por defecto para los argumentos nunca pueden ser otras variables.
// Esto es incorrecto
function paginaCabeceraMal ($color = $mi_color) {
...
}
Llamamos a la función:
Resultado:
En este caso se tiene que cumplir que todos los parámetros opcionales deben ir después
de los obligatorios.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Página 42 de 164
Kinética Mobile Development Curso de PHP5.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Resultado:
5..4..3..2..1.. ¡boom!
Ahora contador es 5
$numeroAmostrar = numeroFormato(44708964);
echo "La población de España es aproximadamente: $numeroAmostrar";
Resultado:
La población de España es aproximadamente: 44.708.964
Para devolver valores desde la función que creemos usamos la palabra return y el valor
que queremos devolver.
Cuando se está ejecutando una función tan pronto encuentre la palabra return, para la
ejecución y devuelve el valor asociado.
function restauranteCuenta($comida, $impuesto, $servicio) {
$totalImpuestos = $comida * ($impuesto / 100);
$totalServicio = $comida * ($servicio / 100);
$total = $comida + $totalImpuestos + $totalServicio;
return $total;
}
Página 43 de 164
Kinética Mobile Development Curso de PHP5.
} else {
echo "Puedo pagar en efectivo.";
}
Resultado:
Página 44 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
function cenaNormal( ) {
echo "Para cenar hay $cena, o ";
$cena = 'Pollo Kung Pao';
echo $cena;
echo "<br/>";
}
o Variables Globales.
El array $GLOBALS
Hay dos formas de acceder a una variable global desde una función.
La más común es usando el array especial $GLOBALS.
Cada variable global es accesible como un elemento en ese array.
Página 45 de 164
Kinética Mobile Development Curso de PHP5.
function cenaLigera( ) {
$GLOBALS['cena'] = ' Revuelto de Esparragos';
}
echo "Una cena regular sería $cena";
echo "<br/>";
cenaLigera( );
echo "Una cena ligera sería $cena";
Resultado:
Una cena regular sería Bonito en Cebolla
Una cena ligera sería Revuelto de Esparragos
La segunda forma de acceder a una variable global dentro de una función es usando la
palabra clave global.
De esta forma indicamos que la variable a la que se asocia es global.
Resultado:
Ejercicios.
1. Crea una funcion para escribir una etiqueta HTML de imagen <img>. La función debe
aceptar un argumento obligatorio con la URL de la imagen y otros argumentos opcionales
con el texto alternativo alt, altura y la anchura de la imagen.
2. Modifica el ejercicio anterior para que se pase sólo el nombre del fichero como
parámetro URL. Dentro de la función usa una variable global para crear la URL completa
de la imagen. Por ejemplo, si pasamos foto.jpg a la funcion y la variable global contiene
“/imágenes/”, entonces el atributo src de la etiqueta <img> debería ser “/imagenes/foto.jpg”.
Página 46 de 164
Kinética Mobile Development Curso de PHP5.
echo “ width=’$width’”;
}
echo '>';
}
$efectivo = 31;
$menu = 25;
$impuesto = 10;
$servicio = 10;
while(($precio = cuentaRestaurante($menu,$impuesto,$servicio)) < $efectivo) {
$servicio++;
echo "Puedo permitirme un servicio del $servicio% ($precio) <br/>";
}
4. Los colores web como #ffffff y #cc3399 se crean concatenando valores hexadecimales
de color para el rojo, verde y azul. Haz una función que acepte valores decimales para los
parámetros del verde, rojo y azul y devuelve una cadena con el color apropiado para su
uso en la web. Por ejemplo, si los parámetros son 255,0 y 255, devolvería la cadena
#ff00ff. Puedes encontrar util la función dechex().
Página 47 de 164
Kinética Mobile Development Curso de PHP5.
Sesión 9. Formularios.
- Objetivo. Aprender a utilizar los formularios en la web.
- Actividades:
o Variables de Servidor.
El array global $_SERVER contiene varios elementos que pueden ser muy útiles por la
información que nos proporcionan.
$_SERVER[QUERY_STRING]
Por ejemplo:
http://www.ejemplo.com/catalogo/almacen.php?categoria=cocina&precio=5.
Obtendríamos “category=kitchen&price=5”.
$_SERVER[SERVER_NAME]
$_SERVER[DOCUMENT_ROOT]
Es el directorio que contiene las páginas web de mi sitio, en el ordenador que alberga el
servidor web. Si ese directorio es /var/www/ para el sitio web www.ejemplo.com, el URL
http://www.ejemplo.com/catalogo/almacen.php se correspondería con el fichero en el
servidor /var/www/catalogo/almacen.php.
$_SERVER[REMOTE_ADDR]
Es la dirección IP de la máquina del usuario que solicita alguna página a nuestro servidor
web.
$_SERVER[PHP_SELF]
Es la página actual a la que accedemos. Es útil para hacer que un formulario envíe
parámetros a la misma página.
Al principio de cada petición PHP inicializa los arrays globales que almacenan los valores
de cualquier parámetro enviado a través de formulario o pasado en la URL.
Los parámetros de la URL y los de formulario con método get se almacenan en el array
$_GET.
Página 48 de 164
Kinética Mobile Development Curso de PHP5.
En catalogo.php tenemos :
El nombre del elemento tiene que terminar en corchetes [], para que PHP lo trate como un
array.
<form method="POST" action="comer.php">
<select name="comida[ ]" multiple>
<option value="cerdo">Filete de Cerdo </option>
<option value="pollo">Filete de Pollo </option>
<option value="ternera">Filete de Ternera</option>
<option value="cordero">Filete de Cordero</option>
<option value="avestrux">Filete de Avestruz</option>
</select>
<input type="submit" name="Enviar">
</form>
En comer.php tenemos:
<br/>
<?php
foreach ($_POST['comida'] as $seleccion) {
echo "Tu quieres un filete de $seleccion. <br/>";
}
?>
// Muestra el formulario
function muestraForm( ) {
echo “<form method="POST" action="$_SERVER[PHP_SELF]">
Tu nombre: <input type="text" name="miNombre">
<br/>
<input type="submit" value="Enviar">
</form>”;
}
Página 49 de 164
Kinética Mobile Development Curso de PHP5.
// Procesamos formulario
function procesaForm( ) {
echo "Hola, ". $_POST['miNombre'];
}
// Muestra el formulario
function muestraForm ( ) {
echo “<form method=’POST’ action=’$_SERVER[PHP_SELF]’>
Tu nombre: <input type=’text’ name=’miNombre’>
<br/>
<input type=’submit’ value=’Enviar‘>
<input type=’hidden’ name=’_envia_form’ value=’1’>
</form>“;
}
Además hace la lógica principal independiente de los parámetros que pueden cambiar en
un formulario.
Areas de Texto
Página 50 de 164
Kinética Mobile Development Curso de PHP5.
1. ¿Qué aspecto tiene el array $_POST cuando se envia el siguiente formulario con la
tercera opcion seleccionada de la lista desplegable, el primer y último elemento en la
lista de selección múltiple y un 4 introducido en el campo de texto?
Valores de $_POST:
2. Escribe una función procesaForm() que muestre todos los parametros del
formulario enviado y sus valores.
function procesaForm( ) {
echo "<ul>";
foreach ($_POST as $elemento=> $valor) {
echo "<li> \$_POST[$elemento] = $valor</li>";
}
echo "</ul>";
}
Página 51 de 164
Kinética Mobile Development Curso de PHP5.
<?php
$ops = array('+','-','*','/');
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
// El principio del formulario
echo “<form method=’POST’ action=’”.$_SERVER[PHP_SELF].”’>”;
// El primer operando
echo “<input type=’text’ name=’operando1’ size=’5’ value=’”;
echo $_POST['operando1'].”’/>”;
// El operador
echo “<select name=’operador’>”;
foreach ($GLOBALS['ops'] as $op) {
echo '<option';
if ($_POST['operador'] == $op) { echo “ selected=’selected’”; }
echo "> $op</option>";
}
echo '</select>';
// El segundo operando
echo “<input type=’text’ name=’operando2’ size=’5’ value='”;
echo $_POST['operando2'] .”’/>”;
// El boton de envio
echo “<br/><input type=’submit’ value=’Calcular’/>”;
function procesaForm( ) {
if ('+' == $_POST['operador']) {
$total = $_POST['operando1'] + $_POST['operando2'];
} elseif ('-' == $_POST['operador']) {
$total = $_POST['operando1'] - $_POST['operando2'];
} elseif ('*' == $_POST['operador']) {
$total = $_POST['operando1'] * $_POST['operando2'];
} elseif ('/' == $_POST['operador']) {
$total = $_POST['operando1'] / $_POST['operando2'];
}
echo "$_POST[operando1] $_POST[operador] $_POST[operando2] = $total";
}
?>
Página 52 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Introducción
PHP permite separar el código en varios archivos e incluirlo en los programas que
necesitemos, reutilizando así el código generado.
miFoto.php
<?php
define(“ALTO”, 200);
define(“ANCHO”, 200);
?>
<img src=”miFoto.jpg” height=”<?php echo ALTO?>” width=”<?php echo ANCHO?>” />
Según este código tendríamos que repetir la definición de constantes para cada fichero
PHP en el que las utilicemos.
constantes.php
<?php
define(“ALTO”, 200);
define(“ANCHO”, 200);
?>
miFoto1.php
Ahora solo tenemos que incluir el fichero de constantes en cualquier fichero PHP que las
necesite, teniendo disponible todo su código como si estuviese en el archivo en el que se
incluye.
Esto funciona tanto para definición de variables, codigo, definición de funciones, clases,
etc.
Página 53 de 164
Kinética Mobile Development Curso de PHP5.
constantes1.php
<?php
define(“ALTO”, 200);
define(“ANCHO”, 200);
function muestraImagen($img){
echo ”<img src=’$img’ height=’”.ALTO.”’ width=’”.ANCHO.”’ />”;
}
?>
miFoto2.php
<?php
include (“constantes1.php”);
muestraImagen(“miFoto.jpg”);
?>
o include, include_once
include_once(“nombreFichero”);
o require, require_once
Página 54 de 164
Kinética Mobile Development Curso de PHP5.
include (“$archivo”);
o Usar funciones e inclusión de ficheros para obtener las cadenas que muestran
los datos de usuario.
Página 55 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
PHP soporta la mayor parte de los motores de bases de datos más conocidos:
IBM DB2
Informix
Ingres
mSQL
MySQL
Oracle
PostgreSQL
Sybase
ODBC
Existen varios juegos de funciones específico para cada motor de base de datos.
Para aprovechar todas estas características se utiliza la extensión PHP para MySQL
mysqli disponible como parte de PHP 5.0.
Página 56 de 164
Kinética Mobile Development Curso de PHP5.
- Usuario: Debe existir una cuenta de usuario válida para acceder a la base de
datos.
Vamos a crear un archivo que contenga las variables necesarias para acceder a nuestra
base de datos y así, poder incluirlo en aquellos ficheros PHP que lo necesiten:
config.php
<?php
$servidor = “localhost”;
$usuario = “admin”;
$clave = “secreto”;
$bd = “cursoPHP5”;
?>
Página 57 de 164
Kinética Mobile Development Curso de PHP5.
include(“config.php”);
Las funciones para conectar con la base de datos no son las mismas para todos los
motores de bases de datos, aunque tienen un formato similar.
$conexion = mysql_connect($servidor,$usuario,$clave);
$baseDatos = mysql_select_db($bd, $conexion);
Procedimental
$conexion = mysqli_connect($servidor,$usuario,$clave);
$baseDatos = mysqli_select_db($bd,$conexion);
Oracle:
Página 58 de 164
Kinética Mobile Development Curso de PHP5.
Id * Nombre Precio
1 Patatas 10.00
2 Manzanas 5.00
3 Tomate 3.00
4 Limon 2.00
o phpMyAdmin
Podemos crear nuestra base de datos desde PHP pero es más útil y rápido usar este tipo
de entornos tanto para la creación, como la modificación y administración de nuestras
bases de datos MySQL.
Patatas
Manzanas
Tomate
Limon
Resultado:
// array numerico
while ( $fila = $resultado->fetch_array())
echo " $fila [ 0 ] , $fila [ 1 ] <br/>"; //echo " $fila[id] , $fila[nombre] <br/>";
Página 59 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
1, Patatas
2, Manzanas
3, Tomate
4, Limon
Registros: 4
Oracle:
$producto = “Jamón”;
$consulta = “INSERT INTO productos (id, nombre) VALUES (null , ’$producto’)”;
$resultado = mysql_query($consulta);
o Cerrando la conexión
Cualquier conexión abierta de base de datos es cerrada cuando finaliza el script PHP.
Página 60 de 164
Kinética Mobile Development Curso de PHP5.
mysql_close ( $conexión );
mysqli_close ( $conexión );
oci_close ( $conexión );
$conexion->insert_id
mysql_insert_id()
SELECT LAST_INSERT_ID( ) ;
Ejercicios.
1. Escribe un programa en PHP que muestra todos los platos de la tabla ordenados por
precio.
Página 61 de 164
Kinética Mobile Development Curso de PHP5.
<?php
require_once “config.php”;
$conexion = mysqli_connect($servidor,$usuario,$clave);
$baseDatos = mysqli_select_db($conexion, $bd);
$consulta=”SELECT nombrePlato,precio FROM platos ORDER BY precio”;
$resultado = $conexion->query($consulta);
if($resultado->num_rows>0){
while ( $plato = $resultado->fetch_array())
echo " - $plato[nombrePlato] ($plato[precio]) <br/>";
}
}
else{
echo “No hay platos disponibles.”;
}
?>
<?php
require_once “config.php”;
$conexion = mysqli_connect($servidor,$usuario,$clave);
$baseDatos = mysqli_select_db($conexion, $bd);
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
// Comienzo del formulario
echo “<form method=’POST’ action=’”.$_SERVER['PHP_SELF'].”’>”;
echo “<table>”;
// El precio
echo “<tr><td>Precio:”;
echo “<input type=’text’ name='precio' id=’precio’>”;
echo “</td></tr>”;
function procesaForm( ) {
global $conexion;
$consulta=”SELECT nombrePlato, precio FROM platos”.
“ WHERE precio >=”.$_POST['precio'];
$resultado = $conexion->query($consulta);
if ($resultado->num_rows> 0) {
while($plato = $resultado->fetch_array()) {
echo "- $plato[nombrePlato] ( $plato[precio] ) <br/>";
}
} else {
echo “No hay coincidencias.”;
}
}
?>
3. Crea un programa que muestre un formulario con una lista desplegable con los nombres
de los platos. Una vez que el usuario haya elegido un plato de la lista y haya enviado el
Página 62 de 164
Kinética Mobile Development Curso de PHP5.
formulario, el programa mostrará toda la información referente a ese plato (Id, nombre,
precio, y si es picante).
<?php
require_once “config.php”;
$conexion = mysqli_connect($servidor,$usuario,$clave);
$baseDatos = mysqli_select_db($conexion, $bd);
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
// Comienzo del formulario
echo “<form method=’POST’ action='”.$_SERVER['PHP_SELF'].”’>”;
echo “<table>”;
// Lista desplegable de platos
echo “<tr><td>Plato:”;
echo “<select name='idPlato' >”;
foreach($GLOBALS['platos'] as $id=>$plato )
echo “<option value=’$id’>$plato</option>”;
echo “</select>”;
echo “</td></tr>”;
function procesaForm( ) {
global $conexion;
$idPlato = $_POST['idPlato'];
$consulta=”SELECT idPlato,nombrePlato, precio, esPicante”.
“ FROM platos WHERE idPlato= $idPlato”;
$resultado = $conexion->query($consulta);
$tabla=$resultado->fetch_array();
if ($resultado->num_rows > 0) {
echo “ ID: $tabla[idPlato] <br/>";
echo " Nombre: $tabla[nombrePlato] <br/>";
echo " Precio: $tabla[precio] <br/>";
echo " Picante: “;
if($tabla[esPicante] == 1)
echo “ Sí ";
else
echo “ No ";
} else {
echo “Ese plato no existe.”;
}
}
?>
Página 63 de 164
Kinética Mobile Development Curso de PHP5.
4. Crea una nueva tabla que almacene información sobre los clientes del restaurante. La
tabla deberá contener la siguiente información: idCliente, nombre, telefono, y el id de su
plato favorito. Escribe un programa que muestre un formulario que permite insertar nuevos
clientes en la tabla. La parte del formulario encargada de seleccionar el plato favorito
deberá ser una lista desplegable con todos los platos. El id del cliente no se creará desde
el formulario sino que será generado automáticamente por la base de datos.
<?php
require_once “config.php”;
$conexion = mysqli_connect($servidor,$usuario,$clave);
$baseDatos = mysqli_select_db($conexion, $bd);
$platos= array( );
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
global $platos;
// Si se ha enviado el formulario, obtenemos los valores enviados para mostrar
if ($_POST['_envia_form']) {
$defecto = $_POST;
} else {
// Si no, no mostramos nada
$defecto = array( );
}
?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<table>
<tr><td>Nombre del Cliente:</td>
<td><input type=’text’ name='nombre' id=’nombre’></td></tr>
<tr><td>Teléfono:</td>
<td><input type=’text’ name=’telefono’ id=’telefono’></td></tr>
<tr><td>Plato Favorito:</td>
<td>
<select name=’platoFavorito’ >
<?php foreach($platos as $indice=>$plato)
echo “<option value=’$indice’>$plato</option>”;
?>
</select>
</td></tr>
<tr><td colspan="2" align="center">
<input type=’submit’ value=’Nuevo Cliente’>
</td></tr>
</table>
<input type="hidden" name="_envia_form" value="1"/>
</form>
<?php
} // El fin del formulario
function procesaForm( ) {
global $conexion;
Página 64 de 164
Kinética Mobile Development Curso de PHP5.
$resultado = $conexion->query($consulta);
// Confirmamos al usuario la inserción
echo “Añadido el cliente $_POST[nombre] a la base de datos.”;
}
?>
Página 65 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
echo date(“d/m/y”);
13/04/07
Como se puede observar la letra ‘d’ indica el día (13), la ‘m’ el mes (04) y la ‘y’ el año con
dos dígitos (07).
La barra inclinada (/) al no ser un carácter que la función date() reconozca, la imprime
como un carácter más.
Página 66 de 164
Kinética Mobile Development Curso de PHP5.
Con la función strftime(), los caracteres a reemplazar van acompañados del carácter de
porcentaje (%) y aunque algunos coinciden con date(), tiene sus propios caracteres de
formato.
echo strftime('%d/%m/%y');
El resultado es el mismo:
13/04/07
En el apartado de referencias al final de este texto se encuentra una tabla con los
caracteres de formato de ambas funciones.
La característica más importante que hace más atractivo el uso de date() sobre strftime()
es que la primera es una función nativa de PHP mientras que la segunda utiliza una
función subyacente del sistema en el que se instala PHP.
Página 67 de 164
Kinética Mobile Development Curso de PHP5.
Resultado:
Todos los parámetros de mktime() son opcionales, de forma que aquellos que omitamos
los completa con la hora actual. Por ejemplo mktime(15,30,0) devuelve las 3:30 p.m. de
hoy.
Cuando quieres obtener una fecha relativa a algun evento concreto se usa strtotime( ).
Solo reconoce descripciones en inglés de momentos concretos y devuelve la fecha
correspondiende.
$ahora = time( );
$despues = strtotime('Thursday',$ahora); // Busca la fecha del próximo martes
$antes = strtotime('last thursday',$ahora); // Busca la fecha del martes anterior
echo strftime("ahora: %d/%m/%Y \n", $ahora);
echo strftime("despues: %d/%m/%Y \n", $despues);
echo strftime("antes: %d/%m/%Y \n", $antes);
ahora: 13/04/2007
despues: 19/04/2007
antes: 12/04/2007
Ejercicios.
Página 68 de 164
Kinética Mobile Development Curso de PHP5.
Hoy es día 13 de abril y el día 294 del año 2007. Son las 07:45 PM (es decir las 19:45).
Para mostrar exactamente lo mismo que el ejemplo utiliza mktime() para obtener la marca
de tiempo correspondiente al 13 de abril de 2007 a las 7:45 p.m.
$marca = mktime(19,45,0,10,20,2004);
echo strftime(“Hoy es día %d de %B y el día %j del año %Y. Son las %I:%M %p
(es decir las %H:%M).”, $marca);
$marca = mktime(19,45,0,10,20,2004);
echo “Hoy es día “.date(“d”,$marca).” de “.date('F',$marca).” y día “. (date(“z”,$marca)+1);
echo “ del año “.date(“Y”,$marca.”. Son las “.date(“h:i A”,$marca);
echo “ (es decir las “.date(“H:i”,$marca).”).”;
3. Crea una tabla que muestre la fecha en la que cae el último domingo de mayo desde el
2007 al 2020.
echo “<table>”;
echo “<tr><th>Year</th><th>Elecciones</th></tr>”;
for ($anio = 2007; $anio <= 2020; $anio++) {
// Obtenemos la fecha del 1 de mayo del año $anio
$marca = mktime(12,0,0,6,1,$anio);
// Avanzamos hasta el primer domingo
$marca = strtotime('last sunday', $marca);
echo "<tr><td>$anio</td><td>";
echo date('F j', $marca);
echo "</td></tr>\n";
}
echo '</table>';
Página 69 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
El elemento de formulario <input type="file"> nos permite subir a nuestro servidor web
todo el contenido de un fichero.
Cuando un formulario enviado incluye entre sus elementos uno de tipo file, PHP
proporciona acceso al fichero subido a través del array global $_FILES.
if ($_POST['_enviado']) {
if ($formErrores = validaForm( )) {
muestraForm($formErrores);
} else {
procesaForm( );
}
} else {
muestraForm( );
}
function validaForm( ) {
$errores = array( );
if (($_FILES['miFichero']['error'] == UPLOAD_ERR_INI_SIZE)||
($_FILES['miFichero']['error'] == UPLOAD_ERR_FORM_SIZE)) {
$errores[ ] = “El tamaño del archivo es demasiado grande.”;
} elseif ($_FILES['miFichero']['error'] = = UPLOAD_ERR_PARTIAL) {
$errores[ ] = 'La subida del fichero ha sido interrumpida.';
} elseif ($_FILES['miFichero']['error'] = = UPLOAD_ERR_NO_FILE) {
$errores[ ] = 'No hay ficheros para subir. ';
}
return $errores;
}
function procesaForm( ) {
echo "Has subido un archivo llamado {$_FILES['miFichero']['name']} ";
echo " de tipo {$_FILES['mFichero']['type']} que tiene un tamaño de ";
echo "{$_FILES['miFichero']['size']} bytes.";
echo “{$_FILES['miFichero']['name']}”;
$ficheroDestino = '/var/www/cursoPHP5/ficheros/imagen.jpg';
$ficheroOrigen=$_FILES['miFichero']['tmp_name']; // La ruta de almacenamiento temporal
// del fichero subido en el servidor
if (copy ($ficheroOrigen, $ficheroDestino)) {
echo "Fichero subido como $destination_file.";
} else {
echo "No ha sido posible subifr el fichero.";
}
}
Página 70 de 164
Kinética Mobile Development Curso de PHP5.
Página 71 de 164
Kinética Mobile Development Curso de PHP5.
Página 72 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Activando sesiones.
Una cookie identifica un cliente particular para un servidor web y un intérprete PHP. Cada
vez que un cliente hace una solicitud envía una cookie con esa solicitud. PHP lee la cookie
e identifica que la petición viene del mismo cliente web que hizo otras peticiones antes con
la misma cookie.
El inconveniente de las cookies es que sólo almacenan un valor para cada cookie.
Cuando queremos almacenar más información son más útiles las sesiones.
Una sesión usa una cookie para distinguir entre cada usuario y almacena una pila temporal
de datos para cada usuario en el servidor.
Los datos permanecen durante las peticiones, de forma que en una solicitud podemos
añadir una variable a la sesión de usuario y en una posterior podemos recuperarla sin
problemas.
Página 73 de 164
Kinética Mobile Development Curso de PHP5.
Cuando iniciamos una sesión en una página, PHP comprueba la presencia de esta cookie
y la inicializa si no existe.
session_start( );
$_SESSION['contador'] = $_SESSION['contador'] + 1;
echo "Has visitado esta página " . $_SESSION['contador'] . ' veces.';
Resultado:
Página 74 de 164
Kinética Mobile Development Curso de PHP5.
A medida que vayamos visitando la página sin cerrar el navegador y sin cerrar la sesion
explícitamente con PHP iremos viendo como se incrementa el contador:
...
session_start( );
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
echo “<form method=’POST’ action=’".$_SERVER['PHP_SELF']."’>”;
echo “ Plato: <select name=’dish’>”;
foreach($GLOBALS[‘platosPrincipales’] as $indice=>$plato)
echo “<option value=’$indice’> $plato</option>”;
echo “ </select><br/>“;
echo “Cantidad: <input type=’text’ name=’cantidad’ value=’$POST[cantidad]’>”;
echo “<br/>”;
echo “<input ytpe=’submit’ value=’Enviar’>”;
echo “<input type=’hidden’ name=’_envia_form’ value=’1’/>”;
echo “</form>”;
}
function procesaForm( ) {
$_SESSION['orden'][ ] = array('plato' => $_POST['plato'],
'cantidad' => $_POST['cantidad']);
echo “Gracias por su pedido.”;
} ?>
Los datos de sesion no están restringidos a cadenas y números como las cookies.
<?php
session_start( );
Página 75 de 164
Kinética Mobile Development Curso de PHP5.
if (count($_SESSION['orden']) > 0) {
echo “<ul>“;
foreach ($_SESSION['orden'] as $orden) {
$platoNombre = $platosPrincipales [ $orden['plato'] ];
echo "<li> $orden[cantidad] de $platoNombre </li>";
}
echo "</ul>";
} else {
echo "No has pedido nada.";
}
?>
Ese html es una sección de la respuesta que además contiene las cabeceras o headers,
que están situadas antes del html.
Estas cabeceras no se utilizan para mostrar algo en nuestra web sino para indicar ciertas
órdenes o incluir información útil para el navegador.
Todas las cabeceras de la respuesta del servidor web han de estar al principio de la
respuesta, antes del cuerpo de la página, que es donde html controla lo que se muestra en
el navegador. Si se envía algo del cuerpo, aunque sea una línea e incluso un espacio, ya
no es posible enviar más cabeceras.
Página 76 de 164
Kinética Mobile Development Curso de PHP5.
Para eliminar una variable de sesión es necesario utilizar unset(), al igual que cualquier
otra variable.
Ejercicios.
1. Crea una página web que use una variable de sesión que almacene el número de veces
que un usuario ha visto la página. Debe mostrar :
Número de vistas: 1.
Número de vistas: 2.
...
session_start( );
$_SESSION['contador'] = $_SESSION['contador'] + 1;
echo "Número de vistas: " . $_SESSION['contador'] . “.”;
2. Modifica la página web del primer ejercicio para que muestra un mensaje especial para
la vez quinta, décima y décimo quinta. Para la vigésima vez elimina la sesión y comienza
de nuevo.
<?php
session_start( );
$contadorPag = $_SESSION['contador'] + 1;
if ($contadorPag == 20) {
// un valor vacío elimina la variable
session_destroy();
echo "Comenzamos de nuevo.";
} else {
$_SESSION['contador']= $contadorPag;
echo "Número de vistas: $contadorPag";
if ($contadorPag == 5) {
echo "<br/> Ésta es tu quinta visita.";
} elseif ($contadorPag == 10) {
echo "<br/> Ésta es tu décima visita.";
} elseif ($contadorPag == 15) {
echo "<br/> Ésta es tu décimo quinta visita.";
}
}
?>
Página 77 de 164
Kinética Mobile Development Curso de PHP5.
3. Escribe un programa PHP que muestra un formulario que permita al usuario elegir un
color de una lista. Crea otra página cuyo color de fondo se establezca al color elegido por
el usuario. Almacena el valor del color en $_SESSION para que ambas páginas puedan
utilizarlo.
<?php
session_start( );
$colores = array( '#ff0000' => 'rojo',
'#ff6600' => 'naranja',
'#ffff00' => 'amarillo',
'#0000ff' => 'verde',
'#00ff00' => 'azul',
'#ff00ff' => 'purpura');
if ($_POST['_envia_form']) {
procesaForm( );
} else {
muestraForm( );
}
function muestraForm() {
echo “<form method=’POST’ action=’".$_SERVER['PHP_SELF']."’>”;
echo “Color: <select name=’color’>“;
foreach($GLOBALS[‘colores’] as $indice=>$color)
echo “<option value=’$indice’>$clor</option>”;
echo “</select><br/>”;
echo “<input type=’submit’ value=’Selecciona Color’>”;
echo “<input type=’hidden’ name=’_envia_form’ value=’1’/>”;
echo “</form>”;
}
function procesaForm( ) {
$_SESSION['color'] = $_POST['color'];
echo "Tu colo favorito es: " . $GLOBALS['colores'][ $_SESSION['color'] ];
}
?>
color.php
<?php
session_start( );
echo “<html>
<body bgcolor=’$_SESSION[color]’>
Esta página tiene tu color de fondo personalizado.
</body>
</html>”;
?>
Página 78 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Introducción.
La POO necesita una forma diferente de pensar al crear nuestras aplicaciones, nos
acercamos con código a tareas, procesos e ideas del mundo real.
Con la POO modelamos nuestra aplicación como un conjunto de objetos que colaboran
entre sí y realizan de forma independiente ciertas actividades.
Cuando se construye una casa los carpinteros no necesitan saber si los circuitos de una
habitación son de 10 o 20 amperios. Sólo necesitan conocer lo relacionado con su
actividad. Un contratista se asegura que cada subcontratista termine su trabajo para
terminar la obra pero no le interesan los detalles particulares de cada tarea.
La POO es similar ya que cada objeto oculta a los demás los detalles de su
implementación. Cómo haga cada uno su trabajo es irrelevante para el resto de
componentes del sistema. Lo interesante es el servicio que cada objeto es capaz de
proveer.
Ventajas de la POO
Página 79 de 164
Kinética Mobile Development Curso de PHP5.
Una clase Persona bien hecha puede ser facilmente copiada de un proyecto a otro
con alguno o ningún cambio, ofreciendonos toda la funcionalidad desarrollada
previamente. Esta es otra de los grandes beneficios de la POO, la reutilización de
código entre proyectos.
o Conceptos de POO
• Clases: son el molde de un objeto donde reside el código que define las
propiedades y los métodos.
• Objetos: son instancias concretas de una clase que contienen toda la información
necesaria para que nuestra aplicación funcione.
• Polimorfismo: permite definir una clase como miembro de mas de una categoría
de clases ( tal como un coche es “una cosa con motor” y “una cosa con ruedas”)
Página 80 de 164
Kinética Mobile Development Curso de PHP5.
Clases
Un coche puede acelerar, parar, poner el interminente para indicar un giro y hacer sonar el
claxon. Estos son sus comportamientos.
Estas características y comportamientos son comunes a todos los coches. Aunque unos
coches pueden tener distinto color, todos tienen un color.
Utilizando el concepto de CLASE la POO permite establecer la idea de coche como algo
con todas esas características.
Una clase es una unidad de código, compuesto de variables y funciones, que describen las
características y comportamientos de todos los miembros del conjunto.
Un clase llamada Coche describiría las propiedades y métodos comunes a todos los
coches.
Las propiedades tienen un nombre y un valor. Algunas permiten que su valor cambie y
otras no.
Por ejemplo, en la clase Coche, podemos tener propiedades como el color y el peso.
Aunque el color del coche se puede cambiar con una mano de pintura, el peso del coche
(sin carga ni pasajeros) es un valor fijo.
Página 81 de 164
Kinética Mobile Development Curso de PHP5.
Algunas propiedades representan el estado del objeto, que son aquellas características
que cambian debido a ciertos eventos pero no son modificables directamente. En una
aplicación que simule el funcionamiento de un vehículo, la clase Coche puede tener una
propiedad llamada velocidad. La velocidad del coche no es un valor que se pueda cambiar
directamente, sino que es un producto de la cantidad de combustible enviada al motor, las
características de funcionamiento de ese motor y el terreno sobre el que el coche se
desplaza.
Algunos métodos actúan sobre datos externos pasados como parámetros, pero también
pueden actúar sobre las propiedades de su objeto, incluso pueden utilizarlas para indicar
acciones realizadas por el método o cambiar el estado del objeto modificando valores
como la velocidad del coche.
Objetos
Podemos pensar en una clase como en un plano para construir un objeto. De la misma
forma que, en la mayoría de los casos, muchas casas se pueden construir con el mismo
plano, podemos crear múltiples instancias de un objeto desde su clase.
Pero el plano no especifica detalles tales como el color de las paredes o el tipo de suelo.
Sólo indica que esos elementos existirán. Las clases funcionan de la misma forma. La
clase define el comportamiento y las características que tendrán los objetos, pero no
necesariamente los valores que tendrán esas características.
Un objeto es una entidad concreta construida usando el plano proporcionado por una
clase. La idea de casa es análoga a una clase. Tu casa es análoga a un objeto de esa
clase.
Página 82 de 164
Kinética Mobile Development Curso de PHP5.
• Una zona de memoria donde cargar el objeto. Esto lo hace PHP automáticamente.
• Los datos para dar valores a las propiedades. Estos datos pueden venir de una
base de datos, un fichero de texto plano, otro objeto o algun otro origen.
Una clase nunca tendrá propiedades con valores o un estado. Solo lo tienen los objetos.
Tenemos que usar el plano para construir la casa antes de empapelar las paredes o
pintarla con gotelé. De igual forma, tenemos que instanciar un objeto de la clase antes de
que podamos interactuar con sus propiedades o invocar sus métodos.
Las clases se manipulan en tiempo de diseño cuando haces cambios en los métodos o
propiedades.
Los objetos se manipulan en tiempo de ejecución cuando los valores se asignan a sus
propiedades y se invocan sus métodos.
Página 83 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
class.Demo.php
<?php
class Demo {
}
?>
Convención de código:
testdemo.php
<?php
require_once('class.Demo.php');
$objDemo = new Demo();
?>
Incluimos el fichero que contiene la clase y creamos con new una nueva instancia de la
clase Demo.
El valor que devuelve esta clausula es una referencia a la instancia que se asigna a una
nueva variable, $objDemo.
Ahora podemos invocar los métodos del objeto y examinar o establecer el valor de sus
propiedades.
Página 84 de 164
Kinética Mobile Development Curso de PHP5.
Aunque la clase no haga nada ni tenga propiedades con las que trabajar, es una forma
válida de definir una clase.
Añadiendo un método.
class.Demo1.php
<?php
class Demo1 {
}
}
?>
testdemo1.php
<?php
require_once('class.Demo1.php');
El operador -> se usa para acceder a todos los métodos y propiedades de nuestros
objetos.
Página 85 de 164
Kinética Mobile Development Curso de PHP5.
class.Demo2.php
<?php
class Demo2 {
public $nombre;
function diHola() {
echo " ¡Hola $this->nombre!";
}
}
?>
Para acceder a esta propiedad usamos el mismo operador que antes -> junto al nombre de
la propiedad.
testdemo2.php
<?php
require_once('class.Demo2.php');
$objDemo = new Demo2();
$objDemo->nombre = ‘Florencio';
$objOtroDemo = new Demo2();
$objOtroDemo->nombre = 'Epi';
$objDemo->diHola();
$objOtroDemo->diHola();
?>
Resultado:
La palabra clave public es usada para indicar que la variable pueda ser usada desde fuera
de la clase.
Algunas propiedades existen sólo para uso interno de la clase, por tanto no deben ser
accesibles desde código externo.
Página 86 de 164
Kinética Mobile Development Curso de PHP5.
El objeto usa la variable $this para obtener información sobre sí mismo, es decir, es una
referencia a sí mismo. Podemos tener múltiples objetos de una clase y como no es posible
conocer de antemano el nombre del objeto, la variable $this nos ayuda a referenciar el
objeto cuestión
En el ejemplo, la variable $this permite a cada objeto acceder a sus propiedades y métodos
sin tener que saber el nombre de la variable que lo representa en la aplicación.
o Protegiendo el acceso
Podemos asignar el valor de una propiedad a cualquier cosa que queramos, tanto a otro
objeto, como a un array de enteros, un manejador de fichero o cualquier otro valor.
Para ello, por convenio, el acceso a las propiedades se hace en forma de funciones que
obtienen y establecen las propiedades de la clase. Se conocen como getters y setters
porque suelen nombrarse como get[nombrePropiedad]() y set[nombrePropiedad]().
class.Demo3.php
<?php
class Demo3 {
private $nombre;
Página 87 de 164
Kinética Mobile Development Curso de PHP5.
Comprobamos en testdemo3.php:
testdemo3.php
<?php
require_once('class.Demo3.php');
$objDemo = new Demo3();
$objDemo->setNombre('Florencio');
$objDemo->diHola();
$objDemo->setNombre(37); // esto mostrará un error
?>
La palabra reservada private protege el código haciéndolo inaccesible desde fuera del
objeto, tanto las propiedades como los métodos
Página 88 de 164
Kinética Mobile Development Curso de PHP5.
Utilizar getter/setters con nuestras propiedades hará mucho más simple cualquier cambio
debido a nuevos requerimientos en el futuro.
o Inicializando Objetos
A veces es necesario obtener cierta información de una base de datos, inicializar algunas
propiedades, etc.
Para ello creamos un método llamado constructor, usual en POO, que permite realizar las
acciones necesarias al instanciar el objeto. En PHP, por norma, se llama __construct(), y
será PHP quien lo invoque automáticamente cuando instanciemos un objeto de la clase.
class.Demo4.php
<?php
class Demo4 {
private $nombre;
function diHola() {
echo "¡ Hola $this->nombre !";
}
}
?>
testdemo4.php
<?php
require_once('class.Demo4.php');
$objDemo = new Demo3(‘Florencio’);
$objDemo->diHola();
?>
Nota: En PHP4, los constructores tenían el mismo nombre que la clase. Con PHP5, para
mantener la compatibilidad hacia atrás, se busca en primer lugar el método __construct() y
si no se encuentra busca un método con el mismo nombre que la clase.
Página 89 de 164
Kinética Mobile Development Curso de PHP5.
o Destruyendo Objetos
Las variables de objeto que creamos se eliminan de la memoria del sistema cuando la
página solicitada se ha terminado de ejecutar o cuando se establece como nula.
Para hacer esto creamos una función llamada __destruct sin parámetros, de forma que
antes de que el objeto sea destruido será llamada automáticamente.
Esto nos permite realizar acciones de última hora como cerrar ficheros o conexiones con
bases de datos.
Página 90 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Herencia.
Aunque son diferentes tipos de vehículos comparten ciertos tipos de características como
el color, fabricante, modelo, año, número de bastidor, etc.
Para asegurar que cada una de estas clases tiene las mismas propiedades podemos
copiar el código que las define en cada fichero que contiene la definición de las clases.
Pero en POO, esto no es necesario, se puede reutilizar código usando un proceso llamado
HERENCIA, que es la habilidad que tiene una clase para asumir los métodos y
propiedades de una clase padre o superclase.
La herencia nos permite definir una clase base, en este caso Automovil, y decir que otras
clases son un tipo de Automovil y que tales clases tienen todas las mismas propiedades y
métodos que tiene Automovil.
Página 91 de 164
Kinética Mobile Development Curso de PHP5.
Solo es necesario que añadamos a la clase Turismo las propiedades y métodos que no se
comparten con el resto de clases que heredan también de Automovil. Es decir, solo
tenemos que definir las diferencias; las similitudes se heredan de la clase base.
Tenemos una ventaja mayor con la herencia. Por ejemplo, tenemos una clase Cliente con
un método comprarAutomovil, que toma un parámetro que es un objeto de la clase
Automovil. Este método imprime la factura y decrementa el stock.
Como todos los Turismos, Furgonetas y MiniVolumenes son Automoviles, podemos pasar
objetos de estas clases al método que espera un Automovil. Como heredan de Automovil,
estas tres clases contienen las mismas propiedades y métodos base. Siempre que
necesitemos trabajar con métodos o propiedades comumes a todos los Automoviles,
podemos aceptar objetos de cualquier clase que hereden de Automovil.
o Herencia en PHP.
Consideremos el ejemplo de los felinos. Todos los felinos comparten las mismas
actividades. Comen, duermen, escupen bolas de pelo y cazan. También comparten
propiedades como el peso, color, longitud de pelo y velocidad en carrera.
Sin embargo, los leones tienen melena y rugen. Los guepardos tienen manchas. Los gatos
domésticos no tienen ninguna de estas cosas, pero los tres son felinos.
En PHP se especifica que una clase es una subclase de otra usando extends.
Si tuviesemos que diseñar una aplicacion para gestionar los animales de un zoo,
necesitaríamos una clase Felino, Leon y Guepardo.
Antes de escribir código vamos a planificar nuestra jerarquía de clases con diagramas
UML, para tener algo sobre lo que trabajar. (Más adelante veremos un poco de UML)
Página 92 de 164
Kinética Mobile Development Curso de PHP5.
Este diagrama de clases contiene una clase padre Felino con dos subclases: León y
Guerpardo que heredan de Felino.
class.Felino.php
<?php
class Felino {
public $peso; // en kg
public $color;
public $longitudPelo;
public $velocidadCarrera; // en km/h
Esta clase establece los métodos y propiedades comunes a todos los felinos.
class.Leon.php
Página 93 de 164
Kinética Mobile Development Curso de PHP5.
<?php
require_once('class.Felino.php');
public $longitudMelena; // en cm
testLeon.php
<?php
include('class.Leon.php');
$objLeon = new Leon();
$objLeon->peso = 200; // kg
$objLeon->color = 'marron';
$objLeon->longitudMelena = 36; // cm
$objLeon->comer();
$objLeon->rugir();
$objLeon->dormir();
?>
class.Casa.php
class Casa {
testCasa.php
<?php
include('class.Leon.php');
include('class.Casa.php');
Página 94 de 164
Kinética Mobile Development Curso de PHP5.
?>
class.Guepardo.php
<?php
require_once('class.Felino.php');
public $numeroManchas;
testFelinos.php
<?php
require_once('class.Guepardo.php');
o Sobrescribiendo Métodos.
Heredar de una clase padre no significa que la clase hija tenga que usar la implementación
que la clase padre hace en un método.
Página 95 de 164
Kinética Mobile Development Curso de PHP5.
Por ejemplo, si necesitamos crear un programa que calcule el area de diferentes figuras
geométricas y tenemos clases como Rectangulo y Triangulo, ambas pueden heredar de
una clase padre llamada Poligono.
La clase Poligono puede tener una propiedad llamada numeroLados y un método llamado
getArea.
Todos los polígonos tienen un area calculable, solo que la forma de calcularla varía con los
diferentes tipos de polígonos.
Una función que tenga como parámetro un Poligono y necesite mostrar el area de ese
polígono llamará al método getArea() de la subclase de Poligono que le pasemos
(Rectangulo o Triangulo).
class.Rectangulo.php
Página 96 de 164
Kinética Mobile Development Curso de PHP5.
<?php
class Rectangulo {
public $alto;
public $ancho;
class.Cuadrado.php
<?php
require_once('class.Rectangulo.php');
Cuando queremos solo añadir cierta funcionalidad al método que hemos heredado,
llamamos en primer lugar al método de la clase padre y a continuacióna añadimos nuestro
código.
class.Cliente.php
<?php
class Cliente {
public $id;
Página 97 de 164
Kinética Mobile Development Curso de PHP5.
public $numeroCliente;
public $nombre;
$datos = array();
$datos['numeroCliente'] = 1000000;
$datos['nombre'] = 'Florencio Analista';
class.PremioCliente.php
<?php
require_once('class.Cliente.php');
class PremioCliente extends Cliente {
parent::__construct($clienteID);
if($this->clienteNumero == 1000000) {
echo "¡Felicidades $this->nombre! " .
"¡Eres el cliente un millón! " .
"¡ Has ganado un cepillo de dientes! ";
}
}
}
?>
testCliente.php
<?php
require_once('class.PremioCliente.php');
$promocionActiva = true;
if ($promocionActiva) {
$objCliente = new PremioCliente (12345);
} else {
$objCliente = new Cliente(12345);
}
bienvenidaCliente($objCliente);
?>
Página 98 de 164
Kinética Mobile Development Curso de PHP5.
- Actividades:
o Interfaces.
Por ejemplo, tanto un tarro como una puerta se pueden abrir y cerrar, sin embargo, no
tienen otro tipo de relación.
Un interfaz es como un contrato entre varios objetos para confirmar que realizan una
determinada función.
Un objeto que implemente este interfaz garantiza a quien lo use que es capaz de realizar
todas las funciones definidas en la interfaz.
Las bicicletas y las pelotas de futbol son cosas totalmente diferentes; sin embargo, un buen
sistema de inventario en un almacen de deportes debe ser capaz de tratar los objetos que
representan estos elementos sin problemas.
interface.Abierto.php:
<?php
interface Abierto {
abstract function abrir();
Página 99 de 164
Kinética Mobile Development Curso de PHP5.
Definirlos como abstractos implica que cualquier clase que implemente este interfaz está
obligado a implementar sus métodos. Si no lo hacemos así PHP producirá un error.
El interfaz Abierto es un contrato con otras partes de la aplicación indicando que cualquier
clase que implemente este interfaz debe propocionar dos métodos, llamados abrir() y
cerrar(), sin parámetros. Con este acuerdo permitimos que muchos objetos diferentes
reconozcan la misma función sin la necesidad de relaciones de herencia entre ellos.
class.Puerta.php
<?php
require_once('interface.Abierto.php');
if($this->_bloqueada) {
echo "No puedo abrir la puerta, está bloqueada.";
} else {
echo "crack...<br>";
}
}
class.Tarro.php
<?
require_once('interface.Abierto.php');
private $contenidos;
testAbierto.php
<?php
require_once('class.Puerta.php');
require_once('class.Tarro.php’);
abrirAlgo ($objPuerta);
abrirAlgo ($objTarro);
?>
Tanto Puerta como Tarro implementan el interface Abierto, por lo que podemos pasar sus
objetos a la función abrirAlgo(). Como la función únicamente acepta aquellos objetos que
implementen el interface Abierto, podemos llamar a los métodos abrir() y cerrar(), pero no
podemos acceder a la propiedad $contenidos de Tarro ni a los métodos bloquearPuerta() y
desbloquearPuerta(), porque no forman parte de la interfaz.
o Encapsulación
Los objetos son capaces de ocultar ciertos detalles de su implementación a otros objetos.
Una clase bien diseñada proporciona un escudo completo y presenta un interfaz hacia el
exterior totalmente separada de su parte interna. Haciendo esto obtenemos dos ventajas:
2. Como nada fuera de nuesta clase puede modificar el estado o las propiedades de
un objeto de nuestra clase sin querer, podemos confiar en que el estado del objeto
y el valor de sus propiedades son válidos.
Tanto las propiedades como los métodos de una clase tienen visibilidad, es decir, pueden
ser referenciadas o no desde fuera.
Los miembros protegidos solo son visibles para las subclases que heredan de nuestra
clase.
Los miembros públicos son utilizables por cualquier código, dentro o fuera de la clase.
Por lo general, todos las propiedades internas de la clase deben ser declaradas como
privadas.
Cualquier acceso a estas variables desde fuera de la clase debe ser hecho a través de
métodos de acceso (getters/setters).
- Actividades:
o Contexto.
Un cliente de una discográfica ha contactado con nosotros para desarrollar un sistema web
para gestionar las bandas de sus clientes.
1. Debe permitir a los usuarios web ver detalles de las diferentes bandas que la
compañia representa y conocer sus próximos conciertos.
Las personas que intervienen en la reunión son Juan, el propietario de la empresa; Silvia,
la gerente; y Florencio, un administrativo de la empresa.
Esa persona puede ser alguien que realiza de forma manual el proceso que se intenta
automatizar, o alguien que conoce cómo funciona el negocio y qué necesita nuestro
software para modelar correctamente algun proceso de ese negocio. Esta persona se
suele llamar Experto en el Dominio.
Volvamos a nuestra entrevista. Observamos que Silvia es quién habla la mayor parte del
tiempo. Describe cómo espera ella que el sistema funcione y cómo maneja la empresa
actualmente esos procesos. Por tanto, podemos determinar a Silvia como nuestra Experta
en el Dominio. Durante las siguientes reuniones contactaremos directamente con ella. Juan
no está atento durante la entrevista y es interrumpido constantemente por el móvil para
atender asuntos de alto nivel de la empresa. Florencio solo aclara que el será la persona
responsable de introducir la información en nuestro sistema.
2. Los usuarios pueden ver información acerca de las próximas actuaciones que pueden
incluir una o varias bandas.
Los diagramas de casos de uso muestran el sistema desde el punto de vista del usuario.
Un caso de uso representa una tarea que el usuario intenta realizar con el sistema.
Este es un diagrama de caso de uso simple que muestra que los usuarios visitan el sitio
web Triunfitos y navegan consultando la información de las bandas.
La línea indica que este actor puede realizar ese caso de uso.
El caso de uso Navegar Información Bandas es bastante general. Para empezar, en este
caso, no es necesario mayor nivel de detalle.
Ahora cubriremos todos los casos de uso que nuestro sistema vaya a contemplar.
Los casos de uso administrativos son las tareas separadas que el administrador puede
realizar al usar el sistema Triunfitos.
Como el acceso al sistema puede ser visto como una tarea en sí misma, necesaria para los
casos de uso de administración, podemos usar un include para indicar que ese caso de
uso es parte de los otros tres casos.
Como tanto el administrador como los usuarios normales pueden consultar la información
de las bandas, ambos comparten ese caso de uso.
Además, el caso de uso incluirá un actor no humano, el sistema de reserva, que realiza la
tarea de actualizar la información acerca de las próximas actuaciones.
Los dos diagramas siguientes completan los casos de uso del sistema Triunfitos.
o Diagramas de Clases
Modelando el Dominio
En nuestra aplicación, los usuarios pueden ver información sobre los diferentes tipos de
músicos.
Sería una buena idea tener una clase Musico, o incluso mejor, un interface Musico que
todos los tipos de músicos puedan implementar.
Musico
- tipo : String
- nombre : String
- apellidos : String
La caja de arriba muestra el nombre de la clase. - nombreBanda :
String
+ getBanda() : String
+ getNombre() : String
+ getTipo() : String
La caja del medio muestra sus atributos y la de abajo los + setBanda()
métodos. + setTipo()
+ setNombre()
El signo más indica que los métodos son públicos. Si alguno de los métodos devuelve un
valor, se indica después de los dos puntos.
class.Musico.php
class Musico
{
private $apellidos;
private $nombre;
private $nombreBanda;
private $tipo;
function __construct($apellidos, $nombre, $tipoMusico) {
$this->apellidos = $apellidos;
$this->nombre = $nombre;
$this->tipo = $tipoMusico;
}
Relaciones
Como Triunfitos necesita varias clases, necesitamos conocer cómo interactúan entre ellas.
En nuestro ejemplo usamos cadenas de texto para los tipos de las propiedades y métodos
de nuestra clase.
Esta no es una buena idea. Si un músico fuese parte de una banda, querremos conocer
algo más acerca de la banda además de su nombre. Por ejemplo, los otros componentes
de la banda, el genero de música que tocan, etc.
Estas ideas nos ayudan en el diseño. Cuando se nos presentan ciertos elementos
variables que necesitan mayor grado de complejidad es necesario que tengan sus propias
clases.
Asociaciones
En ocasiones no es necesario mostrar todos los atributos y métodos de una clase, sino
sólo lo relevante en el contexto .
La línea que conecta las dos clases es un tipo de relación conocida como asociación.
Para este ejemplo, la asociación es de uno-a-muchos (1 a *), una Banda puede tener
muchos Musicos, o muchos Musicos pueden estar en una Banda.
En el ejemplo, la línea sin flechas muestra que nos podemos mover en ambas direcciones,
es decir, una navegabilidad bidireccional. Es decir, cada clase tiene una referencia interna
a la otra.
Si la asociación nos permite navegar en una sola dirección, se trata de una navegabilidad
unidireccional.
Realizaciones y Generalizaciones
La realización se dibuja como una línea discontinua con una punta de flecha vacia.
Los interfaces en UML son parecidos a los diagramas de clases pero se incluye la palabra
interface entre comillas españolas.
Cuando queremos mostrar herencia desde una clase abstracta o regular usamos la
generalización, que es idéntica a la realización pero con línea contínua.
Composiciones
A menudo, las relaciones entre clases no están basadas en las asociaciones o la herencia
sino en la forma en la que se agrupan las clases.
La nueva notación de las líneas con un diamante negro indica que Bateria es una
composición de clases Tambor y Platillo.
Una composición es una relación estricta que se caracteriza por dos elementos:
La notación para la agregación es la misma que para la composición pero el diamante está
vacío.
Implementación
ejemplo122.php
<?php
interface Banda {
public function getNombre();
public function getGenero();
public function nuevoMusico(Musico $musico);
public function getMusicos();
}
interface Musico {
public function nuevoInstrumento(Instrumento $instrumento);
public function getInstrumentos();
public function asignarAbanda(Banda $banda);
public function getTipoMusico();
}
interface Instrumento {
public function getNombre();
public function getCategoria();
}
function __construct($nombreBanda) {
$this->nombreBanda = $nombreBanda;
$this->musicos = array();
$this->generoBanda = "rock";
}
function __construct($nombre) {
$this->nombre = $nombre;
$this->categoria = "guitarra";
}
// Probar Objetos
$banda = new BandaRock("Los Variables");
$bandaMiembroA = new Guitarrista("Juan", "Float");
$bandaMiembroB = new GuitarristaPrincipal("Tommy", "Integer");
$bandaMiembroA->nuevoInstrumento(new Guitarra("Gibson Les Paul"));
$bandaMiembroB->nuevoInstrumento(new Guitarra("Fender Stratocaster"));
$bandaMiembroB->nuevoInstrumento(new Guitarra("Hondo H-77"));
$banda->nuevoMusico($bandaMiembroA);
$banda->nuevoMusico($bandaMiembroB);
foreach($banda->getMusicos() as $musico) {
echo "Musico ".$musico->getNombre() . "<br>";
echo "es el " . $musico->getTipoMusico() . "<br>";
echo "en la banda de " . $musico->getBanda()->getGenero();
echo " conocida como " . $musico->getBanda()->getNombre() . "<br>";
foreach($musico->getInstrumentos() as $instrumento) {
echo "Y toca la " . $instrumento->getCategoria() . " ";
?>
Vemos como no es necesario saber con qué tipo de Musico o Instrumento estamos
tratando antes de llamar a sus métodos. Como se siguen las reglas definidas en la
interface sabemos que los objetos responderán apropiadamente.
- Actividades:
o Diagramas de Actividad.
Silvia mencionó en la reunión que la aplicación Triunfitos, al añadir una nueva actuación,
necesitará enganchar con otros dos sistemas de terceros: el sistema de entradas y el
sistema de reserva de locales.
Para comprender el orden en el que tienen que realizarse las diferentes tareas podemos
dibujar lo que se conoce como diagrama de actividad.
Los diagramas de actividad son muy recomendables en aquellas situaciones en las que es
necesario comprender el flujo de las actividades que tienen lugar en un caso de uso.
En este ejemplo, el caso de uso es la reserva de una actuación por parte del administrador
de Triunfitos.
Conversaciones posteriores con Silvia revelaron que el sistema no solo tendrá que enviar
un mensaje al sistema de reservas del local, sino que también necesita recibir información
de ambos sistemas.
El sistema de locales enviará una confirmación de que el local está disponible y el sistema
de entradas devolverá cierta información tal como el precio.
Los diagramas de actividad comienzan con un círculo negro, llamado punto de inicio.
Desde ahí el flujo del proceso sigue las flechas, llamadas transiciones, hacia los
rectángulos redondeados que representan actividades.
Después de la decisión, una barra negra (fork) divide el flujo en dos actividades diferentes.
Los tres grandes rectángulos (calles o carriles) dividen el diagrama en las actividades
particulares de cada sistema. Aunque los carriles no son obligatorios, ayudan a clarificar el
diagrama cuando están implicados varios sistemas.
El diagrama termina en un circulo doble negro que indica la finalización de las actividades.
o Diagramas de Secuencia
Triunfitos tiene una jerarquía de clases. Las Bandas contienen Musicos que tienen
Instrumentos que pueden estar compuestos por otros instrumentos.
Podemos considerar las llamadas a métodos como un tipo de mensaje que un objeto envía
a otro.
Por ejemplo, si una instancia de Banda necesita conocer qué Instrumentos tocan sus
Musicos, enviará un mensaje llamando al método getInstrumentos() de todos sus Musicos.
Es útil visualizar cómo los mensajes se mueven entre los objetos. Para ello UML
proporciona el diagrama de secuencias.
Para el caso de uso “buscar instrumentos por banda’’, el diagrama de secuencia debería
mostrar todos los objetos implicados y los mensajes pasados entre ellos para realizar la
tarea.
La linea discontinua que desciende de cada objeto es la línea de vida del objeto.
El rectángulo vertical muestra la activación del objeto, es decir, el tiempo durante el cual el
objeto está implicado en la ejecución de una operación concreta.
Las flechas indican mensajes. Se nombran con el nombre de método correspondiente del
objeto. Siguiendo los mensajes la secuencia es como sigue:
o Diagramas de Estado.
Los diagramas de estado son muy útiles cuando queremos mostrar los cambios que
soporta un objeto durante su vida.
Los cambios de estado pueden ser desde simples diferencias en las propiedades hasta
cosas más complejas como sondear esperando una respuesta de una fuente externa.
En Triunfitos, la clase Actuacion tiene una vida que podemos documentar con un diagrama
de estados.
Cuando se crea un nuevo objeto Actuacion, éste debe contactar con el sistema de reserva
de locales y esperar una confirmación. Si la respuesta confirma la reserva, se almacena la
actuación en la base de datos. Si no se acepta la reserva, el objeto Actuacion informa al
sistema y es destruido.
Para indicar alguna información extra, como que el estado de esperando confirmación se
mantiene como máximo un minuto, se utiliza una Anotación o Nota. Este elemento se
puede utilizar en cualquier diagrama UML para aclarar algún concepto.
Los diagramas de componentes proporcionan una visión abstracta de alto nivel de nuestro
software.
Elementos técnicos como un servidor web forman parte de otro diagrama UML llamado
diagrama de despliegue.
En la figura, los cubos se denominan nodos. Los nodos identifican piezas separadas del
hardware físico o, conceptualmente, como sistemas separados de software como un
servidor web.
Las flechas discontinuas son dependencias. La parte web de Triunfitos (GUI) depende de
la aplicación Triunfitos en el servidor web, pero no al contrario.
Las líneas continuas muestran una conexión entre nodos, como, por ejemplo, el navegador
web comunicándose sobre HTTP.
Los círculos pequeños son un tipo de atajo para mostrar un interface. Como vimos
anteriormente, nuestra aplicación tiene un interface único llamado Sistema que todos los
clientes tienen que utilizar.
La empresa que maneja el sistema de reservas nos ha pasado una lista de métodos
públicos que podemos usar. No necesitamos nada mas para trabajar con este sistema de
reservas, solo necesitamos conocer los métodos del API que nos pasan.
ANEXO.
Cuando pasamos un programa PHP al intérprete, éste presta atención únicamente a la parte
del contenido que se encuentra entre las etiquetas de inicio “<?php” (en algunos casos la
abreviada “<?”) y fin “?>” de PHP.
Todas las páginas escritas en PHP se identifican con la extensión “.php”.
Cualquier elemento que se encuentra fuera de esas etiquetas será dibujado sin modificaciónes.
Esto hace fácil embeber pequeños trozos de código PHP que mayoritariamente contienen
HMTL, aunque lo aconsejable es no mezclar.
<html>
<head>
<title>PHP dice hola</title>
</head>
<body>
<b>
¡Hola Mundo!
</b>
</body>
</html>
<html>
<head>
<title>PHP dice hola</title>
</head>
<body>
<b>
<?php
echo "¡Hola Mundo!";
?>
</b>
</body>
</html>
La salida es:
<html>
<head>
<title>PHP says hello</title>
</head>
<body>
<b>
Hello, World!
</b>
</body>
</html>
• Una de las mayores fuentes de información para los programas en PHP es el mismo usuario
que visita nuestro sitio.
• El navegador muestra un formulario, el usuario introduce información y pulsa el botón enviar, el
navegador envía esa información al servidor y éste finalmente lo pasa al intérprete PHP donde
es finalmente accesible por tu aplicación PHP.
Ejemplo 3.2. Fichero en PHP diHola.php que muestra el saludo dependiendo del nombre introducido en
el formulario.
<?php
echo "Hello, ";
// Muestra la información enviada por el formulario en el parámetro ‘usuario’
echo $_POST['usuario'];
echo "!";
?>
Si escribimos Florencio en la caja de texto y enviamos el formulario, nuestro programa dibuja ¡ Hola
Florencio!.
• Observaciones.
o Todas las variables en PHP comienzan con el carácter ‘$’.
o La variable global de PHP $_POST almacena todos los valores enviados por un
formulario con el método POST. Realmente se trata de un array que puede ser
modificado.
<html>
<head>
<title>Mis Contactos</title>
<meta name="AUTHOR" content="PAKO">
</head>
<body>
<center>
<h1>Hola</h1>
<br/>
<p>
Bienvenido/a a su página de contactos.
</p>
<p>
<a href="contactos.html">Entrar</a>
</p>
</center>
</body>
</html>
Vamos a incluir un formulario de bienvenida para introducir el nombre del usuario que accede a
nuestros contactos:
<p>
Por favor, introduzca su nombre de usuario.<br/>
<form action="contactos.php">
Usuario: <input type="text" name="usuario" method=”POST”>
<input type="submit" value="Entrar">
</form>
</p>
Modificamos la página que muestra la lista de contactos para que muestre un mensaje de bienvenida
general. Ésta página ya contiene php (contactos.php):
<?php
echo "Bienvenido/a a la página de contactos.";
?>
• Asignar un número a cada contacto y modificar enlaces para apuntar a una sola página:
contactoDatos.php. Modificamos contactos.php
<p>
<a href="contactoDatos.php?contacto=1">Jennifer Aniston</a>
<br/>
• Fusionar todas las páginas de contactos en una dinámica y aplicar decisiones a la agenda
usando una variable con el número. Creamos contactoDatos.php
<html>
<head>
<title>Mis Contactos</title>
<meta name="AUTHOR" content="PAKO">
</head>
<body>
<center>
<h1>Mis Contactos</h1>
<br/>
<p>
Nombre:
<?php
$contacto=$_GET["contacto"];
if( $contacto == 1 )
echo "Jennifer";
elseif( $contacto == 2)
echo "Manuel";
?>
<br/>
Apellidos:
<?php
if( $contacto == 1 )
echo "Aniston";
elseif( $contacto == 2)
echo "Esparcia";
?>
<br/>
Teléfono:
<?php
if( $contacto == 1 )
echo "924 007 001";
elseif( $contacto == 2)
echo "924 007 002";
?>
<br/>
Correo:
<?php
if( $contacto == 1 )
echo "janiston@edu.juntaex.es";
elseif( $contacto == 2)
echo "mesparcia@edu.juntaex.es";
?>
<br/>
Lugar de Trabajo:
<?php
if( $contacto == 1 )
echo "<img src='janiston.jpg'>";
elseif( $contacto == 2)
echo "<img src='mesparcia.jpg'>";
?>
</p>
<p>
<a href="contactos.php">Volver</a>
</p>
</center>
</body>
</html>
<p>
<a href="contactos.php">Volver</a>
</p>
Así, el mensaje de bienvenida anterior usando la variable usuario no funcionará porque al volver, el
enlace no pasa ninguna variable, por lo tanto será necesario pasarle el usuario a la página
datosContacto.php para luego devolverlo.
<?php
$usuario=$_POST["usuario"];
echo "Hola $usuario. <br/>";
echo "Bienvenido/a a la página de contactos.";
?>
Aun así observamos que tampoco muestra el usuario en el mensaje de bienvenida. Eso es porque
usamos la variable global $_POST pero pasamos la variable en la URL, por lo que tambíen tenemos
que contemplar esta posibilidad. Actualizamos contactos.php:
<?php
if($_POST["usuario"])
$usuario=$_POST["usuario"];
elseif($_GET["usuario"])
$usuario=$_GET["usuario"];
echo "Hola $usuario. <br/>";
echo "Bienvenido/a a la página de contactos.";
?>
• En la página inicial, almacenar la información de los contactos en un array y mostrar la lista con
un proceso repetitivo.
<?php
• Almacenar la información de los contactos en arrays y aglutinar todas las páginas de contactos
en una.
<?php
$contactos= array (array ( 'nombre' => 'Jennifer',
'apellidos' => 'Aniston',
'tfno' => '924 007 001',
'email' => 'janiston@edu.juntaex.es',
'lugar' => 'Secretaría General',
'img' => 'janiston.jpg'),
array ( 'nombre' => 'Manuel',
'apellidos' => 'Esparcia Montoya',
'tfno' => '924 007 002',
'email' => 'mesparcia@edu.juntaex.es',
'lugar' => 'Secretaría General',
'img' => 'mesparcia.jpg'));
?>
<html>
<head>
<title>Mis Contactos</title>
<meta name="AUTHOR" content="PAKO">
</head>
<body>
<center>
<h1>Mis Contactos</h1>
<br/>
<?php
$contacto=$_GET["contacto"];
$usuario=$_GET["usuario"];
$item=$contactos[$contacto];
echo "<p>";
echo "Nombre: {$item['nombre']} <br/>";
echo "Apellidos: {$item['apellidos']} <br/>";
echo "Tfno: {$item['tfno']} <br/>";
echo "Email: {$item['email']} <br/>";
echo "Lugar de Trabajo: {$item['lugar']} <br/>";
echo "<br/>";
echo "<img src='{$item['img']}'/>";
echo "</p>";
?>
<p>
<a href="contactos.php?usuario=<?php echo $usuario;?>">Volver</a>
</p>
</center>
</body>
</html>
• Separamos el array que almacena los datos de usuario en otro fichero: datos.php.
datos.php
<?php
$contactos= array (array ( 'nombre' => 'Jennifer',
'apellidos' => 'Aniston',
'tfno' => '924 007 001',
'email' => 'janiston@edu.juntaex.es',
'lugar' => 'Secretaría General',
'img' => 'janiston.jpg'),
array ( 'nombre' => 'Manuel',
'apellidos' => 'Esparcia Montoya',
'tfno' => '924 007 002',
'email' => 'mesparcia@edu.juntaex.es',
'lugar' => 'Secretaría General',
'img' => 'mesparcia.jpg'));
?>
• Incluimos el fichero de datos en el archivo contactos.php para poder usar esos datos.
• En otro fichero guardaremos las funciones comunes que vamos a usar para mostrar diversos
datos, como por ejemplo el mensaje de bienvenida (hola()) y la lista de contactos
(listaContactos()).
funciones.php
<?php
function hola(){
global $usuario;
$usuario=usuario();
echo "Hola $usuario. <br/>";
echo "Bienvenido/a a la página de contactos.";
}
function usuario(){
if($_POST['usuario'])
return $_POST['usuario'];
elseif($_GET['usuario'])
return $_GET['usuario'];
else return "";
}
function listaContactos(){
global $contactos;
global $usuario;
foreach($contactos as $indice=>$item){
echo "<a href='contactoDatos.php".
"?contacto=$indice&usuario=$usuario'>$item[nombre]</a><br/>";
}
}
function detalleContacto($cont){
global $contactos;
$item=$contactos[$cont];
echo "<p>";
echo "Nombre: $item[nombre] <br/>";
echo "Apellidos: $item[apellidos] <br/>";
?>
<?php
require_once "datos.php";
require_once "funciones.php";
?>
<html>
<head>
<title>Mis Contactos</title>
<meta name="AUTHOR" content="PAKO">
</head>
<body>
<center>
<h1>Mis Contactos</h1>
<br/>
<p>
<?php
hola();
?>
</p>
<p>
<?php
listaContactos();
?>
<br/>
</p>
<p>
Total: <?php echo count($contactos);?> contactos.
</p>
</center>
</body>
</html>
<?php
require_once "datos.php";
require_once "funciones.php";
?>
<html>
<head>
<title>Mis Contactos</title>
<meta name="AUTHOR" content="PAKO">
</head>
<body>
<center>
<h1>Mis Contactos</h1>
<br/>
<?php
$contacto=$_GET["contacto"];
$usuario=$_GET["usuario"];
detalleContacto($contacto);
?>
<p>
<a href="contactos.php?usuario=<?php echo $usuario;?>">Volver</a>
</p>
</center>
</body>
</html>
En primer lugar, el archivo datos.php que contiene el array con los datos ya no es
necesario.
config.php
<?php
funciones.php
<?php
require_once("config.php");
function hola(){
global $usuario;
$usuario=usuario();
echo "Hola $usuario. <br/>";
echo "Bienvenido/a a la página de contactos.";
function usuario(){
if($_POST['usuario'])
return $_POST['usuario'];
elseif($_GET['usuario'])
return $_GET['usuario'];
else return "";
}
function listaContactos(){
global $conexion;
global $usuario;
$lista = array( );
$conexion=conecta();
$consulta="SELECT idContacto,nombre,apellidos FROM contactos";
$resultado = $conexion->query($consulta);
while ($contacto = $resultado->fetch_array()) {
$lista[]=$contacto;
}
foreach($lista as $indice=>$item){
echo "<a href='contactoDatos.php? ".
"contacto=$item[0]&usuario=$usuario'>".
"$item[nombre] $item[apellidos]</a><br/>";
}
}
function detalleContacto($cont){
$conexion=conecta();
$consulta="SELECT * FROM contactos WHERE idContacto=$cont";
$resultado = $conexion->query($consulta);
$contacto = $resultado->fetch_array();
echo "<p>";
echo "Nombre: $contacto[nombre] <br/>";
echo "Apellidos: $contacto[apellidos] <br/>";
echo "Tfno: $contacto[tfno] <br/>";
echo "Email: $contacto[email] <br/>";
echo "Lugar de Trabajo: $contacto[lugar] <br/>";
echo "<br/>";
echo "<img src='$contacto[img]'/>";
echo "</p>";
}
function conecta(){
global $datosConexion;
$conexion = mysqli_connect($datosConexion['servidor'],
$datosConexion['usuario'],
$datosConexion['clave']);
$baseDatos = mysqli_select_db($conexion, $datosConexion['bd']);
return $conexion;
}
function numContactos(){
$conexion=conecta();
$consulta="SELECT * FROM contactos";
$resultado = $conexion->query($consulta);
$num = $resultado->num_rows;
return $num;
}
?>
El archivo que muestra la lista de contactos inicial no varía con respecto al Taller 4,
excepto en la sección que muestra el número de contactos que tenemos registrados.
Para ello usamos la función que hemos añadido en el archivo funciones.php. Otra
forma de hacerlo sería obteniendo ese número aprovechando la consulta que muestra
la lista de contactos.
Comenzamos creando un archivo que contenga un formulario para solicitar los datos
del contacto a insertar.
nuevoContacto.php
<?php
require_once "funciones.php";
$usuario=$_GET["usuario"];
?>
<html>
<head>
<title>Mis Contactos</title>
</head>
<body>
<h1>Mis Contactos</h1>
Nuevo Contacto
<?php
if(!$_POST['_envia_form'])
{
?>
<form action='nuevoContacto.php' method='POST'>
function nuevoContacto(){
$campos= array();
$campos[]=$_POST['nombre'];
$campos[]=$_POST['apellidos'];
$campos[]=$_POST['telefono'];
$campos[]=$_POST['email'];
$campos[]=$_POST['lugar'];
$campos[]=$_POST['imagen'];
$conexion=conecta();
$consulta= "INSERT INTO contactos (idContacto, nombre, apellidos,”.
"tfno, email, lugar, img) VALUES (null, '$campos[0]', ".
"'$campos[1]','$campos[2]','$campos[3]','$campos[4]','$campos[5]')";
$resultado = $conexion->query($consulta);
}
Para modificar un contacto hacemos algo similar a lo hecho para crear uno nuevo.
Creamos un fichero que muestre un formulario con los datos del contacto, ofreciendo la
posibilidad de modificar esa información y enviarla para actualizar la base de datos.
editarContacto.php
<?php
require_once "funciones.php";
$usuario=$_GET["usuario"];
?>
<html>
<head>
<title>Mis Contactos</title>
</head>
<body>
<h1>Mis Contactos</h1>
<p>
Editar Contacto
</p>
<?php
if(!$_POST['_envia_form'])
{
$datos=obtenerDatos($_GET['cont']);
?>
<form action='editarContacto.php' method='POST'>
}
?>
</body>
</html>
En la página de funciones creamos una nueva que nos permita obtener los datos del
contacto a modificar y otra que haga la modificación en la base de datos del contacto
editado.
function obtenerDatos($cont){
$conexion=conecta();
$consulta="SELECT * FROM contactos WHERE idContacto=$cont";
$resultado = $conexion->query($consulta);
return $contacto = $resultado->fetch_array();
}
function modificarContacto(){
$campos= array();
$campos[]=$_POST['idContacto'];
$campos[]=$_POST['nombre'];
$campos[]=$_POST['apellidos'];
$campos[]=$_POST['telefono'];
$campos[]=$_POST['email'];
$campos[]=$_POST['lugar'];
$campos[]=$_POST['imagen'];
$conexion=conecta();
$consulta= "UPDATE contactos set ".
" nombre='$campos[1]'," .
" apellidos='$campos[2]'," .
" tfno='$campos[3]'," .
" email='$campos[4]'," .
" lugar='$campos[5]'," .
" img='$campos[6]'".
" WHERE idContacto=$campos[0]";
$resultado = $conexion->query($consulta);
}
Para eliminar un contacto creamos una página que simplemente nos pida la
confirmación para borrar ese contacto de la base de datos.
eliminarContacto.php
<?php
require_once "funciones.php";
$usuario=$_GET["usuario"];
?>
<html>
<head>
<title>Mis Contactos</title>
</head>
<body>
<h1>Mis Contactos</h1>
<p>
Eliminar Contacto
</p>
<?php
if(!$_POST['_envia_form'])
{
$datos=obtenerDatos($_GET['cont']);
?>
¿Desea eliminar el siguiente contacto?
<br/>
<form action='eliminarContacto.php' method='POST'>
<?php echo $datos['nombre']." ".$datos['apellidos']?>'
<input type='submit' value='Aceptar'>
<input type='hidden' name='idContacto' value='<?php echo $datos['idContacto']?>'>
<input type='hidden' name='_envia_form' value='1'>
</form>
<?php
}
else{
eliminarContacto();
echo "Contacto eliminado.";
}
?>
</body>
</html>
Como en los casos anteriores agregamos una función que nos permita hacer el borrado
del contacto de la base de datos.
function eliminarContacto(){
$contacto =$_POST['idContacto'];
$conexion=conecta();
$consulta = "DELETE FROM contactos WHERE idContacto=$contacto";
$resultado = $conexion->query($consulta);
}
Finalmente, en la lista de contactos, añadimos los enlaces necesarios para poder llevar
a cabo estas acciones. Bastará con incluir al final de cada contacto dos enlaces, uno
para editar y otro para borrar.
funciones.php
function listaContactos(){
global $conexion;
global $usuario;
$lista = array( );
$conexion=conecta();
$consulta="SELECT idContacto,nombre,apellidos FROM contactos";
$resultado = $conexion->query($consulta);
while ($contacto = $resultado->fetch_array()) {
$lista[]=$contacto;
}
echo "<table width='60%'>";
foreach($lista as $indice=>$item){
echo "<tr><td width='90%' style='border-bottom: 1px solid #CCC'>";
echo "<a href='contactoDatos.php?contacto=$item[0] ".
"&usuario=$usuario'>$item[nombre] $item[apellidos]</a>";
echo "</td><td width='5%'style='font-size: 12px'>";
echo "<a href='editarContacto.php?cont=$item[0]'>Editar</a>";
echo "</td><td width='5%' style='font-size: 12px'>";
echo "<a href='eliminarContacto.php?cont=$item[0]'>Borrar</a></td>";
echo "</tr>";
}
echo "</table>";
}
nuevoContacto.php
<?php
require_once "funciones.php";
$usuario=$_GET["usuario"];
?>
<html>
<head>
<title>Mis Contactos</title>
</head>
<body>
<h1>Mis Contactos</h1>
Nuevo Contacto
<?php
if(!$_POST['_envia_form'])
{
?>
<form action='nuevoContacto.php' method='POST' enctype="multipart/form-data">
funciones.php
function nuevoContacto(){
$campos= array();
$campos[]=$_POST['nombre'];
$campos[]=$_POST['apellidos'];
$campos[]=$_POST['telefono'];
$campos[]=$_POST['email'];
$campos[]=$_POST['lugar'];
$campos[]=$_FILES['imagen'][‘name’];
if($_FILES['imagen']) {
subirFichero();
$campos[]=$_FILES['imagen'][‘name’];
}
$conexion=conecta();
$consulta= "INSERT INTO contactos (idContacto, nombre, apellidos,”.
"tfno, email, lugar, img) VALUES (null, '$campos[0]', ".
"'$campos[1]','$campos[2]','$campos[3]','$campos[4]','$campos[5]')";
$resultado = $conexion->query($consulta);
}
function subirFichero( ) {
$ficheroOrigen = str_replace('/', '', $_FILES['imagen']['name']);
$ficheroOrigen = str_replace('..', '', $ficheroOrigen);
$ficheroDestino = '/var/www/cursoPHP5/' . $ficheroOrigen;
if (move_uploaded_file($_FILES['imagen']['tmp_name'], $ficheroDestino)) {
echo "Fichero subido como $destination_file.";
} else {
echo "No ha sido posible subifr el fichero.";
}
}
funciones.php
function modificarContacto(){
$campos= array();
$campos[]=$_POST['idContacto'];
$campos[]=$_POST['nombre'];
$campos[]=$_POST['apellidos'];
$campos[]=$_POST['telefono'];
$campos[]=$_POST['email'];
$campos[]=$_POST['lugar'];
if($_FILES['imagen']) {
subirFichero();
$campos[]=$_FILES['imagen']['name'];
}
$conexion=conecta();
$consulta= "UPDATE contactos set ".
" nombre='$campos[1]'," .
" apellidos='$campos[2]'," .
" tfno='$campos[3]'," .
" email='$campos[4]'," .
" lugar='$campos[5]'," .
" img='$campos[6]'".
" WHERE idContacto=$campos[0]";
$resultado = $conexion->query($consulta);
}
Al eliminar un contacto también tenemos que tener en cuenta la eliminación del archivo
de imagen asociado.
function eliminarContacto(){
$contacto =$_POST['idContacto'];
$conexion=conecta();
$consulta= "SELECT img FROM contactos WHERE idContacto=$contacto".
" and img not like ''";
$resultado = $conexion->query($consulta);
$imagen=$resultado->fetch_array();
unlink("c:\\wamp\\www\\cursoPHP5\\taller\\taller7\\".$imagen[0]);
$consulta="DELETE FROM contactos WHERE idContacto=$contacto";
$resultado = $conexion->query($consulta);
Vamos a variar un poco nuestra aplicación de agenda de contactos para practicar creando un proyecto
en PHP, orientado a objetos y modelado con diagramas UML.
Es importante aclarar que la solución aplicada en este caso es una de las muchas posibles, ya que el
modelado puede variar tanto por los elementos a tener en cuenta como por los diseñadores que lo
lleven a cabo.
Nuestra agenda de contactos maneja datos sobre personas. Vamos a ampliar su espectro hacia la
organización de la Secretaría General de la Consejería de Educación de la Junta de Extremadura.
Por tanto tendremos en cuenta que cada persona trabaja en cero o una sección y que una sección
pertenece a un servicio.
Tanto la sección, como el servicio tendrá, cada uno, un responsable. También tendrán un identificador,
un nombre, una dirección física, una página web, un correo electrónico, un télefono y un fax.
Además los datos de cada contacto son: un identificador, un nombre, apellidos, dirección del trabajo,
dirección personal, teléfono del trabajo, teléfono personal, fax, email del trabajo y email personal.
Esta lista de requisitos, en el análisis, se detalla en más profundidad, obteniendo una lista de requisitos
identificados a los que poder referirnos durante el diseño y que podamos validar con el cliente, una vez
terminada esa fase de diseño.
Antes de nada se debe hacer un análisis de los requisitos y a continuación obtener casos de uso de
alto nivel, tanto en diagramas como en plantillas textuales. Lo que nosotros veremos aquí sería la etapa
de diseño. Tanto el análisis como el diseño se hacen en este taller de forma combinada y con la mayor
brevedad. Existe una metodología de desarrollo de software basada en Métrica v.3 aun en estudio, que
será la utilizada en el desarrollo de cualquier aplicación en la sección de desarrollo del servicio de
informatica de la Consejeria de Educacion. Esta metodología incluye mayor nivel de detalle y
documentación, y utiliza también UML para el modelado.
Con nuestra aplicación de modelado (ArgoUML) vamos a crear un nuevo fichero llamado
AgendaContactos. Aun no tenemos en cuenta cómo almacenamos esos datos de forma permanente,
es decir, el diseño de las tablas en la base de datos. Eso lo retomamos después del modelado en el
apartado del diseño del dominio de la aplicación.
Hemos identificado dos roles o perfiles: uno encargado de crear, modificar y eliminar contactos
(administrador); y otro que solo consulta los contactos (usuario).
Aunque nuestra aplicación no contemple diferencia entre ambos, ya que no hay control de acceso, los
trataremos como tales para ver como interactuan diferentes roles con nuestros casos de uso.
Como vemos, están representadas las asociaciones entre los contactos y las secciones y servicios.
Pero si observamos detenidamente podemos determinar que:
De ambas observaciónes podemos determinar que en lugar de contacto la clase que se refiere a las
personas en sí, se llame, obviamente, Persona y establecemos una nueva clase Contacto que
contenga tanto las propiedades como los métodos comunes a todas las clases. Así, hacemos que esas
clases hereden de la clase Contacto. Esa clase por sí sola no tiene sentido, así que la creamos como
abstracta.
Para indicar además que hay un responsable tanto en Seccion como en Servicio añadimos una
asociación con Persona desde ambas clases.
Para tratar con los datos de la base de datos creamos una clase llamada GestorDatos.
Para que nuestra aplicación funciones de forma que exista un solo punto de entrada, nos creamos una
clase Aplicación, que será con la que tratemos para ejecutar todas las peticiones que necesitemos.
En el caso del nombre de la persona, se sobreescribe la propiedad denominacion, que en este caso
será igual a la concatenación del nombre y los apellidos.
Añadimos un interfaz que indica que todas aquellas clases que lo realicen deben implementar un
método validar(), encargado de la validación de los valores que se establezcan para las propiedades de
esas clases.
Ahora que hemos hecho una primera aproximación a la solución del problema, tenemos que diseñar
cómo almacenar la información en la base de datos MySQL, es decir, el modelo de dominio de la
aplicación.
0..N 0..1
Persona pertenece Seccion
0..N
pertenece
0..1
Servicio
Existe una aproximación que permite relacionar de una forma más directa ambos modelos. Crear cada
clase como encargada de mantener una tabla de la base de datos.
En nuestro caso nos permitiría tener una nueva tabla, Contactos, que almacenaría aquellos campos
comunes a las demás tablas.
Podemos mejorar este diseño combinando las tablas de Sección y Servicio en una única tabla: Unidad.
De forma que aquel registro cuya id_unidadSuperior sea cero indicará que es un servicio y si es distinto
de cero, indica que se trata de una sección y de que unidad (servicio) depende.
Si además, como puede observarse, Contacto tiene una relación de uno a uno con Persona y Unidad,
podemos hacer coincidir la clave de Contacto con la clave de Persona y Unidad.
Si además, desde contactos necesitamos saber de qué tipo de contacto se trata, es decir, si es una
Persona o una Unidad, necesitamos crear un campo tipo en contactos.
Se podría mejorar mucho más hasta hacer que toda esa información provenga de una única tabla, pero
a efectos de mostrar cómo funciona el modelado con UML, dejamos este diseño como válido.
Contacto
Es un
Es un
0..1 0..1
Persona Unidad
0..N
depende
Es
responsable
Estos cambios en el modelo de dominio también pueden afectar a nuestro modelo de diseño de
objetos. Es decir, es posible que nuestras clases se vean condicionadas por el resultado en el modelo
de datos.
Hemos determinado que la clase Aplicación gestione todos los mensajes que podemos pasar a nuestro
programa. Pero nuestra aplicación tiene que tener un comienzo, un punto de entrada. Con el cliente,
hemos confirmado que el caso de uso Listar Contactos sea lo primero que se ejecute al llamar a
nuestro programa.
Según el caso de uso Listar Contactos, tenemos que mostrar una lista de todos los contactos.
Cada elemento de la lista es la denominación del contacto y un enlace para ver la información detallada
del mismo.
Vamos a llegar hasta este punto en el diseño para no extendernos demasiado en el taller.
Continuamos con la fase de implementación en la que también cubriremos sólo hasta este caso de
uso.
Referencias
%P a a.m. o p.m.
001-366 strftime(),
%j z Día del año, numérico. 0-365 date()
%% Carácter %
%t Carácter de tabulación.
[2]
El rango de segundos se extiende a 61 por el salto de segundos.
Imagen 2
Imagen 3
imagen 4
Para crear una nueva tabla introduciremos el nombre que le queramos asignar
y el número de campos (imagen 5).
imagen 5
imagen 6
Imagen 7
Imagen 8
imagen 9
3) Exportar. Desde esta pestaña usted puede exportar de una forma sencilla
sus bases de datos (imagen 10).
Imagen 10
imagen 11
1) Revisar la tabla.
2) Analizar la tabla.
3) Reparar la tabla.
4) Optimizar la tabla.
5) Vaciar caché.