Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2
4 Ámbito de las variables.......................................................................................................24
5 Variables variables...............................................................................................................25
6 Definición de una constante................................................................................................26
7 Constantes predefinidas......................................................................................................27
8 Práctica: Variables...............................................................................................................28
9 Práctica: Constantes............................................................................................................28
Tema 5: Operadores...................................................................................................................29
1 Que son los operadores.......................................................................................................29
2 Operadores de asignación y de concatenación...................................................................29
3 Operadores aritméticos.......................................................................................................30
4 Operadores de comparación...............................................................................................31
5 Operadores lógicos..............................................................................................................32
6 Operadores de incremento-decremento............................................................................33
7 Sentencias Condicionales If, Else-If, Elseif, Else...................................................................33
If, Else.................................................................................................................................34
If, Elseif, Else.......................................................................................................................36
8 Práctica: Mayor de dos números.........................................................................................37
9 Práctica: Carne del polideportivo........................................................................................37
10 Práctica: Valor de variable.................................................................................................38
11 Práctica: Ordenar de menor a mayor................................................................................40
Tema 6: Bucles...........................................................................................................................40
1 Qué es un Bucle...................................................................................................................40
2 Bucle While.........................................................................................................................41
3 Bucle Do While....................................................................................................................42
4 Bucle For..............................................................................................................................42
5 Bucle Foreach......................................................................................................................44
6 Break y Continue.................................................................................................................45
Break..................................................................................................................................45
Continue.............................................................................................................................46
7 Switch..................................................................................................................................46
8 Práctica: Días de la semana.................................................................................................48
9 Práctica: Buscando una letra...............................................................................................49
10 Práctica: Números divisibles entre 5.................................................................................50
11 Práctica: Valores entre dos enteros...................................................................................51
12 Práctica: Tablas de multiplicar...........................................................................................51
Tema 7: Funciones.....................................................................................................................52
3
1 Qué es una Función.............................................................................................................52
2 Cómo se crea una Función..................................................................................................53
3 Cómo se invoca una Función...............................................................................................53
4 Funciones para la gestión de archivos.................................................................................55
Copy...................................................................................................................................55
Rename..............................................................................................................................55
Unlink.................................................................................................................................55
Fopen.................................................................................................................................55
Fgets...................................................................................................................................55
Fwrite.................................................................................................................................55
Fseek..................................................................................................................................55
Feof....................................................................................................................................56
Fpassthru............................................................................................................................56
Fclose.................................................................................................................................56
5 Funciones para la gestión de directorios.............................................................................56
Opendir..............................................................................................................................56
Readdir...............................................................................................................................56
Rmdir..................................................................................................................................56
Mkdir..................................................................................................................................56
Rewinddir...........................................................................................................................56
Closedir..............................................................................................................................56
6 Retorno de valores..............................................................................................................57
7 Práctica: El número mayor..................................................................................................58
8 Práctica: Media aritmética..................................................................................................59
9 Práctica: Listar directorio.....................................................................................................59
Tema 8: Formularios..................................................................................................................60
1 Conocimientos previos........................................................................................................60
2 Campos de entrada de datos...............................................................................................61
3 Cuadro de texto...................................................................................................................61
4 Cuadro de texto con barras de desplazamiento..................................................................62
5 Casillas de verificación.........................................................................................................62
6 Botón de opción..................................................................................................................63
7 Menu desplegable...............................................................................................................63
9 Campo oculto......................................................................................................................64
10 Práctica: Libro de visitas....................................................................................................66
11 Práctica: Cuestionario........................................................................................................67
4
12 Práctica: Formulario de solicitud de información..............................................................70
9: Bases de Datos MySQL I.........................................................................................................72
1 Introducción a MySQL – Front.............................................................................................72
2 Instalando MySQL – Front...................................................................................................73
3 Empezando con bases de datos..........................................................................................73
4 Creación de una base de datos............................................................................................73
5 Creación de tablas...............................................................................................................73
6 Añadir campos a una tabla..................................................................................................73
7 Modificar campos de una tabla...........................................................................................73
8 Borrar campos de una tabla................................................................................................73
9 Operaciones con los registros de una tabla.........................................................................73
10 Editor SQL..........................................................................................................................73
11 Práctica: Realizar una base de datos para clientes............................................................73
Tema 10: Bases de Datos MySQL II............................................................................................74
1 Página principal...................................................................................................................74
2 Conexión con la base de datos............................................................................................75
3 Introducir registros..............................................................................................................76
4 Listado de registros.............................................................................................................78
5 Borrado de registros............................................................................................................80
6 Modificación de registros....................................................................................................82
7 Práctica: Realizar un libro de visitas....................................................................................85
5
Tema 1: Comenzando con PHP
Bienvenidos a esta primera lección, donde nos iremos adentrando en el término PHP, en qué
consiste este lenguaje de programación y, en su todavía breve historia. Trataremos algunas de
sus características más destacadas, de los trabajos en los que puede emplear este lenguaje, y
le enumeraremos una serie de funciones aplicables a la actualidad de los entornos Web, las
cuales le harán elegir PHP frente a otros lenguajes con más antigüedad como el ASP.
1 Historia de PHP
PHP es un lenguaje creado por una gran comunidad de personas sin ánimo de lucro. Este
sistema fue desarrollado en el año 1994 por Rasmus Lerdorf, se trataba de un CGI escrito en
lenguaje C que permitió la interpretación de un número limitado de comandos. En sus
orígenes, el sistema se denominó Personal Home Page Tools y adquirió un éxito reconocido,
puesto que muchas personas solicitaron a Rasmus el uso de sus programas en páginas propias,
demostrando una buena acogida inicial. Tras la aceptación de este primer CGI escrito, Rasmus
Lerdorf diseñó un sistema para procesar formularios, al que denominó Form Interpreter (FI),
dando como resultado de estas dos originarias herramientas, la primera versión del lenguaje
PHP/FI.
A mediados del año 1997, se incluyeron nuevas funcionalidades como el soporte a nuevos
protocolos de Internet, y también el soporte a un gran número de bases de datos comerciales.
Todas estas mejoras consolidaron las bases de PHP versión 3. Los continuos progresos, las
nuevas aplicaciones creadas y el valor de las bases de datos de PHP, convierten a su última
versión en la más competitiva y rápida hasta ahora, dotándola de más independencia que las
anteriores con respecto a los servidores Web.
La programación en PHP, junto con el servidor Web Apache, han sido las dos claves
fundamentales que han cambiado el enfoque de la creación de las últimas aplicaciones Web.
PHP es un lenguaje sencillo y de sintaxis cómoda, y Apache el servidor más utilizado, ya que
está basado en un software de código abierto y que funciona sobre cualquier plataforma. Estas
características los han llevado a ser utilizados por numerosos grupos de adeptos, que lo
emplean a diario en todo tipo de entornos Web alojados desde cualquier parte del mundo.
En Internet, como ejemplos claros de entornos PHP, se pueden encontrar desde las más
simples páginas personales, páginas comerciales con su pequeño proceso de compra-venta
incluido, hasta los complejos sitios Web de las empresas más prestigiosas, que además de
tener puntos de ventas presenciales, se están adaptando a los nuevas tecnologías, ampliando
su campo de comercio a través de las ventas por Internet. Para ello, utilizan los conocidos
carros de la compra y los más avanzados sistemas de seguridad para proteger el pago de sus
productos y los datos personales de sus clientes. Asimismo, están a la orden del día, las
populares páginas de descarga de ficheros (música, imágenes, vídeos, etc.), que se actualizan
rápidamente e identifican a cada uno de sus usuarios gracias a las sesiones en PHP.
6
han optando por adecuar sus contenidos a los nuevos sistemas de enseñanza para Internet,
utilizando la red como soporte para distribuir la formación especializada. Han adaptado sus
materias a los nuevos medios, empleando esto como complemento en algunas asignaturas, e
incluso, impartiendo estudios completos desde las cada vez más conocidas plataformas e-
learning o de teleformación (http://www.uned.es, http://www.us.es, http://www.ucm.es,
http://www.uoc.es entre otras).
2 Significado de PHP
PHP es un lenguaje de programación de estilo clásico, es decir, que utiliza variables, sentencias
condicionales, funciones…
PHP, Hypertext Preprocessor, se define como un lenguaje interpretado de alto nivel, cuyo
código va insertado en las páginas HTML, permitiendo saltar del modo PHP al código HTML
dentro de las mismas. Este lenguaje es ejecutado del lado del servidor, lo cual permite acceder
a los recursos que tiene el servidor, enviando rápidamente los resultados al navegador en
forma de página Web.
Al ser PHP un lenguaje que se ejecuta en el servidor, no es necesario que el navegador soporte
PHP, pero sí es condición imprescindible para que las páginas PHP funcionen correctamente y
que el servidor donde están alojadas soporte PHP.
<? echo'
<html>
<head>
<title>Primera página</title>
<body>
<p> Buenas, me llamo Ana Gessa </p>
</body>
</html>
' ?>
<html>
<head>
<title>Primera página</title>
<body>
7
<p> Buenas,
<?
// Ahora pasamos la misma página a modo PHP
$nombre=”Ana”;
$apellido=”Gessa”;
echo “me llamo $nombre $apellido”;
?>
</p>
</body>
</html>
El servidor Web, al soportar PHP, procesará la página de forma secuencial: desde el principio
hasta el fin; buscando secciones PHP dentro de los delimitadores del código, . En el caso de
que las encuentre, las compila y ejecuta mostrando un resultado idéntico a la página HTML.
Es importante saber que existen dos tipos de lenguajes de programación: del lado servidor y
del lado cliente.
Ambos tienen sus ventajas e inconvenientes. Mientras que el del lado cliente es totalmente
independiente del servidor, permitiéndole a sus páginas que puedan ser abiertas desde
cualquier sitio; los del lado del servidor son independientes del cliente y como consecuencia de
ello son lenguajes menos rígidos y el tiempo que tardan en generar las páginas Web es menor
debido a que son scripts almacenados por quien los ejecuta.
PHP está basado principalmente en lenguajes como C, C++ y Java con los que comparte toda su
sintaxis y semántica, asimilando también características de lenguajes interpretados como Perl
y Bash. A nivel general, las principales diferencias entre PHP y C son:
Podemos encontrar productos similares de otras grandes empresas, como son: Active Server
Pages (ASP), de Microsoft; ColdFusion, de Allaire; y Java Server Pages (JSP), de Sun.
PHP es uno de los lenguajes del lado del servidor más extendidos en Internet en los últimos
años. Ha tenido muy buena aceptación entre los programadores debido a factores tan
determinantes como su gran parecido con C, su potencial y su simplicidad, entre otros. Está
específicamente orientado al desarrollo de páginas dinámicas conectadas a bases de datos,
mostrando así los contenidos de éstas en las llamadas Interface Web. Un ejemplo claro del uso
de PHP con bases de datos son muchas de las páginas con un proceso de compra on-line.
8
3 Características más importantes de PHP
Cabe destacar algunas de las características de PHP, puesto que son las que posicionan a PHP
como uno de los lenguajes de programación más utilizados. Éstas son:
1. Velocidad: Este lenguaje goza de una alta velocidad de ejecución, con lo que evita las
demoras innecesarias en la máquina. Por lo tanto, no necesita muchos recursos del
sistema.
2. Estabilidad: Utiliza un sistema propio de administración de recursos y dispone de un
sofisticado método de manejo de variables, consiguiendo así uno de los sistemas más
robustos y estables de los existentes.
Y por último, cabe acentuar su Conectividad. Es un lenguaje que dispone de una amplia gama
de librerías y agregarle extensiones es muy sencillo. Esto permite que este lenguaje sea
utilizado en áreas muy diversas, como sería la encriptación, gráficos, XML y otras muchas.
Todas estas características, y muchas más que irá identificando a medida que avance en el
curso, le mostrarán una amplia variedad de proyectos realizables con PHP, serán motivos
relevantes para que cuando programe se decante por este lenguaje ante otros a la hora de
trabajar.
Es importante saber que PHP puede ser utilizado en cualquiera de los principales sistemas
operativos del mercado: Linux, variantes de Unix, Microsoft Windows, Mac OS X y algunos
más. Soporta la mayoría de servidores Web actuales, Apache, Personal Web Server, iPlanet,
Caudium, etc. La mayoría de funciones que hacen de PHP uno de los lenguajes de
programación más útiles a la hora de desarrollar son las siguientes:
Tiene acceso y soporta muchas bases de datos: Adabas D, d base, Empress, FiloPro,
IBM DB2, INformix, Ingres, Internase, FrontBase, mSQL, MySQL, ODBC, Oracle,
PostgreSQL, Solid, SYbase, Veloces, UNIX dbm.
Conectividad con otros servicios, usando HTTP, FTP, COM, SNMP, Sockets, LDAP, etc.
Servicios de correo y noticias: POP, IMAP, SNMP, NNTP y derivados.
Creación de textos y gráficos: XML, HTML, XHTM, PDF, GD, Flash.
Funciones matemáticas.
POSIX: memoria compartida, acceso a ficheros, cronómetros…
Comercio electrónico: Cybercash, CyberMUT, Verisign Pro y CCVS para programas de
pago.
Formularios.
Encriptación y compresión: MD5, Gzip, Bzip2…
Con PHP podrá realizar todo aquello que se plantee, desde una simple calculadora, hasta un
calendario, así como pequeñas funciones añadidas a su página Web personal, creación de un
auténtico portal de negocios, donde se pueden vender todo tipo de productos con el carrito de
9
la compra, gestionar de manera segura todos los datos de clientes, sacar las estadísticas de
ventas mensuales…
Para entornos de Windows, los competidores más conocidos son ASP y ColdFusion, la elección
entre uno de ellos se basa en asuntos más técnicos. ASP junto a IIS es probablemente más
estable que PHP con IIS, pero está demostrado que PHP bajo Windows NT es más estable que
los otros dos, además de ser más rápido y utilizar menos recursos.
6 ASP o PHP
Muchos son lo debates abiertos sobre cuál de entre estos dos lenguajes es mejor a la hora de
aplicarlo en trabajos reales. Es un hecho demostrable el imparable ascenso de PHP frente a
otros lenguajes del lado del servidor, y concretamente sobre el ASP “Active Server Pages” de
Microsoft.
Uso libre.
Lenguaje abierto.
Diseñado para la Web.
Multiplataforma.
Multisistema operativo.
Soporte para varios servidores Web.
Soporte nativo para casi cualquier base de datos.
Buena y accesible documentación.
Perfecta integración de Apache + PHP + MySQL.
Modulable.
No depende de un único proveedor de servicios.
Sencillo de aprender y utilizar.
Sintaxis clara y bien definida.
Seguro.
Como desventaja ante el ASP, tiene una peor integración con el paquete Office de
Microsoft.
Errores en seguridad, solucionables antes que en otros sistemas.
10
Puede realizar la instalación individualmente, o bien puede instalar un paquete preconfigurado
como EasyPHP o AppServ, entre otros. Estos paquetes preconfigurados instalan
simultáneamente un servidor Apache y el módulo PHP en cualquier sistema operativo, incluido
Linux y Windows. Más adelante, trataremos detalladamente estos programas.
Una vez instalado todo, cree las páginas PHP y alójelas en su directorio Web, y el navegador
interpretará el código sin necesidad de compilar nada, ni de instalar otras herramientas.
Si lo que realmente desea es alojar sus páginas .php en Internet, existen dos posibilidades:
Alojar las páginas en un servidor gratuito, el cual puede facilitar un espacio limitado,
que llena sus páginas de publicidad variada, y que es posible que no soporte PHP.
Contratar un paquete de alojamiento Web a un proveedor de servicios de Internet
(www.yahoo.es, www.ya.com, www.terra.es…), que soporte este tipo de páginas. Si
desconoce si el servidor incluye esta posibilidad, consulte con su proveedor. Lo mismo
ocurre si desea trabajar con bases de datos MySQL, PostgreSQL, etc.
1 Opciones de instalación
Para usuarios más experimentados en la materia, es posible que deseen realizar la instalación
paso a paso, es decir, instalar el servidor Apache y el módulo PHP individualmente, y
adecuando los ficheros de configuración según sus necesidades.
Nosotros trataremos esta opción por encima, comentando algunos de sus pormenores. Nos
centraremos más en la instalación de un paquete integrado, como EasyPHP, que reúne todo lo
necesario para realizar aplicaciones en PHP con acceso a bases de datos MySQL, sin necesidad
de saber nada de la configuración del servidor Apache o del módulo PHP.
Otras utilidades que pueden servir al programador dependiendo de sus necesidades, son: si el
usuario quiere gestionar las bases de datos directamente sin necesidad de utilizar el código
PHP, deberá instalar un gestor de bases de datos para crear, modificar y borrar las tablas y los
datos con los que trabaje, como phpMyAdmin; algún editor de PHP, como DevPHP y, también
es de gran utilidad, algún manual de PHP y MySQL.
11
6 Uso del directorio www
Para que las páginas creadas sean interpretadas correctamente en su navegador, es
obligatorio que estén guardadas dentro del directorio C:\Archivos de programa\EasyPHP1-
7\www.
Una vez iniciado EasyPHP, el servidor Apache está configurado por defecto, para que la página
que primero abra en el navegador sea el archivo index.htm, index.html o index.php según la
configuración que tenga por defecto. Este archivo se encuentra dentro del directorio www.
Cuando abra el navegador, escriba en la Barra de direcciones http://localhost/, y, si no
tocamos la configuración por defecto, se abrirá automáticamente el fichero index que
tengamos predefinido.
Tenga en cuenta que PHP es un lenguaje bastante flexible, en vez de forzar a una disciplina al
programador, este lenguaje permite mucha libertad a la hora de trabajar, simplemente
siguiendo un mínimo de reglas, para evitar posibles errores, conseguirá programar rápida y
fácilmente.
1 Extensiones
Las extensiones de los ficheros en PHP son muy importantes, ya que el servidor HTTP las
identifica y decide si debe pasarlo al procesador de PHP o no.
Las extensiones que indican que un fichero contiene código en PHP son:
Los métodos más usados son las etiquetas cortas y las de estilo ASP. La primera fórmula solo
funcionará si previamente se han habilitado las etiquetas cortas. Y para que funcione el estilo
ASP, hay que habilitar las etiquetas tipo ASP.
Etiquetas cortas:
12
Etiquetas canónicas:
<script language=”php”>
</script>
Los métodos más usados son las etiquetas cortas y las de estilo ASP. La primera fórmula solo
funcionará si previamente se han habilitado las etiquetas cortas. Esto se consigue a través de
la función short_tags(), habilitando la opción de configuración short_open_tags en el archivo
de configuración de PHP o compilando PHP con la opción enable-short-tags también en la
configuración. Y para que funcione el estilo ASP, hay que habilitar las etiquetas tipo ASP con la
opción de configuración asp_tags.
<html>
<body>
<?php
If ( Hour(time)>20 || Hour(time)<4) {
echo “Buenas noches.”;
} else {
echo “Buenos días.”;
}
?>
</body>
</html>
NOTA: La instrucción echo seguida de una cadena de texto entrecomillada hace que el PHP
escriba en la página Web, mostrada en el navegador, lo contenido en dicha cadena de texto.
Dentro de la cadena de texto que sigue a echo, puede insertar cuantas etiquetas HTML desee.
3 Espacios en blanco
PHP, al igual que HTTP, ignora los espacios en blanco, por lo que resulta equivalente escribir:
$valor=5+4;
//Es lo mismo que escribir:
$valor = 5 + 4;
13
//Y también se puede escribir:
$valor =
5+
4;
4 Separación de instrucciones
En PHP se denominan instrucciones a todo aquel lenguaje recogido dentro de los
delimitadores de código. Es necesario el lenguaje C o Pascal. Cada sentencia se considera
terminada con un punto y coma.
5 Comillas
No podemos pasar esta lección sin mencionar las comillas, ya que conociendo la manera de
actuar que tienen, evitará la aparición de futuros errores innecesarios.
Comillas simples (‘ '): Son las que muestran el contenido tal y como está escrito dentro de la
cadena. Como consecuencia de ello, las comillas simples son más rápidas, puesto que no
pierden el tiempo interpretado. Si queremos almacenar una comilla doble dentro de una
cadena formada por comillas simples, lo podemos hacer sin ningún problema, ya que será
almacenada como un carácter normal.
Comillas dobles (“”): Éstas leen dentro de la cadena en busca de variables a interpretar.
Comillas simples (‘ '): Son las que muestran el contenido tal y como está escrito dentro
de la cadena.
$variable = ‘Podemos almacenar el carácter “ dentro de unas comillas simples y no
ocurre nada'
Comillas dobles (“ ”): Los caracteres que empiezan con la barra invertida (\) son
sustituidos por caracteres especiales y los nombres de variables que comienzan por
“$” son sustituidos por la cadena que almacenan. Los caracteres especiales más
importantes son:
o \$: sustituye dicho carácter por $.
o \”: sustituye dicho carácter por “.
EJEMPLO:
<?php
echo ‘Esto es una cadena normal dentro de unas comillas simples. No paro en leer
lo que contengo, simplemente lo muestro.';
echo “A mí me están leyendo sin pasar nada por alto por si tengo algo que
14
interpretar.”;
?>
NOTA: Como hemos dicho antes, PHP ignora los espacios en blanco. En este caso, sólo respeta,
los que haya en el interior de las comillas, ya sean simples o dobles, puesto que muestra lo que
está escrito tal cual es.
6 Fin de línea
PHP ignora cualquier carácter de espaciado presente en el código, incluyendo espacios,
tabuladores y saltos de línea, a excepción de si se encuentra dentro de una cadena de texto. En
PHP, el fin de una sentencia se marca con punto y coma (;), al igual que en el lenguaje C o en
Pascal.
<?php
?>
7 Construcción de bloques
Aunque en otros lenguajes de programación, como en ASP, no afecta que una misma función o
variable esté escrita en mayúscula o minúscula, ya que siempre será interpretada de la misma
manera. En PHP, un detalle a tener en cuenta es que sí se distingue entre mayúsculas y
minúsculas, puesto que repercute en el resultado final dependiendo del caso:
Ya sabemos, que las sentencias no pueden ser combinadas, así que debemos poner una
sucesión de sentencias agrupadas todas ellas mediante el uso de llaves {}.
Por ejemplo, si queremos que se ejecuten varias sentencias al mismo tiempo, debemos
agruparlas de la siguiente manera:
if ( 5 == 2 + 3 ) {
15
NOTA: Una cosa muy importante es tener en cuenta el sangrado del código, ya que resulta
muy útil a la hora de comprender los programas y quedan mejor estructurados.
8 Líneas de comentarios
Los comentarios son anotaciones dentro del código PHP que sirven para facilitar la
comprensión del código por parte de los lectores, y no se muestran en pantalla porque el
intérprete de PHP lo primero que hace es quitar todos los comentarios del programa.
Los comentarios en PHP están heredados de lenguajes como “C”, “C++” y shell de Unix. Hay
tres maneras de introducir comentarios en el código.
Para comentarios en una sola línea existen dos posibilidades: colocar // o # al comienzo de la
línea.
• /* Comentario estilo C.
Este comentario es multilínea
otra línea más del mismo comentario */
• // Comentarios estilo C++. Son solo para una sola línea y es el más utilizado.
NOTA: Los comentarios son muy útiles para recordar anotaciones referentes al código utilizado
en el momento de programar cada página, así en el futuro, será más fácil recordar la finalidad
de cada parte del código de las páginas PHP para posibles modificaciones y futuras
actualizaciones.
NOTA: Los comentarios estilo C o multilíneas no pueden anidarse, esto suele ocurrir cuando se
comentan grandes bloques de código. Si los anidáramos por equivocación, PHP dará un error.
9 Mayúsculas y minúsculas
Aunque en otros lenguajes de programación, como en ASP, no afecta que una misma función o
variable esté escrita en mayúscula o minúscula, ya que siempre será interpretada de la misma
manera. En PHP, un detalle a tener en cuenta es que sí se distingue entre mayúsculas y
minúsculas, puesto que repercute en el resultado final dependiendo del caso:
<?php
$numero=1947
print “El año elegido es $numero.”; // Mostrará en pantalla: El año elegido es 1947.
16
print “El año elegido es $Numero.”; // Mostrará en pantalla: El año elegido es .
?>
<?php
$numero=1947
print “El año elegido es $numero.”; // Mostrará en pantalla: El año elegido es 1947.
PRINT “El año elegido es $numero.”; // Mostrará en pantalla: El año elegido es
1947.
?>
EJEMPLO:
<HTML>
<HEAD>
<TITLE>Ficheros></TITLE>
<?php
require (“$libdir/conexion.php”);
require (“$libdir /date.php”);
require (“$libdir /carrito.php”);
require (“$libdir /globals.php”);
?>
</HEAD>
<BODY>
<?php
include (“inicio.html”);
?>
// Aquí iría el resto del código HTML y PHP
<php
include (“fin.html”);
?>
</BODY>
</HTML>
17
11 Práctica: Mi primer texto
MI PRIMER TEXTO:
Código:
<?php
echo “Este texto es un ejemplo muy fácil y seguramente lo hagamos bien. Si
no es así, debemos repasar la lección.”;
?>
practica.php
12 Práctica: Include
INCLUDE:
<?php
include(“practica.php”);
?>
practica2.php
Las variables son una parte fundamental en todos los lenguajes de programación. Se definen
como la principal manera de almacenar valores en el medio de un programa. Con las variables
puede realizar operaciones, puede hacer comparaciones entre sí y puede variar el flujo del
programa en función de su valor en ese momento.
Las características más importantes que debe tener siempre presente de las variables son:
18
No necesitan ser declaradas antes de su uso, es decir, no necesitamos decirle al
programa si una variable es una cadena o un número entero, ya que PHP se encargará
de definirla por sí mismo.
No tienen un valor intrínseco, sino que toman el tipo del último valor asignado.
Las variables que se utilizan antes de ser asignadas tienen un valor por defecto.
Las variables hacen distinción entre las mayúsculas de las minúsculas.
EJEMPLO: <?php
$variableCadena = "Variable";
$variableNumero = 57;
$variableDecimal = 8.5;
?>
Referencias
En PHP las variables pueden tener dos o más nombres diferentes para un mismo dato. Para
definir una referencia, se utiliza en carácter “&” delante de la variable referenciada:
$alias = &$variable
Así, se puede acceder al mismo dato de la memoria con $alias o con $variable
indiferentemente. Todas las modificaciones que se hagan sobre una u otra repercuten en el
mismo dato.
Tipos de variables
Mientras que en C++ la declaración de variables se puede realizar en cualquier parte del
programa, no necesariamente al principio del mismo, pero siempre hay que declararlas; en
PHP no es necesario definirlas antes de utilizarlas, si no que van adquiriendo los diferentes
valores que se le dan a lo largo del programa. PHP gestiona las variables de manera automática
y modifica los tipos de acuerdo con los valores que va tomando durante la ejecución del script.
Enteras (tipo Integer): Son todas aquellas variables con un valor numérico
comprendido entre -231 y 231, PHP los interpreta como tipo Integer.
De coma flotante (tipo Double): Se consideran a las variables que sobrepasan el
intervalo numérico del tipo Integer, con lo que PHP convierte automáticamente la
variable en tipo Double.
19
Cadenas (tipo String): Son todas las variables a las que se le asigna como valor una
cadena de caracteres.
Integer est velit, rhoncus commodo leo eu, pellentesque pretium diam.
TIPOS DE VARIABLE
Doubl Para valores que sobrepasen el intervalo numérico del tipo $a=2.5
e Integer.
String Para valores entre comillas, ya sean números o letras. $a=”palabra” o $a=”
57”
NOTA: Existe una función que devuelve una cadena de caracteres con el tipo de las variables
que contiene, esta función es gettype(variable). Y siempre devolverá los tipos Integer, Double
o String.
$variable=((Integer)3.8) o $variable=((int)3.8)
$variable=((string)57)
20
NOTA: Existe otra posibilidad de forzar el tipo de las variables, esto se consigue con la
instrucción settype(variable,tipo). La cadena tipo debe contener uno de los siguientes valores
Integer, Double o String. Para convertir a tipo entero una variable haríamos:
($variable,Integer)
Al operar con dos Integer (enteros), si el resultado está dentro del rango de los
enteros, devuelve un Integer.
Si opera con dos Integer y el resultado sobrepasa el rango de los Integer,
automáticamente convierte el valor en Double (coma flotante).
Si opera un Integer con una variable Double, dará como resultado Double.
Una variable String (cadena) opera como los Integer. Si hay caracteres numéricos al
comienzo los extrae hasta que aparezca un punto o un carácter no numérico y los
opera como enteros.
Si una cadena no contiene caracteres numéricos al principio, al operar con ella toma el
valor numérico como cero.
Vectores
Los vectores se utilizan para guardar, manejar y operar grupos de variables. Por ejemplo,
vamos a escribir en un archivo .php el siguiente código:
<?php
$a[0]=5;
$a[1]=8;
$a[2]=2;
echo "$a[0],$a[1],$a[2]";
?>
<?php
$v=array(a=>”Sevilla”,b=>”Huelva”,c=>”Granada”);
echo “$v[a], $v[b], $v[c]”;
?>
if (IsSet ($variable) )
print (“el valor de la variable es $variable”);
21
else
print (“no se le ha asignado ningún valor a la variable”);
3 Variables predefinidas
PHP utiliza una serie de variables predefinidas que facilitan información de gran utilidad.
Muchas de estas variables no están completamente documentadas, puesto que dependen de
en qué servidor se esté ejecutando, la versión y configuración del mismo, además de otros
factores. Tenga en cuenta, que el contenido de las celdas donde aparecería el resultado de las
variables predefinidas variarán dependiendo del servidor al que acceda y a los parámetros de
configuración que tenga asignados.
Con estas variables, podrá conocer las IP del visitante, el navegador que utiliza, el nombre del
proveedor, etc.
Para que las muestre en pantalla, deberá llevar la función echo delante de la variable.
Para poder visualizar en pantalla la información que estas variables son capaces de mostrar, es
importante que en el fichero php.ini esté el valor register_globals=ON.
VARIABLES PREDIFINIDAS
22
REMOTE_PORT: Enseña el puerto que se está utilizando en la máquina del usuario para
comunicarse con el servidor Web.
gethostbyaddr("$REMOTE_ADDR"): Indica qué puerto se está usando en la máquina
del usuario para comunicarse con el servidor Web.
SCRIPT_FILENAME: Describe la vía de acceso absoluta del script que se está
ejecutando.
SERVER_ADMIN: Da el valor que se haya dado a la directiva SERVER_ADMIN (en
Apache) en el fichero de configuración del servidor Web.
SERVER_PORT: Muestra el puerto del equipo servidor que está usando el servidor Web
para la comunicación.
SERVER_SIGNATURE: Es una cadena que contiene la versión del servidor y el nombre
del servidor virtual que es añadida a las páginas generadas por el servidor si está
característica está activa.
SCRIPT_NAME: Revela la vía de acceso basada en el sistema de ficheros del script en
cuestión, después de que el servidor haya hecho la conversión virtual-a-real.
REQUEST_URI: Indica la URI que se dio para acceder a esta página.
PHP_SELF: Nos dice el nombre del fichero que contiene el script que se está
ejecutando, relativo al directorio raíz de los documentos.
Normalmente, si utiliza un servidor gratuito para alojar sus páginas .php, no tendrá privilegios
para modificar el archivo de la configuración porque el valor register_globals estará en OFF. Si
esto es así, no podrá visualizar las variables predefinidas. Para poder verlas, bastará con que
modifique la manera de llamar a las variables e introduzca el nombre de la variable en el
campo de nombre de un array asociativo.
register_globals=ON register_globals=OFF
GATEWAY_INTERFACE $HTTP_SERVER_VARS[‘GATEWAY_INTERFACE']
SERVER_NAME $HTTP_SERVER_VARS[‘SERVER_NAME']
Si se decanta por invocar siempre las variables predefinidas de esta forma, le servirá tanto para
register_globals=ON como para register_globals=OFF, de la configuración del php.ini
NOTA: Para la versión PHP 4.2.0 o superior, se incorporan entre otras la variable $_SERVER,
que tiene la misma función que $HTTP_SERVER_VARS, pero con un valor añadido, $_SERVER
tiene la característica de ser una variable superglobal. Anteriormente, para utilizar una variable
dentro de una función era imprescindible definirla en esa función como global, pues a partir de
la versión PHP 4.2.0, la variable $_SERVER define automáticamente como global cualquier
función.
23
4 Ámbito de las variables
El ámbito de una variable es el contexto donde la variable está definida. La mayoría de las
variables PHP solamente tienen un ámbito simple, el cual también abarca los ficheros incluidos
y los requeridos. Las variables pueden ser:
Ámbito global: La variable está presente en todas las partes del script, y puede ser
utilizada en cualquier momento.
Para declarar una variable de ámbito global, se puede utilizar la palabra global, aunque
sólo con definirla fuera de cualquier función ya se le está aplicando este ámbito.
Ámbito local: La variable sólo existe y opera dentro de una función concreta, no puede
ser accesible por el script en general ni por la demás funciones.
En cualquier caso, dentro de las funciones definidas por el usuario existe un ámbito local a la
función. Cualquier variable que se use dentro de una función estará limitada al ámbito local de
la función. Un ejemplo de todo esto puede ser:
<?php
$x = 1; /* variable global */
function Prueba()
{
echo $x; /* referencia a la variable local */
}
Prueba();
?>
El ejemplo anterior no producirá salida, puesto que la orden “echo” usa una versión local de
la variable $x, a la cual no se ha asignado ningún valor en su ámbito. Seguramente, no
notemos que hay un pequeño contraste con el lenguaje C, y es que en las variables globales
están disponibles automáticamente dentro de la función siempre que sean sobrescritas por
una definición local. Sin embargo, esto puede acarrear problemas, que podremos cambiar
variables globales inesperadamente. En PHP, las variables globales deben ser declaradas
globales dentro de la función si van a ser utilizadas dentro de dicha función. Con el siguiente
ejemplo se verá claramente:
<?php
$num1 = 2;
$num2 = 4;
function Suma()
{
global $num1, $num2;
$num2 = $num1 + $num2;
}
Suma();
echo $num2;
?>
24
Pero en este caso, el ejemplo anterior producirá la salida "6". Al declarar “$num1” y “$num2”
globales dentro de la función, las referencias que realicemos a dichas variables se referirán a la
versión global.
Una de las características más importantes del ámbito de las variables es la variable “static”.
Una variable estática puede existir sólo en el ámbito local de la función y no pierde su valor
cuando la ejecución del programa abandona este ámbito. Lo podremos ver más claro en el
siguiente ejemplo:
<?php
function Prueba ()
{
static $var = 0;
echo $var;
$var++;
}
?>
Las variables estáticas también suministran una forma de manipular funciones recursivas. La
función recursiva es aquélla que se llama a sí misma. Debemos tener cuidado cuando
escribamos una función recursiva, puesto que puede suceder que se llame a sí misma
indefinidamente. Nos tenemos que asegurar de implementar de una forma adecuada para
terminar la recursión. La función del siguiente ejemplo cuenta recursivamente hasta 5, usando
la variable estática “$a” para saber cuándo parar:
<?php function Prueba() { static $a = 0; $a++; echo $a; if ($a < 5) { Prueba(); }
$a--; } ?>
5 Variables variables
A menudo, se suele usar lo que se conoce con el nombre de “variables variables”. Es decir, son
nombres de variables que pueden establecerse y usarse dinámicamente. Por ejemplo, una
variable normal se establece con una sentencia de la siguiente manera:
<?php
$variable = "hola";
?>
En el caso de una variable variable, toma el valor de una variable y lo trata como el nombre de
una variable. En el ejemplo anterior, la variable “hola” se puede usar como el nombre de una
variable usando “$$”, como por ejemplo:
<?php
$$variable = "mundo";
?>
25
cadena "mundo". Por lo tanto, estas dos sentencias producen el mismo resultado: “hola
mundo”.
<?php
echo "$variable ${$variable}";
?>
<?php
echo “$variable $hola”;
?>
Donde nombre es el nombre que le damos a la constante, valor su valor, y el campo opcional
noMayusculas indica si está a 1 que podemos acceder a la variable independientemente con
mayúsculas o minúsculas, mientras que si está a 0 (valor por defecto) sólo podremos acceder a
ella de la misma forma que la hayamos definido.
Las diferencias existentes entre las constantes y las variables en PHP son muy claras:
El ámbito de una variable es el contexto donde la variable está definida. La mayoría de las
variables PHP solamente tienen un ámbito simple, el cual también abarca los ficheros incluidos
y los requeridos. Las variables pueden ser:
Ámbito global: La variable está presente en todas las partes del script, y puede ser
utilizada en cualquier momento.
Para declarar una variable de ámbito global, se puede utilizar la palabra global, aunque
sólo con definirla fuera de cualquier función ya se le está aplicando este ámbito.
Ámbito local: La variable sólo existe y opera dentro de una función concreta, no puede
ser accesible por el script en general ni por la demás funciones.
Las diferencias existentes entre las constantes y las variables en PHP son muy claras:
<?php
define("CONSTANTE", "Hola mundo.");
echo CONSTANTE; // muestra "Hola mundo."
?>
Las diferencias existentes entre las constantes y las variables en PHP son muy claras:
26
No llevan el símbolo del dólar delante.
Puede accederse a ellas desde cualquier parte del código donde han sido definidas, sin
restricciones de ámbito como en las variables.
No pueden ser redefinidas o borradas una vez definidas.
Sólo pueden contener valores escalares, no vectores.
7 Constantes predefinidas
En PHP existen constantes predefinidas que no requieren de la función
define(“nombre”,”valor”).
Éstas son:
NOTA: No olvide, que tanto la constante FILE como LINE llevan dos rayas delante y otras dos
detrás.
Las constantes E_* se usan típicamente con la función error_reporting() para configurar el
nivel de informes de error.
<HTML>
<TITLE>EJEMPLO</TITLE>
</HEAD>
<BODY>
<?php
// La constante del sistema __FILE__ nos devolverá
// el nombre del fichero que se está interpretando
27
// actualmente. En este caso nos devolverá ejemplo.php
// y también su path.
echo "La ruta completa de este fichero es: ";
echo __FILE__;
// La constante del sistema __LINE__ nos devolverá
// el número de línea que se está interpretando y
// también cuenta las líneas en blanco
// cuenta las líneas y verás que devuelve ... 21.
echo "<br>Esta es la línea: ",__LINE__, "del fichero";
echo "<br>Estamos utilizando la versión: ",PHP_VERSION, " de PHP";
echo "<br>El PHP se está ejecutando desde el sistema operativo: ",PHP_OS;
?>
</BODY>
</HTML>
8 Práctica: Variables
VARIABLES:
Realizar una función en la cual utilicemos una variable definida fuera de dicha
función.
<?php
$num = 5;
function sumar($num){
$suma = ($num + 25);
echo $suma;
}
sumar($num);
?>
9 Práctica: Constantes
CONSTANTES:
<HTML>
<TITLE>CONSTANTES</TITLE>
28
</HEAD>
<BODY>
<?php
define (“nombre”,”Mi nombre es Manolo García”);
echo __FILE__; //mostrará la ruta del fichero.
echo PHP_VERSION; //nos muestra la versión de PHP que estamos
utilizando.
echo PHP_OS; //nos muestra el sistema operativo que estamos utilizando.
echo nombre; //nos mostrará nuestro nombre y apellido.
?>
</BODY>
</HTML>
Tema 5: Operadores
Durante esta lección aprenderemos que las variables pueden ser creadas, modificadas y
comparadas entre sí por medio de los “operadores”. También nos instruiremos en cómo listar
los operadores más importantes.
Por medio de dichos operadores, las variables pueden ser creadas, modificadas y comparadas
entre sí.
Operador de asignación
El operador de asignación que se utiliza es el símbolo igual (=) que nos permite asignar
valores a las variables.
Operador de concatenación
El operador de concatenación que utilizamos es el punto (.) y con él podemos unir los
valores de las variables.
También podemos utilizar el operador punto igual (.=) para asignar un dato al valor
anterior.
Operador de asignación: El operador de asignación que se utiliza es el símbolo igual (=) que
nos permite asignar valores a las variables. Veamos un ejemplo:
<?php
$variable = 1582;
$departamento = "desarrollo";
$var1 = var2 = 0;
?>
29
Operador de concatenación: El operador de concatenación que utilizamos es el punto (.) y con
él podemos unir los valores de las variables. Por ejemplo:
<?php
$nom = "fernando";
$ape = "altea";
$completo = $nom." ".$ape; // concatena los dos valores y añade un espacio
?>
También podemos utilizar el operador punto igual (.=) para asignar un dato al valor anterior:
<?php
$cadena = "pulsera";
$cadena .=" amarilla";
// la variable $cadena contiene ahora “pulsera amarilla”
?>
3 Operadores aritméticos
Los operadores aritméticos son aquéllos que nos permiten realizar operaciones numéricas con
nuestras variables.
El operador que puede llevar más confusión es el tanto por ciento (%). Para utilizarlo
correctamente, si queremos obtener el resto de una división, lo debemos colocar entre los dos
valores que queremos realizar la operación.
+ Suma
- Resta
* Multiplicación
/ División
Vamos a realizar un ejemplo con los distintos tipos de operaciones que se pueden realizar.
Para ello utilizaremos las variables ‘$a' y ‘$b'.
30
<HTML>
<BODY>
<?php
$a = 10; // Asignamos a “a” el valor
// Muestra a = 10, b = 6
echo 'a + b = ' . ($a + $b) . '<BR>'; // Muestra a + b = 16
echo 'a - b = ' . ($a - $b) . '<BR>'; // Muestra a – b = 4
echo 'a * b = ' . ($a * $b) . '<BR>'; // Muestra a * b = 60
echo 'a / b = ' . ($a / $b) . '<BR>'; // Muestra a / b = 1,666667
echo 'a % b = ' . ($a % $b) . '<BR>'; // Muestra a % b = 4
echo '-a = ' . ($a) . '<P>'; // Muestra -a = -10
?>
</BODY>
</HTML>
4 Operadores de comparación
Los operadores de comparación se suelen utilizar generalmente para comparar dos variables,
comprobando si cumple o no la condición previamente establecida. Estos operadores son
binarios y su resultado es un booleano (valor de verdad).
== Igualdad
!= Desigualdad
31
Como ejemplo de cada uno de ellos, tenemos:
5 Operadores lógicos
Los operadores lógicos se usan conjuntamente con los operadores de comparación cuando la
expresión que queremos comparar requiere de un operador lógico. Sirven para componer
condiciones más simples por medio de las reglas de la y, o y no lógicas.
Estos operadores nos permiten expresar condiciones compuestas de las que queremos
averiguar su valor de verdad.
|| Or (O)
! NOT (Negación)
<HTML>
<BODY>
<?php
$a = 10; // Asignamos a la variable “a” el valor 10
32
echo '(a > b) && (a > c) : ' . (($a > $b) && ($a > $c)) . '<BR>';
echo '(a > b) && (a < c) : ' . (($a > $b) && ($a < $c)) . '<BR>';
echo '!(a < b) : ' . !($a < $b) . '<BR>';
echo '(a > b) || (a > c) : ' . (($a > $b) || ($a > $c)) . '<BR>';
?>
</BODY>
</HTML>
La primera comparación nos dice si '$a' es mayor que '$b' y a la vez mayor que '$c'.
La segunda, si '$a' es mayor que '$b' y a la vez menor que '$c'.
La tercera, si no se cumple que '$a' sea menor que '$b'.
Y por último, la cuarta nos dice si '$a' es mayor que '$b', o bien '$a' es mayor que '$c'.
6 Operadores de incremento-decremento
Los operadores de incremento o decremento sirven para aumentar o disminuir el valor de una
variable. Estos operadores solo suman o restan una unidad, existen dos tipos:
Este tipo de sentencias sirven para realizar una operación u otra dependiendo de la condición
que establezcamos. Este tipo de acciones las podemos llevar a cabo gracias a una paleta de
instrucciones que se encuentran en casi todos los lenguajes de programación.
Es la estructura de control más simple en PHP. La sentencia If obliga a evaluar la expresión que
haya entre paréntesis y, si se cumple la condición, ejecuta un bloque de código. Si por el
contrario dicha condición no se cumple, el bloque de código será ignorado.
Como todo el mundo sabe, no todo puede ser sí o no, blanco o negro, grande o pequeño… Por
esta causa, se pueden plantear muchas más condiciones dentro de la condición principal,
siempre dependiendo de la finalidad que busquemos. A éstas se les llaman condiciones
anidadas.
33
If, Elseif, Else:
Esta instrucción es similar al último caso que hemos visto, con la salvedad de que nos permite
introducir en la misma línea la instrucción condicional.
If, Else
Es la estructura de control más simple en PHP. La sentencia If obliga a evaluar la expresión que
haya entre paréntesis y, si se cumple la condición, ejecuta un bloque de código. Si por el
contrario dicha condición no se cumple, el bloque de código será ignorado.
if (condición)
Sentencia 1;
Sentencia 2;
...
else
Sentencia 3;
Sentencia 4;
...
<?php
$edad = "";
else
?>
34
<?php
if ($user == "jaime")
{
// código exclusivo para el usuario Jaime
}
// código para todos los usuarios, sean o no Jaime
?>
Para incluir condiciones complejas solo basta con unirlas mediante el operador necesario para
dicha condición. Un ejemplo podría ser:
<?php
Como todo el mundo sabe, no todo puede ser sí o no, blanco o negro, grande o pequeño… Por
esta causa, se pueden plantear muchas más condiciones dentro de la condición principal,
siempre dependiendo de la finalidad que busquemos. A éstas se les llaman condiciones
anidadas, y su estructura sería:
if (condición1)
{
Sentencia 1;
Sentencia 2;
...
}
else
{
if (condición2)
{
Sentencia 3;
Sentencia 4;
...
}
else
{
Sentencia 5;
...
}
}
35
Si cumple la condición1, realizaría las sentencias 1 y 2. Si cumple la condición2, realizaría las
sentencias 3 y 4. Y si por el contrario no cumple ninguna de las dos condiciones anteriores,
realizaría la sentencia 5.
if (condición1)
{
Sentencia 1;
Sentencia 2;
...
}
elseif (condición2)
{
Sentencia 3;
Sentencia 4;
...
}
else
{
Sentencia 5;
...
}
<?php
if ($user == "pablo")
{
// código exclusivo para el usuario Pablo
}
elseif ($user == "miguel")
{
// código exclusivo para el usuario Miguel
}
else
{
// código para el resto, o lo que es lo mismo,
// para todos menos para Pablo ni Miguel
}
?>
36
De todo esto, deducimos que “elseif” es lo mismo que escribir primero un “else” y a
continuación un “if”.
Programa que asigne dos valores distintos a dos variables y nos diga cuál es la
mayor de las dos.
<?php
$a = 6;
$b = 2;
if ($a > $b)
{
echo “La variable a es mayor que la variable b.”;
}
else
{
echo “La variable b es mayor que la variable a.”;
}
?>
Realizar un programa que, según la edad que escribamos, nos diga cuánto
vale sacarse un carné en el polideportivo.
37
1. Si el socio tiene 9 años o menos, deberá costar 15
euros.
2. Si el socio tiene entre 10 y 17 años, deberá costar 22
euros.
3. Si el socio es mayor de edad, deberá costar 28
euros.
<?php
$edad = 19;
if ($edad <= 9)
{ echo “El carné cuesta 15 euros.”;
}
elseif ($edad <= 17)
{
echo “El carné cuesta 22 euros.”;
}
else
{
echo “El carné cuesta 28 euros.”;
}
//el carné le costará 28 euros.
?>
38
el valor de la variable es numérico, entero y menor o igual
de 10.
el valor de la variable es numérico, entero y mayor de 10.
el valor de la variable es numérico, decimal y menor o
igual de 10.
el valor de la variable es numérico, decimal y mayor de 10.
el valor de la variable es texto.
<?php
$var = 4.5;
$valor=(gettype($var));
if ($valor == "integer" || $valor == "double")
{
if($var<=10)
{
if ($valor == "integer")
{
echo "el valor de la variable es numérico, entero y menor o igual de 10.";
}
else
{
echo "el valor de la variable es numérico, decimal y menor o igual de 10.";
}
}
else
{
if ($valor == "integer")
{
echo "el valor de la variable es numérico, entero y mayor de 10.";
}
else
{
echo "el valor de la variable es numérico, decimal y mayor de 10.";
}
}
}
else
{
39
echo "el valor de la variable es texto.";
}
?>
<?php
$a=100;
$b=10;
$c=60; if($a>$b)
{
$aux=$a;
$a=$b;
$b=$aux;
} if($b>$c)
{
$aux=$b;
$b=$c;
$c=$aux;
}
if($a>$b)
{
$aux=$a;
$a=$b;
$b=$aux;
}
echo "$a, $b, $c";
?>
Tema 6: Bucles
En el desarrollo de la siguiente lección, aprenderemos a utilizar una serie de instrucciones
llamadas Bucles, los cuales forman parte de la sintaxis en PHP.
40
1 Qué es un Bucle
Como todos sabemos, los ordenadores están diseñados para realizar tareas repetitivas y, por
lo tanto, podemos realizar programas para aprovechar este tipo de tareas, y poder realizar una
secuencia de instrucciones el número de veces que indiquemos.
Para todo ello, utilizaremos las estructuras llamadas bucles, que se utilizan para realizar la
tarea definida el número de veces que necesitemos.
A continuación detallaremos algunos de los aspectos de los bucles más utilizados en PHP.
2 Bucle While
Este bucle es el más sencillo de utilizar se utiliza, siempre y cuando la condición sea verdadera,
para ejecutar las instrucciones que contiene dentro de él. El valor de la expresión es
comprobado cada vez al principio del bucle, incluso si este valor cambia durante la ejecución
de las sentencias, la ejecución no parará hasta el fin de la repetición.
Su sintaxis es la siguiente:
while (condición)
{
Instrucción1;
Instrucción2;
...
}
<?php
$i=1;
while ($i <=10) {
echo "$i<br>";
$i++;
}
?>
El ejemplo anterior muestra los números desde el 1 hasta el 10 de forma correlativa. Cuando
llega al 10 se saldrá del bucle. Para que el ejemplo funcione, ha de cumplir dos condiciones:
una que $i sea, al principio, menor que 10, ya que si es mayor el bucle no se ejecuta pues la
condición no se cumple, y la otra es que hay que ir aumentando $i ($i++), ya que si no hacemos
esto, $i valdría siempre 1. En este caso, la condición siempre sería verdadera y no podríamos
salir nunca del bucle.
<?
41
$cadena = "hoy tengo mucha hambre";
//recorro la cadena hasta encontrar una "b"
$i=0;
while ($cadena[$i]!="b" && $i< strlen($cadena)){
$i++;
}
if ($i==strlen($cadena))
echo "Error, no encontramos ninguna b";
else
echo "¡¡Encontrada!! Está en la posición $i";
?>
NOTA: Para que entendamos bien este ejercicio, es necesario conocer la función de cadena
strlen(), la cual nos da como resultado la longitud de la cadena que se le pase como parámetro:
“int strlen (string cad)” que devuelve un número entero igual a la longitud de la cadena.
En cuanto al ejemplo, definimos una cadena en la que escribimos "hoy tengo mucha hambre".
A continuación, recorrerá esa cadena hasta el final de la cadena o hasta encontrar el carácter
"b". La variable $i la utilizamos para llevar la cuenta de los caracteres que hemos recorrido
durante la ejecución del programa.
3 Bucle Do While
Este bucle es casi igual que el explicado anteriormente, pero con la salvedad de que aquí la
condición se evalúa después de ejecutar el código. Esa es la gran diferencia con respecto a
“while”, así que garantiza la ejecución de la primera iteración de este bucle.
Su sintaxis es la siguiente:
do
{
Instrucción1;
Instrucción2;
...
} while (condición)
<?php
$i=1;
do
{
echo "$i<br>";
$i++;
}
while ($i <=10);
?>
42
Este ejemplo sería igual que el ejemplo de “while”, ya que también mostraría los números
desde el 1 hasta el 10, cada uno en una línea.
4 Bucle For
Es uno de los bucles más complejos en PHP. For toma tres parámetros separados entre ellos
mediante un punto y coma, estos parámetros son:
Este bucle resulta muy práctico en determinadas situaciones. Es uno de los más populares, y la
diferencia que tiene con los anteriormente explicados radica en cómo se plantea la condición
de finalización del bucle.
Es importante saber, que podemos romper cualquiera de los bucles en el momento que
deseemos escribiendo la sentencia “break”.
{ Instrucción1;
Instrucción2;
...
}
La primera expresión que se evalúa es “valor_inicial”, y se hace una sola vez al comienzo del
bucle. A continuación, al comienzo de cada iteración es evaluada “valor_final” y si dicha
evaluación resulta verdadera, el bucle sigue su curso al igual que las sentencias anidadas. Pero
si la evaluación resulta que es falsa, la ejecución del bucle finaliza. Un breve ejemplo de todo
esto podría ser:
<?php
for ($i = 1; $i <= 10; $i++) {
echo "$i<br>";
}
?>
Este ejemplo mostraría los números del 1 al 10, cada uno en una fila distinta. Cabe destacar,
que el valor inicial no se puede poner fuera del bucle For, ya que no afectaría en nada a
nuestro programa. Veamos un ejemplo de esto:
<?php
print(“Cuenta atrás…<P>”);
$i=10;
for ( ; $i >= 0; $i--) {
print (“\$a = $a<BR>”);
}
?>
43
Es importante saber, que podemos romper cualquiera de los bucles en el momento que
deseemos escribiendo la sentencia “break”. Veamos un ejemplo de cómo funciona dicha
sentencia, pero al final de este tema hablaremos de ella con más detenimiento:
<?php
for ($i = 1; ;$i++) {
if ($i > 10) {
break;
}
print $i;
}
?>
Este ejemplo lo que hace es mostrar por pantalla los números correlativos desde el 1 hasta el
10. El valor final se encuentra dentro de una sentencia condicional “if” y, cuando dicho valor
resulta verdadero, se ejecuta la orden “break”, por lo que el programa sale del bucle for.
Tanto el ejemplo anterior como el primer ejemplo que hicimos de este apartado, se podrían
sintetizar considerablemente. Bastaría con escribir el siguiente código y obtendríamos los
mismos resultados:
<?php
5 Bucle Foreach
Los bucles “Foreach” son utilizados para el tratamiento de arrays. Cabe recordar que un array
es una variable que guarda un conjunto de valores relacionados mediante una clave.
Este bucle nos ayuda a recorrer los valores de una matriz, lo que nos resulta muy útil para
realizar una lectura rápida de la misma. Si no lo utilizamos con matrices, nos devolverá un
error.
La sintaxis es la siguiente:
Este bucle recorre el array dado por “$array” y en cada iteración, el valor actual se asigna al
elemento “$valor”, y el puntero interno del array avanza en una unidad, por lo que en el
siguiente paso, estará apuntando al elemento siguiente.
44
<?php
$capitales=array("España"=> "Madrid","Italia" => "Roma","Francia" => "París");
Foreach ($capitales as $clave=>$valor)
{
echo "Pais: $clave Capital: $valor<br>";
}
?>
Un array o matriz multidimensional es aquél en el que al menos uno de sus valores es, a su vez,
un array. Un ejemplo de array multidimensional podría ser:
<?php
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";
foreach($a as $v1) {
foreach ($v1 as $v2) {
print "$v2\n";
}
}
?>
En una matriz dinámica sus valores no contienen ningún array como podemos ver a
continuación:
<?php
foreach(array(1, 2, 3, 4, 5) as $v) {
print "$v\n";
}
?>
6 Break y Continue
“Break” y “Continue” son dos instrucciones que se pueden meter dentro de la sintaxis de
cualquiera de las estructuras anteriores. Son muy prácticas.
Break
Sirve para escapar de cualquier estructura de control: for, while y, como veremos más
adelante, switch. Acepta un parámetro opcional que determina cuántas estructuras de
control hay que escapar.
Continue
Se utiliza dentro del bucle para saltar el resto de esa iteración y pasar a la iteración
siguiente. “Continue” acepta un parámetro opcional que determina cuántos bucles hay
que saltar antes de que continúe con la ejecución.
45
Break
Sirve para escapar de cualquier estructura de control: for, while y, como veremos más
adelante, switch.
<?php
Continue
Se utiliza dentro del bucle para saltar el resto de esa iteración y pasar a la iteración siguiente.
“Continue” acepta un parámetro opcional que determina cuántos bucles hay que saltar antes
de que continúe con la ejecución.
<?php
$i = 0;
while ($i++ < 5) {
echo "$i<br>";
echo "Fuera<br>";
while (1) {
echo " En el centro<br>";
while (1) {
echo " Dentro<br>";
continue 3;
}
echo "Esto no se imprimirá nunca.<br>";
}
echo "Y esto tampoco se imprimirá.<br>";
}
?>
En el bucle “While” que tienen un “1” dentro, equivale a poner TRUE (verdadero) y se refiere a
la expresión del primer while que tiene que ser menor que 5. Si cambiamos el 1 por un 0 no se
ejecutaría ninguno de los dos bucles y sí los dos echos que están debajo. Realmente la
estructura continue no se suele utilizar mucho.
7 Switch
La sentencia “Switch” es una forma distinta y más comprensible para evaluar una variable
frente a multitud de opciones. En muchos casos, queremos comparar la misma variable con
infinidad de expresiones, ejecutando la parte del código correspondiente a la opción elegida.
46
El uso de la cláusula “break” es necesario, ya que con esta estructura cada vez que se cumple
la condición deseada, se ejecutan el resto de declaraciones. Con “break” lo que conseguimos
es salir fuera del “switch” continuando con la ejecución del programa. Si en vez de “break”
pusiéramos “exit”, el resto del programa no se ejecutaría, ya que se saldría de dicho programa.
La expresión “case” puede ser cualquier expresión que se ajuste a un tipo simple, o lo que es lo
mismo, números enteros o de punto flotante y cadenas de texto.
Esta sentencia es lo mismo que escribir numerosas sentencias “if”, por lo que resulta más
ordenado:
if ($i == 0) {
print "i es igual a 0";
}
if ($i == 1) {
print "i es igual a 1";
}
if ($i == 2) {
print "i es igual a 2";
}
<?php
$variable = "a";
switch ($variable) {
case "a":
// el código será ejecutado si $variable vale "a"
break;
case "b":
// el código será ejecutado si $variable vale "b"
break;
case "c":
// el código será ejecutado si $variable vale "c"
break;
default:
// este código se ejecutará si no se cumple ninguna condición
}
?>
El uso de la cláusula “break” es necesario, ya que con esta estructura cada vez que se cumple
la condición deseada, se ejecutan el resto de declaraciones. Con “break” lo que conseguimos
es salir fuera del “switch” continuando con la ejecución del programa. Si en vez de “break”
pusiéramos “exit”, el resto del programa no se ejecutaría, ya que se saldría de dicho programa.
47
Un ejemplo de esta sentencia sería:
<?php
$num = 2;
switch ($num) {
case 0:
print "El valor de num es 0";
break;
case 1:
print "El valor de num es 1";
break;
case 2:
print "El valor de num es 2";
break;
default:
print "El valor de num es distinto a 0, 1 y 2";
}
?>
La expresión “case” puede ser cualquier expresión que se ajuste a un tipo simple, o lo que es lo
mismo, números enteros o de punto flotante y cadenas de texto. Aquí no podemos utilizar ni
arrays ni objetos, siempre y cuando no se conviertan intencionadamente a un tipo simple.
48
<?php
$dia="Jueves";
switch ($dia) {
case "Lunes":
echo "Hoy es lunes y tengo que hacer la compra.";
break;
case "Martes":
echo "Hoy es martes y tengo que recoger a mi hermano.";
break;
case "Miércoles":
echo "Hoy es miércoles y tengo que ver el partido.";
break;
case "Jueves":
echo "Hoy es jueves y tengo que ir al dentista.";
break;
case "Viernes":
echo "Hoy es viernes y tengo descansar un poco.";
break;
case "Sábado":
echo "Hoy es sábado y tengo que jugar al fútbol.";
break;
case "Domingo":
echo "Hoy es domingo y tengo que estudiar.";
break;
default:
echo "No ha escrito correctamente el día de la semana.";
}
?>
49
Esta práctica la realizaremos mediante la sentencia “Do…While” y la cadena será
“esto es un ejercicio de repaso”. Nos debe salir una pantalla parecida a la
siguiente:
<?php
La solución sería:
<?php
$suma=0;
for($i=1; $i<=100; $i++)
{
if($i%5==0)
{
echo "$i<BR>";
50
$suma=$suma+$i;
}
}
echo "La suma total es $suma.";
?>
Elaborar un programa que declare dos variables enteras y muestre todos los
valores entre ellas.
La solución sería:
<?php
$a=7;
$b=20;
if($b<$a)
{
$aux=$a;
$a=$b;
$b=$aux;
} do
{
echo "$a<BR>";
$a++;
}
while ($a<$b)
?>
Realizar un programa que muestre las tablas del multiplicar del 1 al 10.
El resultado sería:
<?php
51
for ($j=0; $j<=10; $j++)
{
$m=$i*$j;
echo $i."*".$j."=".$m."<BR>";
}
echo "<BR></P>";
}
?>
Tema 7: Funciones
En el transcurso de esta lección, aprenderemos a crear y a utilizar funciones dentro del
lenguaje de programación PHP.
Las funciones suelen ser tremendamente prácticas, puesto que las podremos crear para
conectarnos a una base de datos, crear encabezados de página, pies de páginas, etiquetas, etc.
Una gran ventaja de las funciones es que las podemos llamar en cualquier momento. Al utilizar
funciones en nuestro código, podremos perfeccionar cada una de sus funcionalidades cada vez
que sea necesario, siendo mucho más fácil localizarlas. También podremos utilizar el código
que contengan, llamando a la función cuantas veces haga falta, ya que se pueden utilizar
indefinidamente.
Como todos sabemos, la función debe ser definida dentro del script. Las podemos almacenar
en un archivo distinto, llamado librería, al que invocaremos las veces necesarias desde nuestro
script. Para incluirlo en nuestro programa, empleamos las órdenes require o include:
require("encabezado.php") o include("encabezado.php")
Podemos invocar a esta función desde otro archivo distinto como vemos en el siguiente
ejemplo:
<?php
52
include("encabezado.php");
$titulo="Manual de PHP";
crear_cabecera($titulo);
?>
<?php
function nombre_de_la_función (valores) {
// Código de nuestra función
}
?>
El valor que indicamos dentro del paréntesis ( ) puede ser omitido, pero el paréntesis hay que
escribirlo obligatoriamente.
Como hemos visto en otras unidades, PHP sí distingue entre mayúsculas y minúsculas. En el
caso de las funciones, escribir mayúsculas y minúsculas es indiferente, ya que no las distingue.
<?php
function ejemplo () {
echo "esta es una funcion de ejemplo";
}
?>
Cada vez que llamemos a esta función aparecerá en la pantalla el siguiente mensaje “esta es
una función de ejemplo”.
Es importante saber que las funciones no se ejecutan hasta que no sean invocadas.
A una función se le puede invocar antes de que sea definida en el documento. Por lo tanto,
estos dos ejemplos son iguales:
<?php
function numerar () {
53
for ($i=1; $i<=10; $i++) {
echo “$i <br>”;
}
}
numerar ();
?>
//Sería igual que escribir:
<?php
numerar ();
function numerar () {
for ($i=1; $i<=10; $i++) {
echo “$i <br>”;
}
}
?>
Se puede comprobar con el ejemplo, que al invocar una función le podemos pasar una serie de
parámetros externos a nuestra función. De esta forma, podremos definir variables y valores
dentro del paréntesis que va detrás del nombre de la función, como por ejemplo:
La función utilizará estos dos valores (4 y 7) de forma independiente a las variables $x y $z que
pudieran contener otros valores diferentes en el ámbito externo de la función. Otra forma de
asignar valores a las variables internas de una función es pasar los parámetros por valor, como
por ejemplo:
En este último caso, prepararía la función para recibir dos valores pero requeriría que en la
llamada a la función se escribieran, separados por comas, esos dos valores:
numerar (-55,11);
<?php
function calcular ($n=20) {
echo “El resultado de 3*\$n en la función es: ”, 3*$n, “<br>”;
echo “El valor de \$n dentro de la función es: ”, $n, “<br>”;
}
calcular ();
echo “El valor de \$n después de ejecutar la función es: ”, $n,
“<br><br>”;
?>
<?php
function operar ($n, $m) {
54
echo “El resultado de 3*\$n+5*\$m en la función es: ”, 3*$n+5*$m, “<br>”;
echo “El valor de \$n dentro de la función es: ”, $n, “<br>”;
}
operar (5,3);
echo “El valor de \$n después de ejecutar la función es: ”, $n, “<br><br>”;
?>
Copy
Esta función coge el archivo escrito en $origen y lo copia en $destino.
Rename
Esta función coge el nombre del archivo $antes y lo cambia por el archivo $después.
Unlink
Esta función borra el archivo especificado.
unlink ($archivo)
Fopen
Esta función abre el archivo especificado y le asigna $id. En cuanto al modo, nos referimos al
modo de apertura del fichero, son los siguientes:
- “a+” lectura y escritura. El archivo se crea si no existe y el puntero se coloca al final del
fichero.
Fgets
Esta función lee una línea de un archivo en concreto hasta un número máximo de caracteres.
Fwrite
Esta función permite escribir una cadena dentro del archivo señalado.
55
Fseek
Esta función avanza o retrocede un puntero tantas posiciones como indiquemos.
Feof
Esta función realiza la comprobación de que el puntero llegó al final de la función.
Fpassthru
Esta función lee el archivo indicado completo y lo muestra en pantalla.
fpassthru ($id)
Fclose
Esta función cierra el archivo especificado.
fclose ($id)
Opendir
Esta función abre el directorio situado en $path y le asigna el valor $dir.
Readdir
Esta función lee el elemento del directorio $dir abierto previamente con la función opendir.
readdir ($dir)
Rmdir
Esta función elimina el directorio $dir.
rmdir ($dir).
Mkdir
Esta función permite crear un directorio situado en $path con los derechos de acceso
$derechos.
Por ejemplo, en derechos podemos escribir chmod 644 y asignamos permisos de lectura y
escritura para el usuario y solo de lectura para los demás.
Rewinddir
Esta función devuelve el puntero de lectura del directorio $dir al primer elemento.
rewinddir ($dir)
Closedir
Esta función cierra el directorio $dir.
closedir ($dir)
56
Veamos un ejemplo de funciones para la gestión de directorios y entenderemos todo esto
mejor:
<?php
// definir path//
$path ="/home/ikaro/public_html/";
//en el path debemos escribir el directorio
//abrir directorio//
$dir=opendir($path);
//mostrar información//
closedir($dir);
?>
6 Retorno de valores
Una utilidad destacable que poseen las funciones es la posibilidad de retornar variables. Para
ello, debemos escribir la palabra return seguida del dato o seguida de la variable que tiene que
retornar. Cada vez que llamemos a return, terminará la ejecución de la función devolviendo el
dato solicitado. Una función puede poseer múltiples return pero sólo devolverá datos de cada
uno de ellos cada vez.
return $variable;
A continuación, vamos a ver unos ejemplos para entender mejor el retorno de valores en una
variable:
<?php
function iva($precio,$porcentaje=16){
return $precio * $porcentaje /100;
}
echo iva(1000) . "<br>";
//este caso mostrará 160, ya que hace el 16%
echo iva(1000,7) . "<br>";
//este caso nos muestra 70
echo iva(10,0) . "<br>";
//este caso mostrará 0
?>
57
<?php
function iguales ($a=4, $b=7)
{
$cadena = "";
if ($a == $b) {
$cadena =" Las variables a y b son iguales";
} else {
$cadena =" Las variables a y b son distintas";
}
return $cadena;
}
echo iguales();
?>
Con la instrucción return podemos devolver cualquier tipo de valor, incluidos también objetos
y tablas. Si queremos que nuestra función devuelva sólo un valor, tenemos que utilizar una
tabla.
Realizar un programa que utilice una función para conocer el mayor de dos
números cualquiera. En esta práctica vamos a utilizar la orden return para
devolver dicho valor.
<?php
function mayor ($a, $b)
{
$cadena = "";
58
} else {
$cadena = $b." es mayor que ".$a.”.”;
}
return $cadena;
}
echo mayor(7,3),"<br>";
?>
<HTML>
<BODY>
<?php
function media_aritmetica($a, $b)
{
$media=($a+$b)/2;
return $media;
}
echo "La media aritmética es ".media_aritmetica(7,9),"."."<br>";
?>
</BODY>
</HTML>
59
9 Práctica: Listar directorio
LISTAR DIRECTORIO:
<HTML>
<BODY>
<?php
$path ="../www/";
//El archivo que contiene este código estará dentro de /www. Por ese motivo, para
listar su contenido, debemos subir un nivel con ../
$dir=opendir($path);
while ($elemento = readdir ($dir))
{
echo $elemento."<br>";
}
?>
</BODY>
</HTML>
Tema 8: Formularios
A lo largo de esta lección aprenderemos a crear e insertar formularios en nuestro código PHP,
que son de mucha utilidad en las páginas Web, pues recaba información relativa a nuestros
usuarios. Debemos saber que los formularios no forman parte del lenguaje PHP sino del HTML.
Un formulario es el camino por el cual recogemos los datos de nuestra página PHP para que
sean procesados y almacenados en nuestra base de datos. Una de sus principales ventajas es
que cualquier valor introducido dentro de un formulario HTML se almacena en una variable.
Dicho valor podrá ser utilizado posteriormente en nuestros scripts.
1 Conocimientos previos
Es conveniente saber, que un formulario HTML va siempre definido entre las siguientes
etiquetas: <FORM> y </FORM>. Dentro de estas etiquetas, podemos incluir tantos atributos
como nos permite el lenguaje HTML.
Con la palabra ACTION, indicamos el script que va a procesar la información que recogemos en
el formulario; y con la palabra METHOD se indica lo que quiere hacer el usuario con los datos.
60
NOTA: En un formulario HTML podemos utilizar elementos como INPUT y SELECT. Los valores
de dichos elementos los rellenará el visitante de la página. Al enviar el formulario indicado se
genera una variable cuyo nombre se especifica mediante el atributo NAME. El valor será
introducido por el usuario. A lo largo de este tema iremos viendo para qué sirven estos
elementos.
3 Cuadro de texto
Es el método más utilizado para recoger información detallada en un formulario. Sirve para las
entradas de texto sencillas, como un nombre, dirección, teléfono… que son introducidos por el
mismo usuario. Es fácil identificarlo, puesto que crea un cuadro de texto donde podremos
escribir el máximo de caracteres que se especifique.
61
Si queremos que aparezca una palabra delante del cuadro de texto para especificar el campo a
rellenar, sólo debemos escribir dicha palabra al principio de la línea, antes de la etiqueta
<INPUT>. Para que su lectura sea más comprensible, debemos dejar un espacio, donde
corresponda, utilizando la expresión “ ”.
5 Casillas de verificación
Estas casillas se utilizan cuando solo se puede elegir entre un número de opciones concreto.
Pretende buscar la comodidad en el usuario y menor tiempo de respuesta. Es la mejor solución
para ofrecer opciones definidas, que se podrán seleccionar o no haciendo clic encima de la
casilla, que se mostrará como marcada si aparece una pequeña marca en la casilla
correspondiente.
Podemos observar, que hay que poner al final de la línea el código “<br>” para que pase a la
siguiente línea y sea más fácil de leer; de lo contrario, aparecerían todas las opciones en la
misma línea.
62
6 Botón de opción
Los botones permiten activar o desactivar las opciones que pongamos. En este caso, solo
podremos seleccionar una opción a la misma vez, con lo que se descartan las demás
posibilidades. Esta es la gran diferencia que tienen con las opciones anteriormente explicadas.
Día de la semana:<br>
Como hemos podido observar, la opción CHECKED sirve para marcar una opción por defecto.
En este caso, se marcará el sábado porque es donde hemos puesto un CHECKED.
7 Menu desplegable
En esta opción se puede seleccionar uno de los elementos de la lista desplegable. La etiqueta
<SELECT> crea el campo de selección y dentro del mismo se va añadiendo las diferentes
opciones disponibles con el parámetro <OPTION>.
63
Estudios:<br>
<SELECT NAME=”estudios”>
<OPTION SELECTED> ESO
<OPTION> Bachillerato
<OPTION> Ciclos Formativos
<OPTION>Garantía Social
</SELECT>
8 Botón de comando
Este botón es el encargado, cuando hacemos clic sobre él, de enviar los datos del formulario al
script especificado con el atributo Action indicado al principio.
9 Campo oculto
Estos campos se utilizan para añadir información dentro de un formulario, la cual permanece
oculta a la vista del usuario. Es muy útil para datos confidenciales, contraseñas, datos
bancarios… Con este tipo de campos, podemos almacenar variables internas que nos informan
de operaciones que el usuario ha realizado con anterioridad.
En este caso asignamos el valor de 900 a este campo, pero no lo podremos ver, ya que es un
campo oculto (hidden).
<HTML>
<BODY>
<FORM METHOD="post" ACTION="cuestionario.php">
64
<input type="hidden" name="edad" value="55">
<p>Nombre: <input type="text" name="nombre" size="30"></p>
<p>Apellidos: <input type="text" name="apellidos" size="50"></p>
<p>Ciudad: <input type="text" name="ciudad" size="15"></p>
<p>Deporte preferido
<blockquote>
<p><input type="radio" value="Masculino" checked name="sexo">Masculino</p>
<p><input type="radio" value="Femenino" name="sexo">Femenino</p>
</blockquote>
<p>Comentarios</p>
<p><textarea rows="7" name="comentarios" cols="30"></textarea></p>
<p><input type="submit" value="ENVIAR" name="enviar">
<input type="reset" value="LIMPIAR PANTALLA" name="Limpiar"></p>
</FORM>
</BODY>
<HTML>
<?php
echo "Nombre: $nombre <br>";
echo "Apellidos: $apellidos <br>";
echo "Ciudad: $ciudad <br>";
65
echo "Deporte: $deporte <br>";
echo "Aficiones: ";
$n=count($aficiones);
for($i=0; $i<=$n-1; $i++)
{
echo "$aficiones[$i] ";
}
echo "<br>";
echo "Sexo: $sexo <br>";
echo "Comentarios: $comentarios <br>";
?>
66
10 Práctica: Libro de visitas
LIBRO DE VISITAS:
En esta práctica, vamos a realizar un libro de visitas. En él, cualquier usuario debe
dejar escrito su nombre, el texto que deseen escribir y una dirección de correo
electrónico. El programa debe mostrar por pantalla algo parecido a lo que vamos a
ver a continuación:
67
<HTML>
<BODY>
<FORM action="visitas.php" METHOD="post">
Nombre: <INPUT TYPE="text" NAME="nombre" SIZE="20" />
<br><br>
Mensaje:
<TEXTAREA NAME="escribir" COLS="60" ROWS="7"></TEXTAREA>
<br><br>
Correo electrónico: <INPUT TYPE="text" NAME="url" SIZE="35" />
<br><br>
<INPUT TYPE="submit" NAME="enviar" VALUE="ENVIAR"/>
</FORM>
</BODY>
</HTML>
11 Práctica: Cuestionario
CUESTIONARIO:
68
Y si pulsamos el botón “VALIDAR” nos debe aparecer:
CUESTIONARIO.PHP
<HTML>
<BODY>
<FORM action="respuestas.php" METHOD="post">
1. ¿Cuál es la capital de España?.
<br>
<INPUT TYPE="radio" VALUE=" madrid " CHECKED NAME="capital"> Madrid <br>
<INPUT TYPE="radio" VALUE=" barcelona " NAME="capital"> Barcelona <br>
69
<INPUT TYPE="radio" VALUE="sevilla" NAME="capital"> Sevilla<br>
<br><br>
2. ¿Cuánto es 2 + 2?
<br>
<INPUT TYPE="radio" VALUE="tres" NAME="suma"> 3<br>
<INPUT TYPE="radio" VALUE="cuatro" NAME="suma"> 4<br>
<INPUT TYPE="radio" VALUE="cinco" CHECKED NAME="suma"> 5<br>
<br><br>
3. ¿De qué color es el agua.?
<br>
<INPUT TYPE="radio" VALUE="azul" NAME="color"> Azulvbr>
<INPUT TYPE="radio" VALUE="transparente" NAME="color"> Transparente<br>
<INPUT TYPE="radio" VALUE="verde" CHECKED NAME="color"> Verde<br>
<br><br>
<INPUT TYPE="submit" NAME="validar" VALUE="VALIDAR"/>
</FORM>
</BODY>
</HTML>
RESPUESTAS.PHP
<?php
if ($capital == "madrid")
{
echo "Respuesta 1 Correcta.<br>";
}
else
{
echo "Error!! Respuesta 1 Incorrecta.<br>";
}
if ($suma == "cuatro")
{
echo "Respuesta 2 Correcta.<br>";
}
else
{
echo "Error!! Respuesta 2 Incorrecta.<br>";
}
if ($color == "transparente")
{
echo "Respuesta 3 Correcta.<br>";
}
else
70
{
echo "Error!! Respuesta 3 Incorrecta.<br>";
}
?>
INDEX.PHP
<HTML>
<BODY>
<?php
//La función formulario define el formulario de solicitud.
function formulario()
{?>
<FORM ACTION=index.php METHOD=get>
Rellene el siguiente formulario: <BR><BR>
71
1. Nick <INPUT TYPE=TEXT NAME=nick><BR><BR>
2. Contraseña <INPUT TYPE=PASSWORD NAME=contraseña><BR><BR>
3. Estado civil <INPUT TYPE=RADIO NAME=civil VALUE=Casado CHECKED>Casado
<INPUT TYPE=RADIO NAME=civil VALUE=Soltero>Soltero<BR><BR>
4 Señale sus aficiones. <BR>
<INPUT TYPE=CHECKBOX NAME=afi[] VALUE=informática> Informática<BR>
<INPUT TYPE=CHECKBOX NAME=afi[] VALUE=deportes> Deportes<BR>
<INPUT TYPE=CHECKBOX NAME=afi[] VALUE=viajar> Viajar<BR>
<INPUT TYPE=CHECKBOX NAME=afi[] VALUE=música> Música<BR><BR>
5 Di algo de ti.<BR>
<TEXTAREA NAME=texto COLS=10 ROWS=5>
</TEXTAREA>
<INPUT TYPE=hidden NAME=continuar VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET> <INPUT TYPE=SUBMIT
NAME=mandar VALUE=MANDAR><BR><BR>
</FORM>
<?php }
//La función archivo añade la información del formulario a fichero.txt.
function archivo ($nick,$contraseña,$civil,$afi,$texto)
{ $descriptor=fopen("fichero.txt","a");
$elem=str_replace("\r\n","<BR>",$texto);
$p=fputs($descriptor, $nick."|".$contraseña."|".$civil."|");
if(!empty($afi))
{
for(reset($afi); current($afi)!=false; next($afi))
{
$v=current($afi);
fputs($descriptor,$v."|");
}
}
fputs($descriptor,$elem."\n");
echo "Información insertada con éxito.";
}
/*La primera vez que se ejecute el archivo no existirá la variable continuar y
mostrará el formulario. Al mandar el formulario ya existirá la variable continuar y
se ejecutará la función archivo.*/
if(!$continuar)
{
formulario();
}
else
{
archivo($nick,$contraseña,$civil,$afi,$texto);
72
}
?>
</BODY>
</HTML>
LEER FICHERO.PHP
<HTML>
</HEAD>
<?
$linea=file("fichero.txt");
echo count($linea);
for ($i=0; $i<=count($linea)-1; $i++)
{
$elementos=explode("|",$linea[$i]);
echo "$elementos[0]<BR>";
echo "$elementos[1]<BR>";
echo "$elementos[2]<BR>";
echo "$elementos[3]<BR>";
echo "$elementos[4]<BR>";
echo "$elementos[5]<BR>";
echo "$elementos[6]<BR>";
echo "$elementos[7]vBR>";
echo "<BR></P>";
}
?>
</FORM>
</BODY>
</HTML>
MySQL - Front es una sencilla aplicación diseñada especialmente para desarrolladores que
trabajan con MySQl. Desde el primer momento que empezamos a utilizar este administrador,
descubrimos su facilidad para obtener información de las bases de datos, tanto de sus tablas
como de su estructura y contenido. Todo ello, desde una interfaz muy intuitiva que tiene
mucha similitud al Explorador de Windows.
73
Con MySQL - Front podemos realizar las acciones más básicas, como añadir, modificar o borrar
tablas, campos, registros…
En esta unidad aprenderemos a utilizar este programa de forma general, deteniéndonos solo
en las opciones más útiles.
5 Creación de tablas
Las bases de datos se componen de tablas, y éstas a su vez son las que contienen los campos
que es donde se almacena toda la información de la base de datos. Toda la información
relativa a un mismo elemento contenida en una misma línea de una tabla se denomina
registro.
Cree una base de datos llamada “gestion” con una tabla llamada “cliente”
donde se almacenará información de supuestos clientes. Los campos de la
tabla deben ser:
74
CREATE TABLE `cliente` (`cod` int(11) NOT NULL auto_increment,
`nombre` varchar(20) NOT NULL default '',
`apellido1` varchar(15) NOT NULL default '',
`apellido2` varchar(15) NOT NULL default '',
`DNI` varchar(10) NOT NULL default '',
`civil` varchar(7) NOT NULL default '',
`domicilio` varchar(50) NOT NULL default '',
`localidad` varchar(15) NOT NULL default '',
`provincia` varchar(15) NOT NULL default '',
`empresa` varchar(30) NOT NULL default '',
`telff` bigint(11) NOT NULL default '0',
`telfm` bigint(11) NOT NULL default '0',
`fax` bigint(11) NOT NULL default '0',
`coment` varchar(254) default NULL,
PRIMARY KEY (`cod`)
) TYPE=MyISAM;
INSERT INTO cliente VALUES("2","Marta","González","Martín","14563325-H",
"casado","C/ Mendoza 9","Sevilla","Sevilla","Martín y asociados S.A.",
"954321175","959632166","954321175",""),
("1","Alberto","Ortega","García","14658812-J","soltero","C/ Carmona 4", "Sevilla",
"Sevilla","Soluciones Informáticas SL","954965522","659854222","0","");
1 Página principal
Creamos una primera página que contenga el índice con enlaces a los diferentes apartados de
nuestra Web de gestión. Esta página estará compuesta de código html en su totalidad y tendrá
de nombre index.php para que actúe como página principal.
INDEX:PHP
75
<!--Página principal con el menú de opciones.-->
<html>
<body>
<center><b><font color="#FF3300">ADMINISTRACIÓN DE CLIENTES</font></b>
</center><BR><P>
<center><a href="Temario/558/listacli.php"><B>LISTAR
CLIENTES</B></a></center><BR><P>
<center><a href="anadcli.php"><B>AÑADIR NUEVO
CLIENTE</B></a></center><BR> <P>
<center><a href="Temario/558/borracli.php"><B>BORRAR
CLIENTES</B></font></a></center><BR> <P>
<center><a href="Temario/558/modifcli.php"><B>EDITAR
CLIENTES</B></a></center><BR><P>
</body>
</html>
NOTA: Todos los códigos que se muestren en este tema con un nombre de archivo en su parte
inferior trabajan sobre la base de datos Gestión creada en los ejercicios del tema 9. Para su
correcto funcionamiento, deben guardarse en una misma carpeta con ese nombre y
ejecutarlos con EasyPHP activado y la base de datos correctamente creada. De esta manera, al
final tendremos una pequeña Web que gestiona esta base de datos.
mysql_connect (“Servidor”,”Usuario”,”Password”);
mysql_select_db (“Base de datos”);
Si el servidor es externo, debemos conocer los datos de conexión que se nos facilitarán al
realizar la contratación. Una posible conexión podría ser ésta.
<?php
mysql_connect ("215.155.16.89","user",”db99”);
mysql_select_db("gestion");
?>
<?php
mysql_connect ("localhost","root");
mysql_select_db("gestion");
?>
76
Cada una de estas funciones devuelve “1” si la operación se realiza con éxito. En cambio si hay
algún error no devuelve nada. Podemos controlar de esta forma que la conexión se realice
correctamente de la siguiente forma:
$c=mysql_connect("localhost","root");
if(!$c)
{
echo "<B><CENTER>Error al conectar con el servidor.</CENTER></B>\n";
exit;
}
$c2=mysql_select_db("gestion");
if(!$c2)
{
echo "<B><CENTER>Error al conectar con la base de datos.</CENTER></B>\n";
exit;
}
echo "<B><CENTER>Conexión correcta.</CENTER></B>\n";
<?php
$c=mysql_connect("localhost","root");
if(!$c){?>
<B><CENTER>Error al conectar con el servidor.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
$c2=mysql_select_db("gestion");
if(!$c2){?>
<B><CENTER>Error al conectar con la base de datos.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
?>
3 Introducir registros
Para crear un nuevo registro en la tabla cliente de nuestra base de datos, debemos generar la
información para después introducirla mediante una sentencia SQL que se envía mediante la
función mysql_query, cuya sintaxis es:
77
<html> <body>
<p align="center"><b><font color="#FF3300">ADMINISTRACIÓN DE
USUARIOS</font> </b><P>
<?php
//Definimos la función formulario que pedirá la información necesaria
function formulario ()
{
?>
<CENTER><FORM ACTION="anadcli.php" METHOD=POST>
include ("conectar.php");
78
civil,domicilio,localidad,provincia,empresa,telff,telfm,fax,coment) values
('$nombre',
'$ape1','$ape2','$dni','$civil','$domicilio','$localidad','$provincia','$empresa',
'$teleff','$telefm','$fax','$coment')",$c);
if($res==0){?>
}?>
{
formulario ();
}
else
{
anadir ($nombre,$ape1,$ape2,$dni,$civil,$domicilio,$localidad,$provincia,
$empresa,$teleff,$telefm,$fax,$coment);
}
?>
</body>
</html>
4 Listado de registros
Para elaborar un listado completo de la base de datos, realizamos una consulta SQL que
almacenará la información en una variable $res.
79
<html>
<body>
<p align="center"><b><font color="#FF3300">ADMINISTRACIÓN DE
USUARIOS</font> </b><P>
<?php
include ("conectar.php");
//Obtenemos la información con una consulta SQL.
$res=mysql_query("select * from cliente");
f($res==0)
{?>
<B><CENTER>Error al realizar el listado.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}?>
<CENTER><B>Listado de usuarios registrados.</B></CENTER><P>
$cod=$file["cod"];
$nombre=$file["nombre"];
80
$ape1=$file["apellido1"];
$ape2=$file["apellido2"];
$dni=$file["dni"];
$civil=$file["civil"];
$domicilio=$file["domicilio"];
$localidad=$file["localidad"];
$provincia=$file["apellido1"];
$empresa=$file["empresa"];
5 Borrado de registros
Una forma de realizar un borrado de registros es realizar un listado de clientes con un campo
checkbox de formulario que utilizaremos para indicar qué clientes deseamos eliminar. Después
se procederá al borrado con una sentencia SQL.
<html>
<body>
<p align="center"><b><font color="#FF3300">ADMINISTRACIÓN DE
USUARIOS</font> </b><P>
<?php
//Definimos la función mostrar que muestra la información de los clientes.
function mostrar()
{
$res=mysql_query("select * from cliente");
if($res==0)
{?>
<B><CENTER>Error al realizar el listado</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}?>
<B><CENTER>Seleccione el usuario que desee eliminar de la base de datos y pulse
'borrar'.
81
<FORM ACTION=borracli.php METHOD=GET>
<?php while($file=mysql_fetch_array($res))
{
$codigo=$file["cod"];
$dni=$file["dni"];
$nombre=$file["nombre"];
$ape1=$file["apellido1"];
$ape2=$file["apellido2"];
echo "<TR><TD align='center'><INPUT TYPE=CHECKBOX NAME=borrar[]
VALUE=$codigo></TD><TD align='center'><B><FONT
size='2'>$dni</FONT></B></TD> <TD align='center'><B><FONT
size='2'>$nombre</FONT></B></TD><TD align='center'> <B><FONT
size='2'>$ape1</FONT></B></TD><TD align='center'><B><FONT size='2'>
$ape2</FONT></B></TD></TR>";
}?>
</TABLE></B><P>
<INPUT TYPE=HIDDEN NAME=aux VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=enviar VALUE=BORRAR></CENTER>
<?php }
/*Definimos la función Borrar que elimina los clientes
seleccionados en el formulario anterior.*/
function borrar($borrar)
{
for($i=0; $i<=count($borrar)-1; $i++)
{
$res=mysql_query("DELETE FROM cliente WHERE cod='$borrar[$i]'");
if($res==0)
{?>
<B><CENTER>Error al realizar borrado.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
}?>
<CENTER><B>Los usuarios seleccionados han sido borrados
82
de la base de datos.</B><P>
<center><a href=index.php><b>Volver</b></a></center></CENTER>
<?php }
include ("conectar.php");<
</html>
6 Modificación de registros
Mediante un pequeño formulario pedimos el DNI de la persona cuyos datos deseamos
modificar, y con esta información listamos el mismo formulario que utilizamos en el proceso
de alta, pero con los campos rellenos con la información de la que disponemos.
Al pulsar el botón enviar, la nueva información irá a otro archivo que realizará la modificación
con una sentencia SQL.
MODIFCLI.PHP
<html>
<body>
<p align="center"><b><font color="#FF3300">ADMINISTRACIÓN DE
USUARIOS</font> </b><P>
<?php
83
<CENTER><INPUT TYPE=TEXT NAME=dni maxlength="10"></CENTER><P>
<INPUT TYPE=HIDDEN NAME=v VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
84
> maxlength="15"><BR>
<B>Segundo apellido</B> <INPUT TYPE=TEXT NAME=ape2 VALUE=<? echo
"'$ape2'";?> maxlength="15"><BR>
<?php if ($civil=="Casado")
{?>
<B>Estado Civil </B> <INPUT TYPE=radio NAME=civil VALUE=Soltero> Soltero
<INPUT TYPE=radio NAME=civil VALUE=Casado checked> Casado<BR>
<?php }
else
{?>
<B>Estado Civil </B> <INPUT TYPE=radio NAME=civil VALUE=Soltero checked>
Soltero
vINPUT TYPE=radio NAME=civil VALUE=Casado> Casado<BR>
<? } ?>
</TEXTAREA><BR>
<INPUT TYPE=HIDDEN NAME=v VALUE=<? echo "'$cod'"?>>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=añadir VALUE=MODIFICAR></FONT>
</FORM></CENTER>
<?php }
/*Si no existe $v se ejecutará la función funcionario que pedirá el DNI del cliente
85
a modificar y dará valor 1.
Si existe $v procederemos a mostrar un formulario con los datos del cliente a
modificar.*/
if(empty ($v))
{
formulario ();
}
else
{
modificar ($dni);
}
?>
</body>
</html>
MODIFCLI2.PHP
<html>
<body>
<p align="center"><b><font color="#FF3300">ADMINISTRACIÓN
DE USUARIOS</font> </b><P>
<?
include ("conectar.php");
//Realizamos las modificaciones pertienentes.
$res=mysql_query("update cliente set nombre='$nombre',
apellido1='$ape1',
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
?>
<B><CENTER>La modificación se ha realizado con
éxito.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
</body>
</html>
86
7 Práctica: Realizar un libro de visitas
LIBRO DE VISITAS:
Crea una base de datos llamada “librovisitas” con una tabla llamada “visitas” donde se
almacenará información de supuestos clientes. Los campos de la tabla deben ser:
CONECTAR.TXT
<?php
$c=mysql_connect("localhost","root");
if(!$c){?>
<B><CENTER>Error al conectar con el servidor.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
$c2=mysql_select_db("librovisitas");
if(!$c2){?>
<B><CENTER>Error al conectar con la base de datos.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
?>
ENVIARLV.PHP
87
<HTML>
<BODY>
<?
function formulario ()
{?>
<B><CENTER>Rellene los diferentes campos y pulse 'enviar'
<B>Cuerpo:<B><P>
<TEXTAREA NAME=cuerpo ROWS=10 COLS=45>
</TEXTAREA><P>
<INPUT TYPE=HIDDEN NAME=v VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=enviar VALUE=ENVIAR>
</FORM></CENTER>
<? }
function anadir ($nombre,$correo,$web,$fecha,$asunto,$cuerpo)
{
//Todos los saltos de línea serán convertidos a etiquetas <br /> como datos de la
variable.
$cuerpo=nl2br($cuerpo);
include ("conectar.txt");
$res=mysql_query("insert into visitas (Nombre,Correo,Web,Fecha,Asunto, Cuerpo)
values ('$nombre','$correo','$web','$fecha','$asunto','$cuerpo')",$c);
if($res==0)
{?>
88
Gracias por escribir en nuestro libro de visitas.<P>
<A HREF=index.php>Volver</A></B></CENTER>
<?php }
if(empty ($v))
{
formulario ();
}
else
{
anadir ($nombre,$correo,$web,$fecha,$asunto,$cuerpo);
}
?>
</BODY>
</HTML>
VERLV.PHP
<HTML>
<BODY>
<?
include ("conectar.txt");
$res=mysql_query("select * from visitas order by Codigo desc",$c);
if($res==0)
{?>
<B><CENTER>Error al seleccionar la información.</CENTER>< /B><P>
<center><a href=index.php>< b>Volver< /b></a></center>
<?php exit;
}?>
<?php
while($file=mysql_fetch_array($res))
{
$cod=$file["Codigo"];
$nombre=$file["Nombre"];
$correo=$file["Correo"];
$web=$file["Web"];
$fecha=$file["Fecha"];
$asunto=$file["Asunto"];
$cuerpo=$file["Cuerpo"];
?>
<CENTER><TABLE width='90%'><TR><TD>
< B><CENTER><FONT color='#FF0000'><?php echo "$asunto";?></FONT>
</CENTER>
89
<?php if(!empty($correo))
{?>
<CENTER><B>Escrito por <A HREF="Temario/558/mailto:<?php echo $correo;?>">
<?php echo "$nombre";?></A>
el <?php echo $fecha;?></B></CENTER>
<?php }
else
{?>
<CENTER><B>Escrito por <?php echo "$nombre";?> el <?php echo $fecha;?
></B></CENTER>
<?php }
if($web!="http://" && !empty($web))
{?>
<B><CENTER>Web: <A HREF=<? echo "$web";?> target='_blank'><? echo "$web";?
></A>
</CENTER></B>
<?php } ?>
</TD></TR><TR>
<TR><TD><B><CENTER>
<?php echo "$cuerpo";?><CENTER></B></TD></TR>
</TABLE></CENTER><P>
<?php
}
?>
<B></P><center><a href=index.php><b>Volver</b></a></center>
</BODY>
</HTML>
BORRARLV.PHP
<HTML>
<BODY>
<?php
function mostrar()
{?>
90
if($res==0)
{?>
< B>< CENTER>Error al seleccionar la información.< /CENTER> < /B>< P>
< center>< a href=index.php>< b>Volver< /b>< /a>< /center>
<?php exit;
}?>
<FORM ACTION=borrarlv.php METHOD=GET>
</TABLE></B><P>
<INPUT TYPE=HIDDEN NAME=aux VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=enviar VALUE=BORRAR></CENTER>
<?php }
function borrar($borrar)
{
include ("conectar.txt");
for($i=0; $i<=count($borrar)-1; $i++)
{ $res=mysql_query("DELETE FROM visitas WHERE Codigo='$borrar[$i]'",$c);
if($res==0)
{?>
<B><CENTER>Error al realizar el borrado.< /CENTER>< /B>< P>
91
<a href=index.php>< b>Volver </b></a></CENTER>
<?php }
if(empty ($aux))
{
mostrar();
}
else
{
borrar($borrar);
}
?>
</BODY>
</HTML>
MODIFLIL.PHP
<HTML>
<BODY>
<?php
function mostrar()
{?>
<B><CENTER>Seleccione el comentario que desee
modificar de la base de datos y pulse sobre el botón 'modificar'.
</CENTER></B>
<?php include ("conectar.txt");
$res=mysql_query("select * from visitas order by Codigo Desc",$c);
if($res==0)
{?>
<B><CENTER>Error al seleccionar la información.</CENTER> </B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}?>
<FORM ACTION=modiflv.php METHOD=GET>
<CENTER><TABLE width='60%' border=1><TR><TD align='center'>
<B>MARCAR</B></TD>
<TD align='center'><B>ASUNTO</B></TD><br> <TD
align='center'><B>FECHA</B></TD></TR>
<?php while($file=mysql_fetch_array($res))
{
$codigo=$file["Codigo"];
$titulo=$file["Asunto"];
$fecha=$file["Fecha"];
92
?> <TR><TD align='center'><INPUT TYPE=RADIO NAME=modificar VALUE=<?
php echo $codigo;?>></TD>
<TD align='center'><B><?php echo "$titulo";?></B></TD>
<TD align='center'><B><?php echo $fecha;?></B></TD></TR>
<?php } ?>
</TABLE></B><P>
<INPUT TYPE=HIDDEN NAME=aux VALUE=1>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=enviar VALUE=MODIFICAR></CENTER>
<?php }
function formulario($modificar)
{
include ("conectar.txt");
if (!$modificar)
{
?>
<B><CENTER>No se ha seleccionado elemento para modificar.
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
$res=mysql_query("select * from visitas where Codigo=$modificar",
$c);
if($res==0)
{?>
<B><CENTER>Error al seleccionar la información.</CENTER>
</B><P>
<center><a href=index.php><b>Volver</b></a></center><br>
<?php exit;
}
$file=mysql_fetch_array($res);
$cod=$file["Codigo"];
$nombre=$file["Nombre"];
$correo=$file["Correo"];
$web=$file["Web"];
$fecha=$file["Fecha"];
$asunto=$file["Asunto"];
$cuerpo=$file["Cuerpo"];
?>
93
<B>Correo electrónico</B> <INPUT TYPE=TEXT NAME=correo
SIZE=20 value=<?php echo "'$correo'";?>><P>
<B>Página web</B> <INPUT TYPE=TEXT NAME=web VALUE=<?php
echo "'$web'"?> SIZE=30><P>
<B>Fecha:</B> <INPUT TYPE=TEXT NAME=fecha VALUE="<?php
echo "$fecha";?>" SIZE=10><P>
<B>Asunto</B> <INPUT TYPE=TEXT NAME=asunto value=<?php
echo "'$asunto'";?>><P>
<B>Cuerpo:<B><P>
<TEXTAREA NAME=cuerpo ROWS=10 COLS=45>
<?php echo "$cuerpo";?>
</TEXTAREA><P>
<INPUT TYPE=HIDDEN NAME=v VALUE=<?php echo "$cod";?>>
<INPUT TYPE=RESET NAME=reset VALUE=RESET>
<INPUT TYPE=SUBMIT NAME=enviar VALUE=MODIFICAR>
</FORM></CENTER>
<? }
if(empty ($aux))
{
mostrar();
}
else
{
formulario($modificar);
}
?>
</BODY>
</HTML>
MODIFLIL2.PHP
<HTML>
<BODY>
<?
include ("conectar.txt");
$res=mysql_query("update visitas set Nombre='$nombre',
Correo='$correo', Web='$web', Fecha='$fecha',
Asunto='$asunto', Cuerpo='$cuerpo' where Codigo='$v'");
if(!$res){?>
<B><CENTER>Error al modificar la información.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}
?>
<B><CENTER>La modificación se ha realizado con éxito.</CENTER></B><P>
<center><a href=index.php><b>Volver</b></a></center>
94
</body>
</html>
95
Tema 1: Comenzando con cakephp
1 Que es cakephp y por que hay que utilizarlo
CakePHP es un marco de desarrollo [framework] rápido para PHP, libre, de código abierto. Se
trata de una estructura que sirve de base a los programadores para que éstos puedan crear
aplicaciones Web. Nuestro principal objetivo es que puedas trabajar de forma estructurada y
rápida, sin pérdida de flexibilidad.
Con CakePHP el desarrollo web ya no es monótono porque ofrecemos las herramientas para
que empieces a escribir el código que realmente necesitas: la lógica específica de tu aplicación.
Consigue una copia de CakePHP, empieza con lo verdaderamente importante y no reinventes
la rueda cada vez que te incorpores a un nuevo proyecto.
CakePHP tiene un equipo de desarrolladores y una comunidad activos, lo que añade valor al
proyecto. Con CakePHP, además de no tener que reinventar la rueda, el núcleo de tu
aplicación se mejora constantemente y está bien probado.
Esta es una lista breve con las características de las que disfrutarás al utilizar CakePHP:
Nota: Es necesario montar un servidor de aplicaciones PHP con las librerías propias de Cake
PHP. Para ello, puedes descargar el software (servidor de PHP) y el entorno framework (Cake
PHP).
2 Entendiendo modelo-vista-controlador
Las aplicaciones CakePHP bien escritas siguen el patrón de diseño de software MVC (Modelo-
Vista-Controlador). Programar utilizando MVC consiste en separar la aplicación en tres partes
principales. El modelo representa los datos de la aplicación, la vista hace una presentación del
modelo de datos, y el controlador maneja y enruta las peticiones [requests] hechas por los
usuarios.
96
Figura 1: Una petición MVC básica
La figura 1 muestra un ejemplo sencillo de una petición [request] MVC en CakePHP. A efectos
ilustrativos, supongamos que un usuario llamado Ricardo acaba de hacer clic en el enlace
"¡Comprar un pastel personalizado ahora!" de la página de inicial de la aplicación.
Casi todas las peticiones a tu aplicación seguirán este patrón básico. Más adelante, vamos a
completar algunos detalles específicos de Cake, así que, por favor, ten esto en cuenta a
medida que avanzamos.
3 Beneficios mvc
¿Por qué utilizar MVC? Porque es un patrón de diseño de software probado y se sabe que
funciona. Con MVC la aplicación se puede desarrollar rápidamente, de forma modular y
mantenible. Separar las funciones de la aplicación en modelos, vistas y controladores hace que
97
la aplicación sea muy ligera. Estas características nuevas se añaden fácilmente y las antiguas
toman automáticamente una forma nueva.
Aunque lleva algún tiempo acostumbrarse a construir aplicaciones así, estamos seguros de
que, una vez construyas tu primera aplicación con CakePHP, no querrás volver a hacerlo de
otra forma.
Los Controladores también están equipados con callbacks (rellamadas). Puedes utilizar estos
callbacks si necesitas insertar alguna lógica en las operaciones del núcleo de CakePHP. Los
Callbacks disponibles incluyen:
La mayoría de las aplicaciones repiten piezas de código en sus vistas. CakePHP facilita la
reutilización de este código con diseños [layouts] y elementos [elements]. Por defecto, toda
vista renderizada por un controlador se coloca en un diseño [layout]; los elementos entran en
juego cuando hay que reutilizar estos fragmentos pequeños de contenido.
98
Extensiones de los Modelos
Del mismo modo, los Comportamientos [Behaviors] son formas de añadir funcionalidad común
entre los modelos. Por ejemplo, si almacena datos de los usuarios en una estructura de árbol,
puede especificar que su modelo de usuario se comporte como un árbol, y obtener libre
funcionalidad para eliminar, añadir, y mover nodos en la estructura de árbol subyacente.
Los modelos también cuentan con el apoyo de otra clase llamada DataSource (Origen de
datos). Los DataSources son una abstracción que permite a los modelos manipular diferentes
tipos de datos en forma consistente. Si bien la principal fuente de datos en una aplicación
CakePHP es a menudo una base de datos, puede escribir DataSources adicionales que les
permitan a sus modelos representar canales RSS, archivos CSV, entradas LDAP, o eventos iCal.
Los DataSources le permiten asociar registros de diferentes fuentes: en lugar de limitarse sólo
a uniones [joins] SQL, los DataSources le permiten decirle a su modelo LDAP que está asociado
a muchos eventos iCal.
beforeFind()
afterFind()
beforeValidate()
beforeSave()
afterSave()
beforeDelete()
afterDelete()
Los nombres de estos métodos deben ser lo suficientemente descriptivos para que sepa lo que
hacen. Asegúrese de obtener los detalles en el capítulo acerca de los modelos.
Extensiones de la Aplicación
Tanto los controladores como los ayudantes [helpers] y modelos tienen una clase padre que
puede usarse para definir cambios a nivel global de la aplicación. AppController (localizado
en /app/app_controller.php), AppHelper (localizado en /app/app_helper.php) y AppModel
(localizado en /app/app_model.php) son magníficos lugares donde colocar métodos que desee
compartir entre todos los controladores, ayudantes [helpers] o modelos.
Las rutas juegan un rol en las peticiones hechas a CakePHP. Las definiciones de rutas le dicen a
CakePHP cómo mapear URLs a acciones de controladores. El comportamiento por defecto
asume que la URL "/controller/action/var1/var2/" mapea a Controller::action($var1, $var2),
pero puede usar rutas para personalizar URLs y la forma en que éstas son interpretadas por su
aplicación.
Algunas características en una aplicación merecen ser empaquetadas como un todo. Un plugin
es un paquete de modelos, controladores y vistas que cumplen un propósito específico que
puede abarcar múltiples aplicaciones. Un sistema de administración de usuarios o un blog
simplificado pueden ser buenos ejemplos para plugins de CakePHP.
99
"¡Comprar un pastel personalizado ahora!" en una página de bienvenida de una aplicación
CakePHP.
100
elementos y/o ayudantes [helpers]. Por defecto, la vista es creada dentro del diseño
[layout].
Callbacks del controlador adicionales (como afterFilter) pueden ser aplicados. El código
completo creado por la vista es enviado al navegador de Ricardo.
App
Cake
Vendors
.htaccess
index.php
README
La carpeta app será donde haremos nuestra magia: es donde se ubicarán los ficheros
de tu aplicación.
La carpeta cake es donde nosotros hemos hecho nuestra magia. Comprométete a no
modificar los ficheros de esta carpeta. No podremos ayudarte si has modificado el
núcleo.
Finalmente, la carpeta vendors es donde ubicarás las librerías PHP de terceros que
necesites usar con tus aplicaciones en CakePHP.
La Carpeta App
La carpeta app de CakePHP es donde realizarás la mayor parte del desarrollo de tu aplicación.
101
4 Convenciones de cakephp
Con las convenciones de CakePHP, usted ahorrará tiempo sobre la marcha: siguiendo las
convenciones, obtendrá libre funcionalidad, y también se libera de la pesadilla del
mantenimiento del seguimiento de los archivos de configuración. Las convenciones también
hacen un sistema de desarrollo muy uniforme, permitiendo a otros desarrolladores ayudar
más fácilmente.
Las convenciones de CakePHP han sido destiladas de años de experiencia en desarrollo web y
mejores prácticas. Mientras que le sugerimos el uso de estas convenciones durante el
desarrollo con CakePHP, deberíamos mencionar que muchos de estos postulados pueden ser
anulados, esto es especialmente útil cuando se trabaja con sistemas heredados.
Sin embargo, el nombre de la clase que contiene un archivo puede no necesariamente ser
encontrada en el nombre de archivo. La clase EmailComponent es encontrada en un archivo
llamado email.php, y la clase HtmlHelper es encontrada en un archivo llamado html.php.
102
Convenciones de Modelo y de la Base de datos
Los nombres de las clases de modelos están en singular y en formato CamelCase. Persona,
PersonaGrande, y PersonaMuyGrande son todos ejemplos de nombres de modelos
convencionales.
Los nombres de las tablas correspondientes a modelos de CakePHP están en plural y usando
guion bajo. Las tablas subyacentes para los modelos arriba mencionados serían: personas,
personas_grandes, y personas_muy_grandes respectivamente.
Los nombres de los campos con dos o más palabras se definen con guiones bajos:
nombre_y_apellidos.
El nombre por defecto de las claves foráneas en relaciones hasMany, belongsTo o hasOne, es
el nombre de la tabla relacionada (en singular) seguido de _id. Así, si Panadero hasMany Tarta,
la tabla tartas referenciará la tabla panaderos mediante la clave foránea panadero_id. Para
una tabla compuesta por varias palabras como tipos_categorias, la clave foránea sería
tipo_categoria_id.
Todas las tablas con las que interaccionan los modelos de CakePHP (con excepción de las de
unión de tablas) necesitan una clave primaria simple que identifique inequívocamente cada
fila. Si deseas modelar una tabla que no tiene una clave primaria de un sólo campo, como por
ejemplo las filas de una tabla de unión posts_tags, la convención de CakePHP dicta que se
añada una clave primaria de un solo campo a la tabla.
CakePHP no soporta claves primarias compuestas. Si deseas manipular directamente los datos
de tu tabla de unión, usa llamadas directas a query o añade una clave primaria para que actué
como un modelo normal. Por ejemplo:
CREATE TABLE posts_tags ( id INT(10) NOT NULLAUTO_INCREMENT,
post_idINT(10) NOT NULL, tag_idINT(10) NOT NULL, PRIMARY KEY(id) );
En vez de utilizar una clave autoincremental como clave primaria, puedes utilizar char(36). De
este modo CakePHP utilizará un uuid(String::uuid) único de 36 caracteres siempre que grabes
un nuevo registro utilizando el método Model::save.
Convenciones de Controladores
Los nombres de las clases de los controladores son en plural, con formato CamelCased, y
Terminan en Controller. PersonasController y UltimosArticulosController son ejemplos de
nombres convencionales de controladores.
El primer método que escribas para un controlador debe de ser el método index(). Cuando la
petición especifica un controlador pero no una acción, el comportamiento por defecto de
CakePHP es ejecutar el método index() de dicho controlador. Por ejemplo, una petición de
http://www.example.com/apples/ se corresponde con la llama al método index() del
controlador ApplesController, mientras que http://www.example.com/apples/view se
corresponde con una llamada al método view() del controlador ApplesController.
103
por un guion bajo, el método no será accesible directamente desde la web, sino que estará
disponible sólo para uso interno. Por ejemplo:
<?php class NoticiasController extends AppController { function
ultimas() { $this->_buscaNuevosArticulos(); } function
_buscaNuevosArticulos() { //Lógica para encontrar los nuevos
artículos. } } ?>
/redApples
/RedApples
/Red_apples
/red_apples
Todas resuelven la acción index de controlador RedApples. Sin embargo, la convención es que
las urls sean en minúsculas y separadas con guion bajo, por lo tanto /red_apples/go_pick es la
forma correcta de acceder a la acción. RedApplesController::go_pick.
Convenciones de Vistas
Los archivos de plantillas de Vistas (Views) deben ser nombradas después de las funciones de
los controladores con guion bajo "_". La función getReady() del controlador PeopleController
se visualizara con la plantilla de vista en /app/views/people/get_ready.ctp por ejemplo.
Al nombrar las piezas de su aplicación utilizando las convenciones de CakePHP, usted adquiere
funcionalidad sin mucho mantenimiento de la configuración. Aquí encontramos un ejemplo
final de las convenciones:
104
Tema 3: Desarrollando con cakephp
1 Requerimientos
Servidor HTTP. Por ejemplo: Apache. Preferiblemente con
mod_rewrite, pero no requerido.
PHP 4.3.2 o superior. Si, CakePHP funciona genial en
PHP 4 y 5.
Técnicamente no se requiere un motor de base de datos, pero nos imaginamos que la mayoría
de las aplicaciones usarán uno. CakePHP soporta una gran variedad de motores de
almacenamiento:
MySQL (4 o superior)
PostgreSQL
Firebird DB2
Microsoft SQL Server
Oracle
SQLite
ODBC
ADOdb
Descargue CakePHP.
Configure su servidor para manejar php si es necesario.
Chequee los permisos de los archivos.
Obteniendo CakePHP
Hay dos principales maneras de obtener una copia limpia de CakePHP. Puedes descargar una
copia comprimida (zip/tar.gz/tar.bz2) de la página web principal, o puedes obtener el código
desde el repositorio git.
Todas las releases actuales están alojadas en CakeForge. Este site también contiene enlaces a
muchos otros proyectos en CakePHP, incluyendo plugins y aplicaciones para CakePHP. Las
releases de CakePHP estásn disponibles en http://cakeforge.org/projects/cakephp.
Se crean nightlybuilds alternativas que incluyen parches y mejoras al minuto (bueno, al día).
105
Permisos
CakePHP usa el directorio /app/tmp para diferentes operaciones, como almacenar
descripciones de los modelos, vistas en cache, información de sesiones, entre otros.
Por ello, asegúrate que el directorio /app/tmp de tu instalación de Cake tenga permisos de
escritura por el usuario del servidor web.
Nota: Es necesario montar un servidor de aplicaciones PHP con las librerías propias de Cake
PHP. Para ello, puedes descargar el software (servidor de PHP) y el entorno framework (Cake
PHP).
3 Instalación
Instalar CakePHP puede ser tan simple como colocar el directorio en el servidor, o tan
complejo y flexible como necesites. Esta sección cubrirá los tres tipos principales de instalación
para CakePHP: desarrollo, producción y avanzado.
Desarrollo: fácil para iniciar, los URL de la aplicación incluyen el nombre del directorio,
y es menos seguro.
Producción: Requiere la capacidad de configurar el servidor web para definir el
"document root", muy seguro.
Avanzado: Con cierta configuración, permite ubicar los directorios clave de CakePHP
en diferentes partes del sistema de archivos, para compartir una misma instalación de
CakePHP para varias aplicaciones.
Desarrollo
Usar una instalación de desarrollo es el método más rápido para montar Cake. Este ejemplo te
ayudará a instalar una aplicación de CakePHP y hacerla disponible en
http://www.ejemplo.com/cake_1_2/. Asumimos para el fin de este ejemplo que tu raíz de
documentos está establecido a /var/www/html.
Descomprime los contenidos del archivo Cake en /var/www/html. Ahora tienes una carpeta en
tu raíz de documentos con un nombre dependiente de la versión que te has descargado (p.ej.
cake_1.2.0.7962). Renombra esta carpeta a cake_1_2. Tu configuración de desarrollo será
como la siguiente en el sistema de archivos:
/var/www/html
cake_1_2
/app
/cake
/vendors
.htaccess
/index.php
README
Producción
Una instalación de producción es una manera más flexible de instalar Cake. Usar este método
permite que un dominio entero se comporte como una aplicación CakePHP única. Este
ejemplo te ayudará a instalar Cake en cualquier sitio de tu sistema de ficheros y ponerlo
disponible en http://www.ejemplo.com. Tener en cuenta que esta instalación puede requerir
los privilegios para cambiar el DocumentRoot (raíz de documentos) en servidores web Apache.
106
Descomprime los contenidos del archivo Cake en un directorio a tu elección. Por motivos de
ejemplo, asumimos que escoges instalar Cake en /cake_install. Tu configuración de producción
se verá de la siguiente manera en el sistema de ficheros:
/cake_install/
/app
/webroot (este directorio es el establecido con la directiva DocumentRoot)
/cake
/vendors
/.htaccess
/index.php
/README
Los desarrolladores que usan Apache deberán establecer la directiva DocumentRoot para el
dominio a: DocumentRoot /cake_install/app/webroot.
Aquí hay unas cuantas cosas que puedes probar para conseguir que funcione correctamente.
Primero mira en tu httpd.conf (asegúrate de estar editando el httpd.conf del sistema y que no
es httpd.conf específico de un usuario o del site).
Tras realizar los cambios reinicia Apache para estar seguro de que las opciones de
configuración están activas.
Asegúrate de que tus ficheros .htaccess están en los directorios correctos. Esto puede
pasar durante la copia porque algunos sistemas operativos consideran los archivos que
comienzan por '.' como ocultos y por lo tanto no los copian.
3. Asegúrate de que tu copia de CakePHP es de las sección de descargas de nuestro site o
nuestro repositorio GIT, y que ha sido desempaquetado correctamente verificando
que existen los ficheros .htaccess.
107
En el directorio raíz de Cake (necesita ser copiado al directorio, esto redirige todo a tu
aplicación de Cake):
<IfModulemod_rewrite.c> RewriteEngine on RewriteRule ^$
app/webroot/ [L] RewriteRule (.*) app/webroot/$1 [L] </IfModule>
En el directorio app de Cake (será copiado por bake):
<IfModulemod_rewrite.c> RewriteEngine on RewriteRule ^$ webroot/
[L] RewriteRule (.*) webroot/$1 [L] </IfModule>
En el directorio webroot de Cake (será copiado a tu webroot de la aplicación por
bake):
<IfModulemod_rewrite.c> RewriteEngine On RewriteCond %
{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule^(.*)$ index.php?url=$1 [QSA,L] </IfModule>
Esto puede ser añadido a la misma sección con la directiva RewriteEngine, así, por
ejemplo, tu archivo .htaccess en el webroot debería ser así:
<IfModulemod_rewrite.c> RewriteEngine On RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %
{REQUEST_FILENAME} !-f RewriteRule^(.*)$ index.php?url=$1
[QSA,L] </IfModule> <IfModulemod_rewrite.c> RewriteEngine On
RewriteBase / RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %
{REQUEST_FILENAME} !-f RewriteRule^(.*)$ index.php?url=$1
[QSA,L] </IfModule>
Los detalles de esos cambios dependen de tu configuración, y pueden incluir cosas
adicionales que no están relacionadas con Cake. Consulta la documentación online de
Apache para más información.
# desactivadas en dicho directorio (y sus subdirectorios). # #
Primero, configuramos "por defecto" para que sea un conjunto de
# características muy generales. # <Directory />
OptionsFollowSymLinks AllowOverrideAll # Orderdeny,allow #
Denyfromall </Directory>
4 Enciendelo
Muy bien, ahora veamos a CakePHP en acción. Dependiendo de la configuración que hayas
usado, deberías apuntar tu navegador a http://example.com/ o
http://example.com/mi_aplicacion/. En este punto, se te presentará la vista de bienvenida de
CakePHP por omisión, y un mensaje que indica el estado de conexión con la base de datos.
5 Configuración
Configurar aplicaciones CakePHP es pan comido. Después de instalar CakePHP, crear una
aplicación web básica sólo requiere aplicar la configuración de una base de datos. Existen,
otras configuraciones opcionales, que puedes realizar con el objetivo de aprovechar las
108
ventajas de la arquitectura flexible de CakePHP. Puedes agregar fácilmente elementos al
núcleo de CakePHP, configurar URL personalizadas y definir inflexiones.
Rellena cada para clave/valor en el arreglo de configuración, como mejor se ajuste a tus
necesidades:
Nota que los prefijos son para las tablas, no para los modelos. Por ejemplo, si creaste una tabla
join para tus modelos Torta y Sabor, esta debe llamarse prefijo_sabor_torta (no
prefijo_sabor_prefijo_torta), y asignar la clave prefix con ‘prefijo_’.
Nombrar correctamente tus tablas (y algunas columnas) según las convenciones pueden
librarte de mucho trabajo de configuración. Por ejemplo, si nombras una tabla como tortas, el
modelo Torta y el controller TortasController, todo funcionará automáticamente si necesidad
de tu intervención. Por convención, utiliza guiones bajos, minúsculas, y nombres en plural para
los nombres de tus tablas - por ejemplo: reposteros, reposterias, sabores.
109
Configuración del Core
La configuración de la aplicación en CakePHP se encuentra en /app/config/core.php. Este
archivo es una colección de definiciones de variables Configure y definiciones de constantes
que determinan como ha de comportarse la aplicación. Descripción de cada variable y cómo
afecta tu aplicación CakePHP:
110
La clase Configure puede ser utilizada para leer y escribir valores durante la ejecución del
programa. Esto puede ser especialmente útil si desea deshabilitar el nivel de deburacion
("debug") para una sección limita de lógica en tu aplicación.
http://example.com/controlador/accion/param1/param2/param3
Algunos ejemplos que resuman las rutas por defecto pueden resultar útil.
111
Tema 4: Controladores
1 Introducción
Un controlador (Controller) se usa para manejar la lógica de cierta sección de su aplicación.
Comúnmente, los controladores (Controllers) son usados para manejar la lógica de un solo
modelo (Model). Por ejemplo, si estás construyendo un sitio de una pastelería, podrías tener
un RecetasController y un IngredientesController para manejar las recetas y sus ingredientes.
En CakePHP, los controladores se nombran según el modelo que manejan, y se ponen siempre
en plural.
Los controladores pueden tener cualquier cantidad de métodos a los que normalmente se les
llama acciones. Las acciones son métodos de controladores en tu aplicación web para mostrar
vistas. Una acción es un único método de un controlador. El Dispatcher de CakePHP ejecuta
acciones cuando una solicitud entrante contiene en su URL el nombre de una acción del
controlador. El controlador estaría ubicado en /app/controllers/recetas_controller.php con el
siguiente contenido:
<?php # /app/controllers/recetas_controller.php classRecetasController
extends AppController { function ver($id) { //la lógica de la acción
va aquí... } function compartir($cliente_id, $receta_id) { //la lógica
de la acción va aquí... } function buscar($query) { //la lógica de la
acción va aquí... } } ?>
2 App controller
La clase AppController es la clase superior a todos los controladores de tu aplicación.
AppController extiende la clase Controller incluida en la librería base de CakePHP. Así,
AppController es definida en /app/app_controller.php como:
<?php class AppController extends Controller { } ?>
Las propiedades y métodos creados en tu AppController estarán disponibles para todos los
controladores de tu aplicación. Es el sitio ideal para poner el código que será común a todos
los controladores de tu aplicación. Los Componentes (los cuales veremos después) son lo más
utilizado para el código que se utiliza en la mayoría (pero no necesariamente en todos) los
controladores.
Cuando se aplica la herencia a los objetos, CakePHP también realiza un trabajo extra cuando
existen atributos especiales en el controlador, como una lista de componentes o ayudantes
utilizados por un controlador. En estos casos, los arrays del AppControler son combinados con
los arrays de la clase hijo.
112
Atributos del Controlador
Para ver la lista completa de atributos visite la API de CakePHP.
$name
Los usuarios de PHP4 deberían empezar la definición de sus controladores con el atributo
$name. Este atributo debería ser asignado con el nombre del controlador. Usualmente este es
simplemente el plural del modelo principal al que el controlador está asociado. Esto previene
algunos problemas de distinción de mayúsculas que tiene PHP4 para los nombres de las clases.
<?php # $name Ejemplo de uso del atributo $name classRecetasController
extends AppController { var $name = 'Recetas'; } ?>
Los controladores tienen acceso a su modelo primario disponible por defecto. Nuestro
RecipesController tendrá disponible la clase modelo Recipe en $this->Recipe, y nuestro
ProductsController también posee el modelo Product en $this->Product.
Los ayudantes (Helpers) Html, Form, y Session están siempre disponibles por defecto, como lo
es SessionComponent.
Veamos cómo decirle a un controlador de CakePHP que planeas utilizar clases MVC
adicionales.
<?php class RecipesController extends AppController { var $name =
'Recipes'; var $uses = array('Recipe', 'User') ; var $helpers =
array('Ajax') ; var $components = array('Email') ; } ?>
Cada una de estas variables es fusionada con sus valores heredados, por lo tanto no es
necesario por ejemplo) declarar le ayudante (helper) Form, o cualquier cosa que es declarada
en tu controlador App.
También puedes cambiar el título de la página (que está localizado en la barra en la parte
superior de tu navegador) utilizando $pageTitle. Para que esto funcione apropiadamente, tu
113
diseño (layout) necesita incluir la variable $title_for_layout como mínimo entre las etiquetas
en la cabecera del documento HTML.
<?php // Usando <em>$pageTitle</em> para definir el título de la
página class RecipesController extends AppController
{ functionquickSave() { $this->pageTitle = 'Mi título del motor de
búsquedas optimizado'; } } ?>
También puedes establecer el título desde la vista (view) usando $this->pageTitle (Has de
incluir la parte $this->; se recomienda, ya que separa la lógica del diseño y el contenido). Para
una página estática has de usar $this->pageTitle en la vista si quieres un título personalizado.
Form
$this->params['form']
Admin
$this->params['admin']
isAjax
$this->params['ajax']
Almacena un 1 si la petición actual es una llamada ajax; 0 si no. Esta variable sólo se establece
si el componente RequestHandler es usado en el controlador.
Controller
$this->params['controller']
Almacena el nombre del controlador actual que está sirviendo la petición. Por ejemplo, si fue
pedida la URL /posts/view/1, $this->params['controller'] será igual a "posts".
Action
$this->params['action']
Pass
$this->params['pass']
Almacena la cadena de consulta GET enviada con la petición actual. Por ejemplo, si fue pedida
la URL /posts/view/?var1=3&var2=4, entonces $this->params['pass'] será igual a "?
var1=3&var2=4".
114
url
$this->params['url']
Almacena la URL actual pedida, junto con los pares clave-valor de variables get. Por ejemplo, si
se llamó a la URL /posts/view/?var1=3&var2=4, entonces $this->params['url'] debería
contener:
[url] => Array ( [url] =>posts/view [var1] => 3 [var2] => 4 )
Data
$this->data
Usado para manejar datos POST enviados desde los formularios de FormHelper al controlador.
// El helper FormHelper es usado para crear un elemento de formulario:
$form->text('User.first_name') ;
Cuando el formulario es enviado al controlador mediante POST, los datos aparecen en this-
>data
// El valor first_name enviado se puede encontrar aquí: $this-
>data['User']['first_name'] ;
Prefix
$this->params['prefix']
Establecido al prefijo de enrutado. Por ejemplo, este atributo contendría la cadena "admin"
durante una petición a /admin/posts/someaction.
Named
$this->params['named']
Otros Atributos
Aunque puedes ojear todos los detalles para todos los atributos del controlador en el API, hay
otros atributos del controlador que merecen sus propias secciones en el manual.
persistModel
Usado para crear instancias almacenadas en caché de modelos (Models) un uso de
Controlador (Controller). Cuando se coloca en verdadero (true), todos los modelos
relacionados con el controlador (Controller) se almacenan en caché. Esto puede incrementar el
desempeño en muchos casos.
115
3 Métodos del controlador
Para una lista completa de los métodos del controlador y sus descripciones visita el API de
CakePHP.
El método set() es la principal manera de enviar datos desde tu controlador a tu vista (view).
Una vez que has utilizado set(), la variable puede ser accedida en tu vista.
<?php
$this->set('color', 'azul') ;
?>
El método set() también toma una array asociativo como primer parámetro. A menudo, esto
puede ser una manera rápida de asignar un conjunto de información a la vista.
Las claves (keys) serán flexionadas (inflected) antes de ser asignadas a la vista
('clave_con_subrayado' se convierte en 'claveConSubrayado', etc. ):
<?php $data = array( 'color' => 'pink', 'type' => 'sugar',
'base_price' => 23.95 ) ; // hace que $color, $type, y $basePrice //
estén disponibles a la vista: $this->set($data); ?>
Control de Flujo
Redirect (string $url, integer $status, boolean $exit)
El método de control de flujo que más frecuentemente utilizarás es redirect(). Este método
toma su primer parámetro en forma de URL relativa de CakePHP. Por ejemplo, cuando un
usuario ha hecho un pedido satisfactoriamente, probablemente desearás redirigirle a una
ventana de recibo.
functionrealizarPedidos() { // La lógina para finalizar el pedido va
aquí if($satisfactorio) { $this->redirect(array('controller' =>
'pedidos', 'action' => 'gracias')) ; } else { $this-
>redirect(array('controller' => 'pedidos', 'action' => 'confirmar')) ;
} }
116
El segundo parámetro de redirect() te permite definir un código de estado HTTP que
acompañe la redirección. Puede que desees usar 301 (movido permanentemente) o 303 (mirar
otro), dependiendo de la naturaleza de la redirección.
El método ejecutará exit() tras la redirección a menos que establezcas el tercer parámetro a
false.
Igualmente, el método flash() es usado para redirigir un usuario a una nueva página tras una
operación. El método flash() es diferente en cuanto que muestra un mensaje antes de enviar al
usuario a otra URL.
Para mensajes flash en la página, cerciórate de echarle un ojo al método setFlash() del
componente SessionComponent.
Tema 5: Modelos
1 La comprensión de modelos
Un Modelo representa tu modelo de datos y, en programación orientada a objetos, es un
objeto que representa una "cosa", como un coche, una persona, o una casa. Un blog, por
ejemplo, puede contener varios artículos (posts) y cada artículo puede contener varios
comentarios. Los objetos Blog, Artículo (Post) y Comentario son ejemplos de modelos, cada
uno asociado con el otro.
Simplemente con esta declaración, se le otorga al modelo Ingredient toda la funcionalidad que
necesitarás para crear consultas junto con guardado y borrado de datos. Estos métodos
mágicos provienen del modelo de herencia de CakePHP. El modelo Ingredient extiende el
modelo de aplicación AppModel, el cual extiende la clase Model, interna de CakePHP. Es esta
clase Model interna la que otorga la funcionalidad a nuestro modelo personalizado, Ingredient.
La clase intermedia AppModel está vacía y reside por defecto dentro de la carpeta /cake/.
Redefinir AppModel te permitirá definir funcionalidad que debería estar disponible a todos los
modelos dentro de tu aplicación. Para hacer eso, necesitas crear tu propio fichero
app_model.php que reside en la raíz de la carpeta /app/.
117
utilizar un método de un modelo personalizado y estás obteniendo errores SQL, normalmente
es porque CakePHP no puede encontrar tu modelo.
Con tu modelo definido, este puede ser accedido dentro de tu Controlador. CakePHP
automáticamente hará que se pueda acceder al modelo cuando su nombre concuerde con el
del controlador. Por ejemplo, un controlador llamado IngredientsController automáticamente
inicializará el modelo Ingredient y será accesible por el controlador mediante $this-
>Ingredient.
<?php classIngredientsController extends AppController { function
index() { //obtiene todos los ingredientes y los pasa a la vista:
$ingredients = $this->Ingredient->find('all') ; $this-
>set('ingredients', $ingredients) ; } } ?>
Están disponibles los modelos asociados a través del modelo principal. En el siguiente ejemplo,
el modelo Receta (Recipe) tiene una asociación con el modelo Ingrediente (Ingredient).
$this->Recipe->Ingredient->find('all') ;
Como podrás ver en Controllers, puedes atar múltiples modelos al controlador y acceder
directamente desde él. En el siguiente ejemplo, ambos modelos Recipe y User son accesibles
desde el controlador actual.
<?php classRecipeController extends AppController { var $uses =
array('Recipe', 'User') ; function index() { $this->Recipe-
>find('all') ; $this->User->find('all') ; } } ?>
Los nombres de las tablas son, por convención, en minúsculas y en plural, con las palabras de
los nombres de tablas de varias palabras separadas por guiones de subrayado (_). Por ejemplo,
un nombre de Modelo de Ingredient espera el nombre de tabla ingredients. Un nombre de
Modelo de EventRegistration debería esperar un nombre de tabla event_registrations.
CakePHP inspeccionará tus tablas para determinar el tipo de dato de cada campo y utiliza esta
información para automatizar varias características como la salida de campos de formulario en
la vista.
Los nombres de los campos son, por convención, en minúscula y separados por guiones de
subrayado (_).
118
Las asociaciones del modelo con el nombre de la tabla pueden ser anuladas con el atributo
useTable del modelo, explicado más adelante en este capítulo.
En el resto de esta sección verás cómo CakePHP "mapea" tipos de campos de bases de datos
en tipos de datos PHP y cómo CakePHP puede automatizar tareas basandose en cómo tus
campos están definidos.
MySQL
MySQLi
119
ADOdb
ORACLE
120
SQLite
Títulos
Un objeto, en sentido físico, a menudo tiene un nombre o un título con el que referirse. Una
persona tiene un nombre como Juan o Ambrosio o Colega. Una entrada de un blog tiene un
título. Una categoría tiene un nombre.
Al especificar el campo title (título) o name (nombre), CakePHP automáticamente utilizará esta
etiqueta en varias circunstancias:
121
Scaffolding — títulos de páginas, etiquetas de fieldset.
Listas - normalmente utilizado para los desplegables <select>.
TreeBehavior — reordenación, vistas de árbol.
Si tienes un campo titley un campo name en tu tabla, el campo title será el utilizado.
Los campos created y modified serán establecidos a la fecha y hora actuales cuando el registro
es inicialmente añadido. El campo modified será actualizado con la fecha y hora actuales
cuando el registro existente sea grabado.
Un UUID es una cadena de 32 bytes separada por guiones, con un total de 36 caracteres. Por
ejemplo:
550e8400-e29b-41d4-a716-446655440000
Los UUIDs están diseñados para ser únicos, no sólo dentro de una tabla dada, sino también a
través de tablas y bases de datos. Si necesitas que un campo permanezca único a través de
sistemas, los UUIDs son un genial enfoque
$parametros es un array con cualquiera de las siguientes opciones disponibles como claves:
array( 'conditions' =>array('Model.field' => $thisValue), //array de
condiciones 'recursive' => 1, //int 'fields' =>array('Model.field1',
'Model.field2'), //array de nombres de campos 'order' =>
'Model.created', //string o array definiendo el orden 'group'
=>array('Model.field'), //campos para GROUP BY 'limit' => n, //int
'page' => n //int )
Si estás utilizando find('list'), la clave 'fields' en $parametros define la clave, valor y grupo
// la lista generada será indexada por Post.id, con valor de
Post.title $this->Post->find('list',
array('fields'=>'Post.title')) ; // la lista generada será indexada
122
por Post.slug, con valor de Post.title $this->Post->find('list',
array('fields'=>array('Post.slug',’Post.title'))) ; // la lista
generada será agrupoada por Post.author_id, y cada grupo indexado por
Post.id, con valor de Post.title $this->Post->find('list',
array('fields'=> array('Post.id', 'Post.title',
'Post.author_id') ) ) ;
find('first', $params)
'first' es el tipo find por defecto, y devolverá un solo resultado, deberías utilizar esto para
cualquier caso donde esperes solo un resultado. Abajo hay un par de ejemplos simples (código
del controlador[ controller ]):
functionsome_function() { ... $this->Article->order = null; //
reseteando si ya ha sido inicializado $semiRandomArticle = $this-
>Article->find() ; $this->Article->order = 'Article.created DESC'; //
simulando el modelo teniendo un órden por defecto $lastCreated =
$this->Article->find() ; $alsoLastCreated = $this->Article-
>find('first', array('order' => array('Article.created DESC'))) ;
$specificallyThisOne = $this->Article->find('first',
array('conditions' => array('Article.id' => 1))) ; ... }
En este primer ejemplo, ningún parámetro se le ha pasado a find - por lo tanto ningún criterio
de condición o de ordenamiento será utilizado. El formato devuelto por la llamada a find('first')
será de la siguiente forma:
Array ( [ModelName] => Array ( [id] => 83 [field1] => value1 [field2]
=> value2 [field3] => value3 ) [AssociatedModelName] => Array ( [id]
=> 1 [field1] => value1 [field2] => value2 [field3] => value3 ) )
find('count', $params)
Devuelve un valor entero. Debajo hay un par de ejemplos sencillos (código controlador):
functionsome_function() { ... $total = $this->Article->find('count') ;
$pending = $this->Article->find('count', array('conditions' =>
array('Article.status' => 'pending'))) ; $authors = $this->Article-
123
>User->find('count') ; $publishedAuthors = $this->Article-
>find('count', array( 'fields' => 'DISTINCT Article.user_id',
'conditions' =>array('Article.status !=' => 'pending') )) ; ... }
No pasar campos como arrays a find('count'). Podrías necesitar campos específicos para
DISTINCT count (de lo contrario, count es siempre lo mismo - dictatado por las conditions
(condiciones)).
find('all', $params)
Devuelve un array de resultados (potencialmentemúltiples); es, de hecho, el mecanismo usado
por todas las variantes del método find(), como por ejemplo para paginar. Debajo puedes ver
un par de (código controlador) ejemplos:
functionsome_function() { ... $allArticles = $this->Article-
>find('all') ; $pending = $this->Article->find('all',
array('conditions' => array('Article.status' => 'pending'))) ;
$allAuthors = $this->Article->User->find('all') ; $allPublishedAuthors
= $this->Article->User->find('all', array('conditions' =>
array('Article.status !=' => 'pending'))) ; ... }
El ejemplo de abajo $allAuthors busca todos los campos de la tabla users, no se le han aplicado
condiciones a find.
find('list', $params)
Devuelve un array indexado, útil para cualquier uso donde podrías querer una lista como los
polulares campos select de los formularios. Debajo hay un par de simples ejemplos (código
controlador):
functionsome_function() { ... $allArticles = $this->Article-
>find('list') ; $pending = $this->Article->find('list',
array('conditions' => array('Article.status' => 'pending'))) ;
$allAuthors = $this->Article->User->find('list') ;
$allPublishedAuthors = $this->Article->User->find('list',
array('conditions' => array('Article.status !=' =>
'pending'))) ; ... }
124
Cuando find('list') es llamado, los parámetros pasados son usados para determinar que debería
ser usado como la key del array, value y opcionalmente a que grupo pertenecen los resultados.
Por defecto la clave primaria para el modelo es usada por la key, y el valor que se muestra es el
usado por el value.
findAllBy<nombreCampo>(string $valor)
Estas funciones mágicas pueden ser usadas como atajos para buscar en tus tablas por cierto
campo. Simplemente añade el nombre del campo (en formato CamelCase) al final del nombre
de esas funciones (<nombreCampo>) y proporciona los criterios para ese campo como primer
parámetro.
findBy<nombreCampo>(string $valor)
Estas funciones mágicas pueden ser usadas como atajo en la búsqueda en tus tablas por cierto
campo. Simplemente añade el nombre del campo (en forma CamelCase) al final de las
funciones (), y proporciona los criterios para ese campo como primer parámetro.
$this->Product->findAllByOrderStatus(‘3’); Product.order_status = 3
Los usuarios de PHP4 han de utilizar esta función de manera un poco diferente debido a cierto
caseinsensitivity en PHP4:
$this->Product->findAllByOrder_status(‘3’); Product.order_status = 3
$this->Cake->findById(7); Cake.id = 7
query(string $consulta)
Se pueden realizar llamadas SQL personalizadas usando el método query() del modelo.query()
utiliza el nombre de la tabla en la consulta como clave del array de datos devueltos, en vez del
nombre del modelo. Por ejemplo:
$this->Fotografia->query("SELECT * FROM fotografias LIMIT 2;") ;
Debería devolver
Array ( => Array ( [fotografías] => Array ( [id] => 1304 [user_id] =>
759 ) ) => Array ( [fotografías] => Array ( [id] => 1305 [user_id] =>
759 ) ) )
125
Para usar el nombre del modelo como clave del array, y obtener un resultado consistente con
el devuelto por los métodos Find, la consulta puede ser reescrita:
$this->Fotografia->query("SELECT * FROM fotografia AS Fotografia LIMIT
2;") ;
La cual devuelve
Array ( => Array ( [Fotografia] => Array ( [id] => 1304 [user_id] =>
759 ) ) => Array ( [Fotografia] => Array ( [id] => 1305 [user_id] =>
759 ) ) )
read($fields, $id)
read() es un método usado para establecer los datos del modelo actual (Model::$data)--así
también mientras se está editando-pero también puede ser usado en otras circunstancias para
obtener un solo registro de la base de datos.
$fields es usado para especificar un nombre de campo, como cadena, o un arreglo de nombres
de campo que serán incluidos en la consulta; si no se especifica un valor, entonces todos los
campos serán incluidos.
$id especifica el ID de registro que será leído. Por defecto, el registro actualmente
seleccionado, especificado por Model::$id, es usado. Si se especifica un valor diferente a $id
causará que el registro que cumpla con la condición será seleccionado.
function beforeDelete($cascade) { ... $rating = $this->read('rating');
// obtiene el rating del registro que será borrado. $name = $this-
>read('name', $id2); // obtiene el nombre un segundo registro. $rating
= $this->read('rating'); // obtiene el rating del segundo registro
$this->id = $id3; // $this->Article->read(); // lee un tercer
registro, especificado por $id3. $record = $this->data // almacena el
tercer registro en $record ... }
Notar que la tercera llamada a read() obtiene el rating del mismo registro leído anteriormente
por la llamada $this->read('name', $id2). Esto es porque read() cambia el valor en Model::$id a
cualquier valor pasado como $id.
Usar arrays permite una lectura más clara y fácil, y también hace muy fácil la construcción de
consultas. Esta sintaxis también particiona los elementos de tu consulta (campos, valores,
operadores, etc.) en partes discretas y manipulables. Esto permite a CakePHP generar la
consulta más eficiente posible, asegurar una sintaxis SQL apropiada, y formatear
apropiadamente cada parte individual de la consulta.
126
$condiciones = array("Articulo.title" => "Esto es un artículo") ; //
Ejemplo de uso con un modelo: $this->Articulo->find($condiciones) ;
La estructura aquí es bastante autoexplicativa: buscará cualquier artículo donde el título sea
igual a "Esto es un artículo". Notar que podríamos haber utilizado como nombre de campo
simplemente 'title', pero cuando se construyen consultas es buena práctica especificar siempre
el nombre del modelo (en este caso, Articulo), ya que mejora la claridad del código y ayuda a
prevenir colisiones en el futuro, en cuyo caso deberías modificar tu esquema de tablas.
¿Qué hay sobre otros tipos de condiciones? Estas son igualmente simples. Digamos que
queremos buscar todos los artículos donde el título no sea 'Esto no es un artículo':
array("Articulo.title<>" => "Esto no es un artículo")
Notar el '<>' que está detrás del nombre del campo. CakePHP puede analizar sintácticamente
cualquier operador de comparación en SQL, incluyendo las expresiones usando LIKE,
BETWEEN, o REGEX, siempre y cuando dejes un espacio entre el nombre del campo y el
operador. La unica excepción aquí es la condición de búsqueda del tipo IN (...). Digamos que
querías buscar artículos donde el título estaba dentro de un conjunto dado de valores:
array( "Articulo.title" =>array("Primer artículo", "Segundo artículo",
"Tercer artículo") )
Para realizar una búsqueda con condición NOT IN(...) para encontrar artículos cuyo título no
está en el conjunto de valores dado:
array("NOT" => array( "Articulo.title" => array("Primer artículo",
"Segundo artículo", "Tercer artículo") ) )
Añadir filtros adicionales a las condiciones es tan simple como añadir pares clave/valor
adicionales al array:
array ( "Articulo.title" =>array("Primer artículo", "Segundo
artículo", "Tercer artículo") , "Articulo.created>" =>date('Y-m-d',
strtotime("-2 weeks")) )
También puedes crear búsquedas que comparen dos campos en la base de datos:
array("Articulo.created = Articulo.modified")
Este ejemplo de arriba devolverá artículos en los cuales la fecha de creación es igual a la fecha
de modificación (p.e. devolverá artículos que nunca han sido modificados).
Por defecto, CakePHP junta múltiples condiciones con AND booleano; es decir, las condiciones
de más arriba sólo coincidirán con artículos que han sido creados en las últimas dos semanas (-
2 weeks), y posean un título que coincida con alguno de los dados en el conjunto ("Primer
artículo",...).
No obstante, podemos igualmente buscar artículos que coincidan con cualquiera de las
condiciones:
array( "or" => array ( "Articulo.title" =>array("Primer artículo",
"Segundo artículo", "Tercer artículo") , "Articulo.created>"
=>date('Y-m-d', strtotime("-2 weeks")) ) )
127
Cake acepta todas las operaciones booleanas de SQL válidas, incluyendo AND, OR, NOT, XOR,
etc..., y pueden estar en mayúsculas o minúsculas, como prefieras. Estas condiciones son
también infinitamente anidables. Digamos que tienes una relación belongsTo entre Artículos y
Autores.
Digamos que quieres buscar todos los artículos que contienen una cierta palabra (p.e.
"magico") o que han sido creados en las últimas dos semanas, pero quieres restringir tu
búsqueda a artículos escritos por Pedro:
array ( "Autor.name" => "Pedro", "or" => array ("Articulo.title LIKE"
=> "%magico%","Articulo.created>" => date('Y-m-d', strtotime("-2
weeks")) ) )
Cake también puede comprobar campos nulos (null). En este ejemplo, la consulta devolverá
registros en los que el título del artículo no es nulo:
array ( "not" => array ("Articulo.title" => null, ) )
Nota: CakePHP entrecomillará los valores numéricos dependiendo del tipo de campo definido
en tu base de datos.
La mayoría de las veces no necesitarás preocuparte por este formato: los ayudantes de
CakePHP HtmlHelper, FormHelper, y métodos de búsqueda empaquetan los datos en este
formato. Si estás usando alguno de los ayudantes, los datos también están convenientemente
disponibles en $this>data para su uso rápido.
Aquí está un ejemplo rápido de una acción de un controlador que usa un modelo de CakePHP
para salvar datos en una tabla de una base de datos:
functionedit($id) { // Ha POSTeado algún dormulario datos? if(!
empty($this->data)) { // Si el formulario puede ser validado y
salvado... if($this->Receta->save($this->data)) { // Establede un
mensaje flash y redirige. $this->Session->setFlash("Receta guardada!")
; $this->redirect('/recetas') ; } } // Si no hay datos de formulario,
busca la receta a editar y pásala a la vista $this->set('receta',
$this->Receta->findById($id)) ; }
Una nota adicional: cuando se llama a save(), los datos pasados a la función como primer
parámetro son validados usando el mecanismo de validación de CakePHP. Si por alguna razón
tus datos no se graban, comprueba si alguna regla de validación se está incumpliendo.
Hay unos pocos métodos relacionados con el salvado que encontrarás útiles:
128
save(array $datos = null, boolean $validar = true, array $listaCampos
= array())
Mostrado arriba, este método graba datos formateados en array. El segundo parámetro
($validar) te permite eludir la validación, y el tercero ($listaCampos) te permite proveer una
lista de campos del modelo a ser grabados. Como seguridad añadida, puedes limitar los
campos grabados a aquellos listados en $listaCampos.
Una vez que un salvado ha sido completado, el identificador ID del objeto se encuentra en el
atributo $id del objeto del modelo (algo especialmente útil cuando se crean nuevos objetos).
$this->Ingrediente->save($datosNuevos) ; $nuevoIngredienteId = $this-
>Ingrediente->id;
Este método resetea el estado del modelo para grabar nueva información.
Si se pasa el parámetro $datos (usando el formato de array descrito arriba), la instancia del
modelo estará lista para salvar con esos datos (accesibles en $this->data).
saveField(string $nombreCampo, string $valorCampo, $validar = false)
Por ejemplo, para actualizar el título de una entrada de un blog, la llamada a saveField desde
un controlador debería parecerse a esto:
$this->Entrada->saveField('titulo', 'Un Nuevo Título para un Nuevo
Día') ;
Por ejemplo, para aprobar a todos los panaderos que han sido miembros durante más de un
año, la llamada de actualización debería ser algo como:
$este_año = date('Y-m-d h:i:s', strtotime('-1 year')) ; $this-
>Panadero->updateAll( array('Panadero.approved' => true) ,
array('Panadero.created<=' => "$este_año") ) ;
El array $campos acepta expresiones SQL. Los valores literales deberían ser entrecomillados
manualmente.
Por ejemplo, para cerrar todos los tickets que pertenecen a cierto vendedor:
$this->Ticket->updateAll( array('Ticket.estado' => "'cerrado'") ,
array('Ticket.vendedor_id' => 453)) ;
129
saveAll(array $datos = null, array $opciones = array())
Usado para salvar (a) múltiples registros individuales para un único modelo o (b) este registro
así como todos los registros asociados.
Para salvar múltiples registros de un único modelo, $data necesita ser un array de registros
indexado numéricamente como esto:
Array ( => Array ( [titulo] =>titulo 1 ) => Array ( [titulo] =>titulo
2 ) )
Para salvar un registro junto con su registro relacionado teniendo una asociación hasOne o
belognsTo, el array de datos debería ser como:
Array ( [Usuario] => Array ( [nombreusuario] =>billy ) [Perfil] =>
Array ( [sexo] =>Varon [ocupacion] => Programador ) )
Para salvar un registro junto con sus registros relacionados teniendo una asociación hasMany,
el array de datos debería ser como:
Array ( [Articulo] => Array ( [titulo] => Mi primer artículo )
[Comentario] => Array ( => Array ( [comentario] => Comment 1
[comentario] => 1 ) => Array ( [comentario] => Comment 2 [comentario]
=> 2 ) ) )
Si ninguno de los registros de los modelos asociados existe aún (por ejemplo, quieres guardar
registros de un nuevo Usuario y su Perfil relacionado a la vez), primero necesitarás guardar el
modelo primario o padre.
Para tener una idea de cómo funciona esto, imaginemos que tenemos una acción en nuestro
controlador de usuarios UsersController que maneja el guardado de un nuevo usuario y su
perfil correspondiente. En la acción de ejemplo mostrada abajo se asumirá que has
POSTeadosufientes datos (usando el FormHelper) para crear un solo Usuario y un solo Perfil.
?php function add() { if (!empty($this->data)) { // Podemos guardar
los datos de Usuario // deberían estar en: $this->data['Usuario']
$this->Usuario->save($this->data) ; // El ID del nuevo Usuario está
ahora en $this->User->id, así que lo // añadimos a los datos a grabar
y grabamos el Perfil $this->data['Perfil']['usuario_id'] = $this-
>Usuario->id; // Como nuestro "Usuario hasOne Perfil", podemos acceder
// al modelo Perfil a través del modelo Usuario $this->Usuario-
>Perfil->save($this->data) ; } } ?>
Como norma general, cuando trabajamos con asociaciones hasOne, hasMany y belongsTo
130
('tiene un', 'tiene varios', y 'pertenece a'), todo es cuestión de las claves. La idea básica es coger
la clave de un modelo y ponerla en el campo de clave foránea en el otro. A veces esto puede
implica usar el atributo $id de la clase del modelo después de save(), pero otras veces podría
simplemente implicar obtener el ID desde un campo oculto de un formulario POSTeado a una
acción del controlador.
Para complementar el enfoque básico usado arriba, CakePHP también ofrece el método muy
útil saveAll, el cual te permite validar y grabar múltiples modelos de golpe. Además, saveAll
provee de soporte transaccional para asegurar la integridad de los datos en tu base de datos
(p.ej. si un modelo falla en la grabación, los otros modelos tampoco serán grabados).
Para que las transacciones funcionen correctamente en MySQL, tus tablas han de usar el
mecanismo InnoDB. Recuerda que las tablas MyISAM no soportan transacciones.
Veamos cómo podemos usar saveAll() para grabar modelos de Compañía (utilizamos este
nombre incorrecto por motivos didácticos) y Cuenta al mismo tiempo.
Primero, necesitas construir tu formulario tanto para el modelo Compañía como el modelo
Cuenta (asumismo que Compañía hasMany Cuenta).
echo $form->create(Compañía, array('action'=>'add')) ; echo $form-
>input('Compañía.nombre', array('label'=>'Nombre de compañía')) ; echo
$form->input('Compañía.descripción') ; echo $form-
>input('Compañía.localización') ; echo $form->input('Cuenta.0.nombre',
array('label'=>'Nombre de cuenta')) ; echo $form-
>input('Cuenta.0.nombreusuario') ; echo $form->input('Cuenta.0.email')
; echo $form->end('Añadir') ;
Echemos un vistazo a la manera en que hemos nombrado los campos del formulario para el
modelo Cuenta. Si Compañía es nuestro modelo principal, saveAll esperará que los datos de
los modelos relacionados (en este caso, Cuenta) lleguen en un formado específico, y teniendo
Cuenta.0.nombreCampo es exactamente lo que necesitamos.
Esto es todo para ello. Ahora nuestros modelos Compañía y Cuenta serán validados y grabados
al mismo tiempo. Una cosa rápida que comentar aquí es el uso de array('validate'=>'first'): esa
opción asegurará que ambos modelos son validados.
Simplemente rellenas el campo de clave foránea con el ID del modelo asociado. Una vez que
está hecho, simplemente llamas al método save() del modelo y todo queda enlazado
correctamente.
131
Con HABTM (Has And BelongsToMany), necesitas establecer el ID del modelo asociado en tu
array de datos. Construiremos un formulario que crea una nueva etiqueta y la asocia al vuelo
con alguna receta.
El formulario más simple debería parecerse al algo como esto (asumimos que $receta_id ya
está establecido a algo):
<?php echo $form->create(‘Etiqueta’); echo $form->input(‘Receta.id’,
array(‘type’=>’hidden’,’value’=>$receta_id)) ; echo $form-
>input('Etiqueta.nombre') ; echo $form->end('Añadir etiqueta') ; ?>
En este ejemplo, puedes ver el campo oculto Receta.id cuyo valor se establece al ID de la
receta a la que queremos enlazar la etiqueta. La acción del controlador que se encarga de
guardar este formulario es muy simple:
function add() { // Graba la asociación if ($this->Etiqueta-
>save($this->data)) { // Hacer algo si todo fue bien } }
Y de esa manera, nuestra nueva Etiqueta es creada y asociada con Receta, cuyo ID estaba en
$this->data['Receta']['id'].
5 Borrando datos
del(int $id = null, boolean $cascada = true) ;
Borra el registro identificado por $id. Por defecto, también borra los registros dependientes
del registro especificado a ser borrado.
Por ejemplo, cuando se borra un registro Usuario que está ligado a varios registros Receta:
Si $cascada está establecido a true, los registros Receta relacionados también son
borrados si el valor de dependent en el modelo está establecida a true.
Si $cascada está establecido a false, los registros Receta permanecerán después de
que el Usuario haya sido borrado.
Definir relaciones entre diferentes objetos en tu aplicación debería ser un proceso natural. Por
ejemplo, en una base de datos de recetas, una receta puede tener varias revisiones, las
revisiones tienen un único autor, y los autores pueden tener varias recetas. El definir la manera
en que funcionan estas relaciones te permite acceder a tus datos de manera intuitiva y
potente.
El propósito de esta sección es mostrarte cómo diseñar, definir y utilizar asociaciones entre
modelos en CakePHP.
132
Mientras que los datos pueden provenir de una variedad de orígenes, la formá más común de
almacenamiento en aplicaciones web es una base de datos relacional. La mayoría de cosas que
cubre esta sección estará en ese contexto.
Tipos de Relaciones
Los cuatro tipos de relaciones en CakePHP son: hasOne, hasMany, belongsTo y
hasAndBelongsToMany (HABTM), "tiene un", "tiene muchos", "pertenece a" y "tiene y
pertenece a muchos", respectivamente.
Las asociaciones son definidas creando una variable de clase nombrada tras la asociación que
estás definiendo. La variable de clase puede, a veces, ser tan simple como una cadena de
caracteres, pero puede ser tan completa como un array multidimensional usado para definir
asociaciones concretas.
<?php class Usuario extends AppModel { var $name = 'Usuario'; var
$hasOne = 'Pefil'; var $hasMany = array( 'Receta' =>
array( 'className' => 'Receta','conditions' => array('Receta.aprobada'
=> '1') , 'order' => 'Receta.created DESC' ) ) ; } ?>
hasOne
Configuremos un modelo Usuario con una relación hasOne con un modelo Perfil.Primero,
necesitas establecer las claves de tus tablas de base de datos correctamente. Para que
funcione una relación hasOne correctamente, una tabla ha de contener una clave foránea que
apunte a un registro en la otra. En este caso, la tabla 'perfiles' contendrá un campo llamado
usuario_id. El patrón básico es: hasOne: el otro modelo contiene la clave foránea.
Relación Esquema
133
Manzana hasOne Plátano plananos.manzana_id
Hay dos maneras de describir esta relación en tus archivos del modelo. La manera más simple
es establecer el atributo $hasOne a una cadena de caracteres conteniendo el nombre de la
clase del modelo asociado, como hemos hecho arriba.
Si necesitas más control, puedes definir tus asociaciones utilizando sintaxis de arrays. Por
ejemplo, podrías desear limitar la asociación para incluir sólo ciertos registros.
<?php class Usuario extends AppModel { var $name = 'Usuario'; var
$hasOne = array('Perfil' => array( 'className' => 'Perfil',
'conditions' =>array('Perfil.publicado' => '1') , 'dependent' =>
true ) ); } ?>
className: el nombre de la clase del modelo que está siendo asociado al modelo
actual. si estás definiendo una relación 'Usuario hasOne Perfil', la clave className
debería ser igual a 'Perfil'.
foreignKey: el nombre de la clave foránea que se encuentra en el otro modelo. Esto es
especialmente útil si necesitas definir múltiples relaciones hasOne. El valor por defecto
para esta clave es el nombre en singular del modelo actual, seguido del sufijo '_id'. En
el ejemplo de arriba, debería ser por defecto 'usuario_id'.
conditions: Un fragmento SQL usado para filtrar registros del modelo relacionado. Es
buena práctica usar nombres de modelos en los fragmentos SQL: 'Perfil.aprobado = 1'
siempre es mejor que simplemente 'aprobado = 1'.
fields: Una lista de campos a ser devueltos cuando se traen los datos del modelo
asociado. Por defecto devuelve todos los campos.
dependent: Cuando la clave dependent se establece a true, y el método delete() del
modelo es llamado con el parámetro $cascada con valor true, los registros del modelo
asociado también son borrados. En este caso lo ponemos a true de manera que
borrando un Usuario también borrará su Perfil asociado.
134
Una vez que esta asociación ha sido definida, las operaciones de búsqueda en el modelo
usuario traerán también el registro Perfil relacionado si existe:
// Resultados de ejemplo de una llamada a $this->Usuario->find() Array
( [Usuario] => Array ( [id] => 121 [name] =>GwootheKungwoo [created]
=> 2007-05-01 10:31:01 ) [Perfil] => Array ( [id] => 12 [user_id] =>
121 [habilidad] => Hornear Pasteles [created] => 2007-05-01 10:31:01 )
)
belongsTo
Ahora que tenemos acceso a los datos de Perfil desde el modelo Usuario, definamos la
asociación belongsTo (perteneceA) en el modelo Perfil para tener acceso a los datos de Usario
relacionados. La asociación belongsTo es un complemento natural a las asociaciones hasOne
(tieneUn) y hasMany (tieneMuchos): nos permite ver los datos de la otra dirección.
A la hora de establecer las claves de las tablas de tu base de datos para una relación
belongsTo, sigue estas convenciones: belongsTo: el modelo actual contiene la clave foránea.
Relación Esquema
Si un modelo (tabla) contiene una clave foránea, "perteneceA" (belongsTo) el otro modelo
(tabla).
También podemos definir una relación más específica usando sintaxis de arrays:
<?php class Perfil extends AppModel { var $name = 'Perfil'; var
$belongsTo = array('Usuario' => array( 'className' => 'Usuario',
'foreignKey' => 'usuario_id' ) ); } ?>
className: el nombre de la clase del modelo que se está asociando al modelo actual.
Si estás definiendo una relación 'Perfil belongsTo Usuario', la clave className ha de
tener el valor 'Usuario'.
foreignKey: el nombre de la clave foránea que se encuentra en el modelo actual. Esto
es especialmente útil si necesitas definir múltiples relaciones belongsTo. El valor por
135
defecto de esta clave es el nombre en singular del otro modelo (separado por guiones
de subrayado) con el sufijo '_id'.
conditions: el fragmento SQL filtra los registros del modelo relacionado. Es buena
práctica usar el nombre de los modelos en los fragmentos SQL: 'Usuario.activo = 1'
siempre es mejor que simplemente 'activo = 1'.
fields: lista de campos a ser recuperados cuando los datos del modelo asociado se
traen de la base de datos. Por defecto devuelve todos los campos.
counterCache: (booleano) si se establece a true, el modelo asociado automáticamente
incrementará o decrementará el campo '[nombre_modelo_en_singular]_count' de la
tabla foránea siempre que hagas un save() o delete(). El valor en el campo contador
representa el número de filas relacionadas.
Una vez que esta asociación ha sido definida, las operaciones de búsqueda en el modelo Perfil
también traerán el registro de Usuario relacionado si existe:
// Resultados de ejemplo de la llamada a $this->Perfil->find(). Array
( [Perfil] => Array ( [id] => 12 [usuario_id] => 121 [habilidad]
=>BakingCakes [created] => 2007-05-01 10:31:01 ) [Usuario] => Array
( [id] => 121 [name] =>GwootheKungwoo [created] => 2007-05-01 10:31:01
) )
hasMany
Siguiente paso: definiendo una asociación "Usuario hasMany Comentario". Una asociación
hasMany (tieneMuchos) nos permitirá traer los comentarios del usuario cuando se trae un
registro Usuario.
A la hora de establecer las claves de las tablas de tu base de datos para una relación hasMany,
sigue estas convenciones: hasMany: el otro modelo contiene la clave foránea.
Relación Esquema
También podemos definir una relación más específica usando sintaxis de arrays:
<?php class Usuario extends AppModel { var $name = 'Usuario'; var
$hasMany = array('Comentario' => array( 'className' => 'Comentario',
'foreignKey' => 'usuario_id', 'conditions' =>array('Comentario.estado'
136
=> '1') , 'order' => 'Comentario.created DESC', 'limit' => '5',
'dependent'=> true ) ); } ?>
className: el nombre de la clase del modelo que está siendo relacionado con el
modelo actual. Si estás definiendo una relación 'Usuario hasMany Comentario', el valor
de clasName ha de ser 'Comentario'.
foreignKey: el nombre de la clave foránea en el otro modelo. Esto es especialmente
útil si necesitas definir múltiples relaciones hasMany. El valor por defecto para esta
clave es el nombre en singular del otro modelo (separado por guiones de subrayado),
con el sufijo '_id'.
conditions: un fragmento SQL filtra los registros del modelo relacionado. Es buena
práctica usar el nombre de los modelos en los fragmentos SQL: 'Usuario.activo = 1'
siempre es mejor que simplemente 'activo = 1'.
fields: lista de campos a ser recuperados cuando los datos del modelo asociado se
traen de la base de datos. Por defecto devuelve todos los campos.
order: un fragmento SQL que define el orden de las filas asociadas devueltas.
limit: el número máximo de filas asociadas que quieres que devuelva.
offset: el número de filas asociadas que quieres saltarte (dadas las condiciones y orden
actuales) antes de traer las filas y asociarlas.
dependent: Cuando dependent se establece a true, es posible el borrado recursivo del
modelo. En este ejemplo, los registros Comentario serán borrados cuando sus
registros Usuario asociados han sido borrados.
El segundo parámetro del método Modelo->delete() ha de establecerse a true para
que ocurra un borrado recursivo.
finderQuery: Una consulta SQL completa que CakePHP puede usar para traer los
registros del modelo asociado. Esto debería ser usado en situaciones que requieren
unos resultados muy personalizados.
Una vez que esta asociación ha sido definida, las operaciones de búsqueda en el modelo
Usuario también traerán los registros Comentario relacionados si existen:
// Resultados de ejemplo de llamada a $this->Usuario->find(). Array
( [Usuario] => Array ( [id] => 121 [name] =>GwootheKungwoo [created]
=> 2007-05-01 10:31:01 ) [Comentario] => Array ( => Array ( [id] =>
123 [usuario_id] => 121 [title] => On GwootheKungwoo [cuerpo]
=>TheKungwooness is not so Gwooish [created] => 2006-05-01 10:31:01 )
=> Array ( [id] => 123 [usuario_id] => 121 [title] => More on Gwoo
[cuerpo] =>Butwhat of the ‘Nut? [created] => 2006-05-01 10:41:01 ) ) )
137
hasAndBelongsToMany (HABTM)
Perfecto. En este punto puedes llamarte "profesional de asociaciones del modelo de
CakePHP". Ya estás versado en tres de las asociaciones que tratan la mayoría de las relaciones
de objetos.
La principal diferencia entre hasMany y HABTM es que un enlace entre modelos en HABTM no
es exclusivo. Por ejemplo, vamos a unir nuestro modelo Receta con un modelo Etiqueta
usando HABTM. Atando la etiqueta 'Italiano' a la receta 'Gnocci' de mi abuela no 'acapara' la
etiqueta; también puedo etiquetar con 'Italiano' mis 'Espaguettis a la barbacoa con miel
glaseada".
Los enlaces entre objetos asociados mediante hasMany son exclusivos. Si mi 'Usuario hasMany
Comentarios', un comentario está sólo enlazado a un usuario específico. Deja de estar
disponible para todos.
Andando. Necesitaremos establecer una tabla extra en la base de datos para manejar las
asociaciones HABTM. El nombre de esta nueva tabla de unión necesita incluir los nombres de
ambos modelos involucrados en plural, en orden alfabético, y separados por un guion de
subrayado ( _ ). El esquema de la tabla debería contener como mínimo dos campos, cada uno
clave foránea (que deberían ser enteros) apuntando a ambas claves primarias de los modelos
involucrados.
HABTM necesita una tabla de unión separada que incluya los nombres de ambos mdelos.
Relación Esquema
Una vez que esta nueva tabla ha sido creada, podemos definir las asociaciones HABTM en los
ficheros del modelo. Vamos a saltar directamente a la sintaxis de arrays esta vez:
<?php class Receta extends AppModel { var $name = 'Receta'; var
$hasAndBelongsToMany = array( 'Etiqueta' => array('className' =>
'Etiqueta', 'joinTable' => 'etiquetas_recetas', 'foreignKey' =>
'receta_id', 'associationForeignKey' => 'etiqueta_id', 'with' => '',
138
'conditions' => '', 'order' => '', 'limit' => '', 'unique' => true,
'finderQuery' => '', 'deleteQuery'=> '', 'insertQuery' => '' ) ); } ?>
className: el nombre de la clase del modelo que se está asociando al modelo actual.
Si estás definiendo una relación 'Usuario hasAndBelongsToMany Comentarios',
className debería ser igual a 'Comentario'.
joinTable: el nombre de la tabla de unión usuada en esta asociación (si si la tabla actual
no se adhiere a la convención de nombrado para tablas de unión HABTM).
foreignKey: el nombre de la clave foránea que se encuentra en el modelo actual. Esto
es especialmente útil si necesitas definir múltiples relaciones HABTM. El valor por
defecto para esta clave es el nombre en singular, separado por guiones de subrayado
(_), del modelo actual con el sufijo '_id'.
associationForeignKey: el nombre de la clave foránea que se encuentra en el otro
modelo. Esto es especialmente útil si necesitas definir múltiples relaciones HABTM. El
valor por defecto para esta clave es el nombre en singulas, separado por guiones de
subrayado (_), del modelo actual con el sufijo '_id'.
with: define el nombre del modelo para la tabla de unión. Por defecto, CakePHP
autocreará un modelo por ti. Usando el ejemplo de arriba, se llamaría EtiquetaReceta.
Usando esta clave puedes sustituir este nombre por defecto. El modelo de la tabla de
unión puede ser usado como cualquier modelo 'regular' para acceder a la tabla de
unión directamente.
conditions: fragmento SQL usado para filtrar registros del modelo relacionado. Es
buena práctica usar nombres de modelos en los fragmentos SQL: 'Comentario.estado =
1' siempre es preferible a simplemente 'estado = 1'.
fields: lista de campos a ser devueltos cuando los datos del modelo asociado son
traídos.
order: fragmento SQL que define el orden de las filas asociadas devueltas.
limit: el número máximo de filas asociadas que deseas que sean devueltas.
unique: si tiene el valor true (valor por defecto) Cake borrará primero los registros de
relación existentes en la tabla de claves foráneas antes de insertar nuevas filas, cuando
se actualiza un registro. Así, las asociaciones existentes deberán ser pasadas de nuevo
durante las actualizaciones.
offset: el número de filas asociadas que omitir (dadas las condiciones actuales y orden)
antes de buscar y asociar.
finderQuery, deleteQuery, insertQuery: una consulta SQL completa que CakePHP
puede usar para buscar, borrar o crear nuevos registros del modelo asociado. Esto
debería ser usado en situaciones que requieren resultados muy personalizados.
Una vez que esta asociación ha sido definida, las operaciones de búsqueda en el modelo
Receta también devolverán los registros Etiqueta relacionados si existen:
// Resultados de ejemplo de una llamada a $this->Receta->find(). Array
( [Receta] => Array ( [id] => 2745 [name] => Bombas de Chocolate con
Azúcar Glaseada [created] => 2007-05-01 10:31:01 [usuario_id] =>
2346 ) [Etiqueta] => Array ( => Array ( [id] => 123 [name] => Desayuno
139
) => Array ( [id] => 124 [name] => Postre ) => Array ( [id] => 125
[name] => Enfermedad del Corazón ) ) )
Recuerda definir una asociación HABTM en el modelo Etiqueta si quieres traer datos de Receta
cuando uses el modelo Etiqueta.
Notar que este ejemplo devuelve TODAS las recetas pero sólo la etiqueta 'Postre'. Para
conseguir nuestro objetivo adecuadamente, hay diversas maneras de hacerlo. Una opción es
buscar en el modelo Etiqueta (en vez de Receta), lo que nos dará también todas las Recetas
asociadas.
$this->Receta->Tag->find('all',
array('conditions'=>array('Etiqueta.name'=>'Postre'))) ;
Podríamos también usar el modelo de tabla de unión (que CakePHP nos provee), para buscar
por un ID dado.
&$this->Receta->bindModel(array('hasOne' =>
array('EtiquetaReceta'))) ; $this->Receta->find('all', array('fields'
=> array('Receta.*') ,
'conditions'=>array('EtiquetaReceta.etiqueta_id'=>124) // id de Postre
)) ;
También es posible crear una asociación exótica con el propósito de crear tantas uniones como
necesarias para permitir el filtrado, por ejemplo:
$this->Receta->bindModel( array( 'hasOne' =>array( 'EtiquetaReceta',
'EtiquetaFiltro' =>array( 'className' => 'Tag', 'foreignKey' => false,
'conditions' =>array('EtiquetaFiltro.id =
EtiquetaReceta.id') ) ) ) ) ; $this->Receta->find('all',
array( 'fields' =>array('Receta.*') ,
'conditions'=>array('EtiquetaReceta.name'=> 'Postre') )) ;
140
[usuario_id] => 2346 ) [Etiqueta] => Array ( => Array ( [id] => 123
[name] => Desayuno ) => Array ( [id] => 124 [name] => Postre ) =>
Array ( [id] => 125 [name] => Enfermedad del corazón ) ) }
dbo_adodb.php
dbo_db2.php
dbo_firebird.php
dbo_mssql.php
dbo_mysql.php
dbo_mysqli.php
dbo_odbc.php
dbo_oracle.php
dbo_postgres.php
dbo_sqlite.php
dbo_sybase.php
Todas las fuentes de datos indicadas arriba derivan de una clase base DboSource la cual añade
alguna lógica común a la mayoría de bases de datos relaciones. Si decides crear una
datasource RDBMS, tu mejor apuesta es trabajar a partir de una de ellas (por ejemeplo:
dbo_mysql.php o dbo_mssql.php) La mayor parte de la gente, sin embargo, está interesada en
escribir datasources para fuentes de datos externas, como APIs REST remotas o incluso
servidores LDAP. Así que eso es lo que vamos a examinar en adelante.
Tema 6: Vistas
La capa vista de CakePHP es cómo hablas a tus usuarios. La mayor parte del tiempo tu vista
estará mostrando documentos (X)HTML a los navegadores, pero tal vez necesites servir datos
AMF a un objeto Flash, responder a una aplicación remota mediante SOAP o producir un
fichero CSV para un usuario.
Los ficheros de vista de CakePHP están escritos en PHP plano y tienen la extensión
.ctp(CakePHP Template) por defecto. Estos ficheros contienen toda la lógica de representación
necesaria para obtener los datos recibidos del controlador en un formato que está preparado
para la audiencia a la que estás atendiendo.
141
Los ficheros de vista se almacenan en /app/views/, en una carpeta nombrada tras el
controlador que usa los ficheros, y nombrada tras la acción a la que corresponde. Por ejemplo,
el fichero de vista para la acción view() del controlador Productos, normalmente, se
encontraría en /app/views/productos/view.ctp.
La capa vista en CakePHP puede estar formada por un número diferentes de partes. Cada
parte tiene usos diferentes, y será tratado en este capítulo:
2 Layouts
Un diseño contiene el código de presentación que envuelve una vista. Cualquier cosa que
quieras ver en todas tus vistas debería estar situada en un layout.
Cuando creas un diseño, necesitas decirle a CakePHP dónde colocar el código para tus vistas.
Para hacer eso, estate seguro que tu diseño incluye un lugar para $content_for_layout (y
opcionalmente, $title_for_layout). Aquí está un ejemplo de a lo que debería parecerse un
diseño por defecto:
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <title><?php
echo$title_for_layout?></title>
<linkrel="shortcuticon"href="Temario/1755/favicon.ico"type="image/x-
icon"> <!-- Incluir ficheros y scripts externos aquí (Mirar el
ayudante HTML para más información --> <?phpecho$scripts_for_layout ?>
</head> <body> <!-- Si quieres algún tipo de menú que mostrar en todas
tus vistas,incluyelo aquí --> <divid="cabecera">
<divid="menu">...</div> </div> <!-- Aquí es donde quiero que se vean
mis vistas --><?php echo$content_for_layout ?> <!--Añadir un pie de
página a cada página mostrada --> <divid="pie">...</div> </body>
</html>
142
Cuando uses $html->css() o $javascript->link() en los ficheros de vista, especifica false en el
argumento 'in-line' para colocar el fuente html en $scripts_for_layout. (Mirar API para más
detalles de uso).
Por ejemplo, si una sección de mi site incluye un espacio menor con banner de publicidad,
debería crear un nuevo diseño (layout) con el espacio publicitario menor, especificándolo
como el diseño para todas las acciones del controlador haciendo algo como: var$layout=
'publicidad_pequena_pordefecto'.
<?php classUsuariosControllerextends AppController
{ functionverActivos() { $this->set('title_for_layout', 'Ver Usuarios
Activos') ; $this->layout = 'publicidad_pequena_pordefecto'; }
functionverImagen() { $this->layout = 'imagen'; //mostrar la imagen
del usuario } } ?>
CakePHP ofrece dos diseños comunes (además del diseño por defecto de CakePHP) que
puedes usar en tus propias aplicaciones: 'ajax' y 'flash'. El diseño Ajax es útil para contruir las
respuestas Ajax; es un diseño vacío (la mayoría de las llamadas ajax sólo requiren una pocas
etiquetas como respuesta, más que una interfaz completa). El diseño flash es usado por
mensajes mostrados por el método flash() del controlador.
Existen otros tres diseños: xml, js y rss en el núcleo como una manera rápida y fácil de servir
contenido que no sea text/html.
3 Elementos
Muchas aplicaciones tienen pequeños bloques de código de presentación que necesita ser
repetido de página en página, algunas veces en diferentes lugares del diseño. CakePHP puede
ayudarte a repetir partes de tu website que necesitan ser reutilizadas. Estar partes reutilizadas
son llamadas Elementos. Anuncios, cajas de ayuda, controles de navegación, menús extras,
formularios de login y llamadas están a menudo implementadas en CakePHP en forma de
elementos. Un elemento es básicamente una minivista que puede ser incluido en otras vistas,
en diseños, e incluso dentro de otros elementos. Los elementos pueden ser usados para hacer
una vista más legible, situando el renderizado de elementos que se repiten en sus propios
ficheros. Pueden también ayudarte a reutilizar fragmentos de contenido en tus aplicaciones.
143
Los elementos están en la carpeta /app/views/elements/ y tienen la extensión de archivo .ctp.
Son mostrados usando el método element() de la vista.
<?php echo$this->element('cajaayuda'); ?>
<?php
?>
Dentro del archivo del elemento, todas las variables pasadas estan disponibles como
miembros del array de parámetros (de la misma manera que set() en el controlador funciona
con los archivos de las vistas). En el ejemplo siguiente, el archivo
/app/views/elements/helpbox.ctp puede usar la variable $helptext.
<?php echo$helptext;//outputs "Oh, this text is veryhelpful." ?>
La función element() combina opciones para el elemento con los datos a pasar en element.
Para tener en cache distintas versiones del mismo elemento en una aplicación, provee una
clave única de cache usando el siguiente formato:
<?php $this->element('helpbox', array( "cache"=>array('time'=>"+7
days",'key'=>'uniquevalue') )
Para hacer esto, en tu controlador añade algo como lo siguiente, para el ejemplo de Post.
144
<?php
classPostsControllerextends AppController
...
function index()
$posts=$this->paginate() ;
if(isset($this->params['requested']))
return$posts;
}else{
$this-
>set(compact('posts')) ;
?>
145
Ahora en el elemento podemos acceder el modelo de posts paginados.
Para tener los últimos cinco posts en una lista ordenada deberíamos
hacer lo siguiente:
<h2>LatestPosts</h2>
<?php $posts=$this-
>requestAction('posts/index/sort:created/order:asc/limit:5'); ?>
<ol>
<li><?php echo$post['Post']['title']; ?
></li>
</ol>
Cache de Elements
Puedes aprovechar el cache de vistas de CakePHP si aportas un parámetro 'cache'. Si lo ajustas
a true, mantendrá en cache durante un día. De otro modo, puedes ajustar tiempos de
caducidad alternativos.
<?php echo$this->element('helpbox',array('cache'=>true)); ?>
Si dibujas el mismo elemento más de una vez en una vista y tienes el cache activado, asegúrate
de ajustar el parámetro 'key' con un nombre diferente cada vez. Esto evitará que cada sucesiva
llamada sobreescriba el resultado almacenado en cache de la anterior llamada element(). Por
ejemplo:
<?php echo $this->element('helpbox',array('cache'=>array('key'=>
'first_use', 'time' => '+1 day'), 'var'=>$var)) ; echo $this-
>element('helpbox',array('cache'=>array('key'=> 'second_use', 'time'=>
'+1 day'),'var'=>$differentVar)) ; ?>
Lo anterior asegura que ambos elementos son almacenados en cache de forma separada
146
Utilizar Elements de un Plugin
Si estás usando un plugin y deseas usar elements dentro de ese plugin, simplemente especifica
el parámetro plugin. Si la vista está siendo dibujada para un controlador/acción de un plugin,
se usará el elemento del plugin. Si el elemento no existe en el plugin, se buscará en la carpeta
APP principal.
<?php echo$this->element('helpbox',array('plugin'=> 'pluginname')); ?>
4 Métodos de la vista
Los métodos de la Vista están disponibles para todos los archivos de vistas, elementos y
plantillas. Para llamar a cualquier método de la vista utilice: $this->method()
set(string $var,mixed$value)
Las Vistas tienen un metodoset() que es análogo al set() encontrado en los objetos Controller.
Te permite agregar variables al viewVars. Usando set() desde tu archivo de vista, agregará las
variables a la capa (layout) y elementos (elements) que luego serán renderizados.
getVar(string $var)
Obtiene el valor de la viewVar con el nombre $var
getVars ()
Obtiene una lista con todas las variables disponibles en el ámbito de la vista actual. Devuelve
un arreglo con los nombres de las variables.
5 Temas
Puedes aprovechar los temas (themes), haciendo sencillo el cambio de la apariencia de tu
página de una forma rápida y fácil.
Para usar los temas, necesitas decirle a tu controlador que use la clase ThemeView en lugar de
la clase por defecto View.
classExampleControllerextends AppController { var$view= 'Theme'; }
Para declarar qué tema usar por defecto, especifica el nombre del tema en tu controlador.
classExampleControllerextends AppController { var$view= 'Theme';
var$theme= 'ejemplo';
Los archivos de vista de los temas deben estar dentro de la carpeta /app/views/themed/.
Dentro de la carpeta themed, crea una carpeta usando el nombre de tu tema. Después de eso,
la estructura de carpetas dentro de /app/views/themed/example/ es exactamente igual a
/app/views/.
147
Por ejemplo, el archivo de vista de una acción de edición de un controlador de Posts estaría
ubicado en /app/views/themed/example/posts/edit.ctp. Los archivos de Layout estarían en
/app/views/themed/example/layouts/.
Si tienes archivos CSS o JavaScript que son específicos para tu tema, puedes almacenarlos en
una carpeta de tema dentro de la carpetawebroot/. Por ejemplo, tus hojas de estilo serían
almacenadas en /app/webroot/themed/example/css/ y tus archivos JavaScript estarían en
/app/webroot/themed/example/js/.
Todos los helpers de CakePHP son conscientes de los temas y crearán las rutas correctas
automáticamente. Como con los archivos de vistas, si un archivo no está en la carpeta del
tema, se ubicará por defecto en la carpeta webroot principal.
Tema 7: Helpers
1 Usando helpers
Usas helpers en CakePHP haciendo que un controlador sepa de su existencia. Cada controlador
tiene una propiedad $helpers que lista los helpers que estarán disponibles en la vista. Para
habilitar un helper en tu vista, agrega el nombre del helper en el arreglo $helpers del
controlador.
?php
classBakeriesControllerextends AppController
?>
También pueden agregar helpers desde dentro de una acción, de esta forma sólo estarán
disponibles para esa acción y no para las demás acciones que permanezcan a ese controlador.
148
Esto ahorra poder de procesamiento para las demás acciones que no usan el helper, y
mantienen al controlador mejor organizado.
<?php
classBakeriesControllerextends AppController
functionbake
$this->helpers[]= 'Time';
function mix
?>
2 Creando helpers
Si un helper del coreno se ajusta a tus necesidades, los helpers son fáciles de crear.
149
Digamos que quisiéramos crear un helper que pudiera ser usado para mostrar como salida un
link específicamente creado con CSS que lo necesitas en diferentes partes de tu aplicación.
Para poder ajustar tu lógica dentro de la estructura existente de helpers de CakePHP,
necesitarás crear una nueva clase en /app/views/helpers. Llamemos a nuestro
helperLinkHelper. El archivo de clase se verá algo como esto:
<?php
/* /app/views/helpers/link.php */
classLinkHelperextends AppHelper
functionmakeEdit($title,$url)
?>
Existen algunos métodos incluidos en la clase de Helper en CakePHP de la cual quisieras sacar
ventaja:
output(string $string)
150
<?php
functionmakeEdit($title,$url)
</div>") ;
?>
<?php
classLinkHelperextendsAppHelper
151
{
var$helpers=array('Html') ;
functionmakeEdit($title,$url)
$link=$this->Html->link($title,
$url,array('class'=> 'edit')) ;
return$this->output("<div
class=\"editOuter\">$link</div>") ;
?>
4 Usando tu helper
Una vez hayas creado tu helper y de haberlo colocado dentro de /app/views/helpers/, podrás
incluirlo dentro de tus controllers usando la variable especial $helpers.
Una vez tu controller se haya dado cuenta de esta nueva clase, podrás usarla en los views
accesando mediante una variable llamada por ese helper:
152
<?phpecho$link->makeEdit('Change this Recipe',
'/recipes/edit/5') ?>
<?php
functioncustomMethod()
?>
153
Tema 8: Scaffolding
El scaffolding (creación de plataformas temporales) en aplicaciones es una técnica que permite
a un desarrollador definir y crear aplicaciones básicas que pueden crear, retirar, actualizar y
borrar objetos. El scaffolding en CakePHP también permite a los desarrolladores definir cómo
los objetos están relacionados unos con otros, y para crear y romper estos enlaces.
El scaffolding de CakePHP es bastante agradable. Te permite tener una aplicación CRUD básica
funcional en minutos. Es tan agradable, que querrás usarla en aplicaciones de producción.
Ahora, nosotros pensamos que es agradable también, pero por favor, ese cuenta lo que el
scaffoldding (plataforma temporal) es... bueno... es solo una plataforma temporal. Su
estructura flexible la deshaces rápidamente al inicio de un proyecto para poder iniciar. No fue
pensada para ser completamente flexible, fue pensada como una manera temporal de iniciar
un proyecto rápidamente. Si usted se encuentra realmente tratando de personalizar la lógica
en sus vistas, es momento de derrumbar su scaffolding para poder escribir más código.
Scaffolding es una gran manera de iniciar las primeras partes de una aplicación web iniciada.
Los esquemas de bases de datos tempranos son sujetos a cambios, lo cual es perfectamente
normal en una parte temprana del proceso de diseño. Esto tiene su inconveniente: un
desarrollador web detesta formas que nunca serán utilizadas.
154
Si has creado la clase básica del modelo Category en el archivo /app/models/category.php, ya
estás listo para comenzar! Visita http://example.com/categories para ver tu nuevo scaffold.
El crear métodos en controladores que se hayan sido "scaffoldeados" puede causar resultados
no deseados. Por ejemplo, si crea un método index() en un controlador "scaffoldeado", su
método index será mostrado en lugar que la funcionalidad de scaffoling.
El scaffolding es reconocido por sus asociaciones de modelos, así que si tu modelo Category
pertenece a un User ["belongsTo" User], usted verá las IDs del modelo User relacionadas en el
listado del modelo Category. Si usted quisiera ver algo aparte de un ID (como el apellido del
usuario), lo logrará activando la variable $displayField en el modelo.
Inicializaremos la variable $displayField en nuestra clase de User para que los usuarios
relacionados con categorías serán mostrados por el primer nombre en lugar de solo el ID en el
scaffolding. Esta característica hace el scaffolding más leíble en muchas instancias.
<?php
var$name= 'User';
var$displayField= 'first_name';
?>
var$scaffold= 'admin';
155
http://example.com/admin/controller/index
http://example.com/admin/controller/view
http://example.com/admin/controller/edit
http://example.com/admin/controller/add
http://example.com/admin/controller/delete
Esta una manera fácil de crear un simple interface “backend” de manera rápida. Tenga en
cuenta que no podrás tener admins creados con scaffolding y sin esta técnica, de manera
simultánea. Aun así, puedes usar un scaffolding sin interface Admin e incluir métodos
individuales y/o reemplazarlos por sus propios.
functionadmin_view($id=null)
//customcodehere
Una vez hayas reemplazado a una acción scafoldeada necesitarás crear un fichero View para
tal acción.
Vistas personalizadas para un controlador específico (para este ejemplo PostsController) debe
ser colocado como lo siguiente:
/app/views/posts/scaffold.index.ctp
/app/views/posts/scaffold.show.ctp
/app/views/posts/scaffold.edit.ctp
/app/views/posts/scaffold.new.ctp
Las vistas scaffolding personalizadas para todos los controladores deberían ser colocadas como
las siguientes:
/app/views/scaffolds/index.ctp
/app/views/scaffolds/show.ctp
/app/views/scaffolds/edit.ctp
/app/views/scaffolds/new.ctp
/app/views/scaffolds/add.ctp
156
2 Constantes y funciones globales
Aunque en la mayor parte de nuestro trabajo diario en CakePHP utilizaremos clases y métodos
nativos, es útil conocer una serie de funciones globales que ofrece CakePHP. Muchas de ellas
están orientadas al trabajo con las clases de CakePHP (cargando las clases de modelo o
componente), pero muchas otras hacen más sencillo trabajar con matrices o cadenas.
También veremos en esta sección algunas de las constantes disponibles en las aplicaciones
CakePHP. Usarlas ayuda a realizar actualizaciones menos complicadas, además de ser útiles a
la hora de referenciar ciertos archivos o directorios en nuestras aplicaciones CakePHP.
Funciones globales
Éstas son las funciones globales disponibles en CakePHP. Muchas de ellas simplemente
facilitan la llamada a funciones de PHP con nombres largos, pero otras (como vendor() y uses())
se pueden usar para incluir código o realizar otras funciones útiles. Lo más probable es que si
estás buscando una función para realizar una tarea con mucha frecuencia, la encuentres aquí.
a(mixed$uno,$dos,$tres...)
print_r(a('foo', 'bar'));
// salida:
array(
=> 'foo',
=> 'bar'
aa(array$uno,$dos,$tres...)
// salida:
157
array( 'a'=> 'b' )
am(array$uno,$dos,$tres...)
Combina todos los arrays pasados como parámetros y devuelve el array resultante.
Config
Puede ser usado para cargar archivos desde el directorio config mediante include_once. La
función comprueba si existe el archivo antes de incluir y regresa un booleano. Toma un
número opcional de argumento.
Ejemplo:config('some_file', 'myconfig') ;
convertSlash(string $cadena)
Sustituye las barras ("/") por subrayados ("_") y elimina el primer y el último subrayados en
una cadena. Devuelve la cadena convertida.
e(mixed$datos)
env(string $key)
Obtiene una variable de entorno a partir de las fuentes disponibles. Alternativa si las variables
$_SERVER o $_ENV están deshabilitadas.
También permite emular las variables PHP_SELF y DOCUMENT_ROOT en los servidores que no
permitan su uso. De hecho, es una buena práctica usar env() en lugar de $_SERVER o getenv()
(sobre todo si pensamos distribuir el código), ya que ofrece la misma funcionalidad y es
totalmente compatible.
fileExistsInPath(string $archivo)
Comprueba que el fichero $archivo está en el include_path actual de PHP. Devuelve un valor
booleano.
ife($condicion,$siNoVacia,$siVacia)
158
Útil en operaciones ternarias. Si $condicion no es vacía, devuelve $siNoVacia; si no, devuelve
$siVacia.
low(string $cadena)
pr(mixed$var)
up(string $cadena)
uses(string $lib1,$lib2,$lib3...)
Permite cargar las librerías nativas de CakePHP (localizadas en cake/libs/). Pasar como
parámetro el nombre de la librería sin la extensión '.php'.
159
Constantes predefinidas
Hay muchos diferentes aspectos del proceso de validación. En esta sección cubriremos el lado
del modelo, es decir, lo que ocurre cuando tu llamas al método save() de tu modelo. Para más
160
información acerca de cómo manejar el despliegue de errores de validación, revisa la sección
que cubre el FormHelper.
Para hacer eso, usa el arreglo Model::validate en la definición del Modelo, por ejemplo:
<?php
?>
<?php
161
var $name = 'User';
) ;
?>
El ejemplo muestra cómo se pueden agregar reglas de validación a los campos de un modelo.
Para el campo login serán aceptadas sólo letras y números, el email debe ser válido, y born
debe ser una fecha válida. La definición de reglas de validación habilitan en CakePHP el
despliegue automático de mensajes de error en formularos si los datos enviados no cumplen
las reglas de validación.
CakePHP incluye muchas reglas de validación y usarlas puede ser bastante simple. Algunas de
las reglas incluidas permiten verificar el formato de los emails, URLs, y números de tarjeta de
crédito - las cubriremos en detalle más adelante.
Acá tenemos un ejemplo de validación más complejo que aprovecha algunas de las reglas
incluidas:
'login' =>array(
'alphaNumeric' =>array(
162
'rule' => 'alphaNumeric',
) ,
'between' =>array(
) ,
'password' =>array(
) ,
'born' =>array(
163
'message' => 'Ingrese una fecha válida',
) ;
?>
Dos reglas de validación son definidas para login: debería contener sólo letras y números, y su
largo debe ser de 5 a 15. El campo password debe tener un largo mínimo de 8 caracteres. El
email debe contener una dirección de correo válida, y born debe ser una fecha válida. Además,
notar que puedes agregar mensajes de error propios que CakePHP mostrará cuando estas
reglas de validación no se cumplan.
Como lo muestra el ejemplo de arriba, un único campo puede tener múltiples reglas de
validación. Y si las reglas incluidas no coinciden con lo que necesitas, puedes agregar tus
propias reglas de validación según tus requerimientos.
Ahora que viste a grandes rasgos cómo funciona la validación, veamos cómo estas reglas son
definidas en el modelo. Hay tres diferentes maneras para definir reglas de validación: arreglos
simples, una única regla por campo, y múltiples reglas por campo.
2 Reglas simples
Tal como el nombre lo sugiere, esta es la manera más simple de definir una regla de validación.
Donde, 'fieldName' es el nombre del campo para el cual se está definiendo una regla, y
'ruleName' es el nombre de una regla pre-definida.
164
Una regla por campo
Ésta técnica de definición permite un mejor control del funcionamiento de las reglas de
validación. Pero antes de su discusión, veamos el patrón de uso general para agregar una regla
a un solo campo:
) ;
El índice 'rule' es requerido. Si sólo se setea 'required' => true la validación del formulario no
funcionará correctamente. Esto debido a que 'required' no es en realidad una regla.
Como puedes ver, cada campo (arriba se está mostrando sólo un campo) es asociado con un
arreglo que contiene cinco índice: ‘rule’, ‘required’, ‘allowEmpty’, ‘on’ y ‘message’. Veamos
con más detalle cada uno de estos índices.
Rule
El índice ‘rule’ define el método de validación y acepta un sólo valor o un arreglo. El valor para
‘rule’ especificado puede ser el nombre de un método en tu modelo, un método de la clase
coreValidation, o una expresión regular. Para un completo listado de todas las reglas
incorporadas ver la sección llamada "Reglas de Validación Incorporadas".
Si la regla no requiere parámetros, ‘rule’ puede ser un sólo valor, por ejemplo:
165
var $validate = array(
'login' =>array(
) ;
Si la regla requiere algunos parámetros (como max, min o range), entonces ‘rule’ debería ser
un arreglo:
'password' =>array(
'rule' =>array('minLength', 8)
) ;
Required
Este índice debería tener asignado un valor booleano. Si ‘required’ es true, el campo debe
estar presente en el arreglo de datos. Por ejemplo, si la regla de validación ha sido definida de
la siguiente manera:
166
var $validate = array(
'login' =>array(
) ) ;
Los datos enviados al método save() del modelo deben contener un valor para el campo login.
Si no es así, la validación falla (la regla no se cumple). El valor por defecto para este índice es
un false booleano.
Si el índice login está presente pero no tiene un valor asignado, la validación será exitosa.
Setear ‘required’ a true sólo verifica que el índice del campo este presente.
allowEmpty
Al índice allowEmpty se le debería asignar un valor booleano. Si allowEmpty es false, los datos
pasados al método save() del modelo deben incluir el campo a un valor no-vacío para ese
campo. Cuando se deja en true, un campo vacío pasará exitosamente la validación de ese
campo.
El valor por defecto de allowEmpty es null. Esto significa que el campo siempre procesará las
reglas de validación incluyendo la ejecución de funciones de validación propias.
On
El índice ‘on’ puede ser seteado con uno de los siguientes valores: ‘update’ o ‘create’. Esto
provee un mecanismo que permite que cierta regla sea aplicada ya sea durante la creación de
un nuevo registro, o durante la actualización de un registro.
Si la regla fue definida como ‘on’ => ‘create’, entonces la regla sólo será verificada durante la
creación de un nuevo registro. De igual manera, si es definida como ‘on’ => ‘update’, la regla
sólo será verificada durante la actualización de un registro.
El valor por defecto de ‘on’ es null. Cuando ‘on’ es null, la regla será verificada durante la
creación y actualización de un registro.
Message
El índice ‘message’ permite definir un mensaje de error de validación para la regla:
167
password' =>array(
'rule' =>array('minLength', 8) ,
) ;
Si quieres asignar múltiples reglas de validación a un sólo campo, básicamente así es cómo se
verá:
'nombreCampo' =>array(
'nombreRegla' =>array(
) ,
'nombreRegla2' =>array(
168
'rule' => 'nombreRegla2',
) ;
Como puedes ver, esto es bastante similar a lo que hicimos en la sección previa.
Anteriormente, por cada campo teníamos un sólo arreglo con parámetros de validación. En
este caso, cada ‘nombreCampo’ consiste en un arreglo de índices de reglas. Cada
‘nombreRegla’ contiene un arreglo distinto con parámetros de validación.
&login' =>array(
'alphanumeric' =>array(
) ,
'minlength' =>array(
169
'rule' =>array('minLength', '8'),
),
) ;
El ejemplo de arriba define dos reglas para el campo login: alphanumeric y minLength. Como
puedes ver, cada regla se identifica con un nombre de índice. En este caso particular, los
nombres de índice son similares a las reglas que usan, pero el nombre de índice puede ser
cualquier nombre.
Por defecto CakePHP trata de validar un campo usando todas las reglas de validación
declaradas para él y retorna un mensaje de error para la última regla no satisfecha. Pero si el
índice last es dejado como true y la regla no es satisfecha, entonces se mostrará el mensaje de
error para esa regla y no se validará ninguna regla adicional. Así que si prefieres mostrar un
mensaje de error para la primera regla no satisfecha entonces debes dejar 'last' => true por
cada regla.
Si vas a usar mensajes de error internacionalizados podrías especificar los mensajes de error
en las vistas:
'error' =>array(
170
) ) ;
El campo ahora está totalmente internacionalizado, y puedes eliminar los mensajes del
modelo.
alphaNumeric
Los datos para el campo deben contener sólo letras y números.
'login' =>array(
) ;
Between
El largo de los datos para el campo debe estar dentro de un rango numérico específico. Se
debe indicar un valor mínimo y máximo.
171
var $validate = array(
'password' =>array(
) ;
Blank
Esta regla es usada para asegurar que el campo es dejado en blanco o con sólo espacios en
blanco como su valor. Los espacios en blanco incluyen los caracteres de la barra espaciadora,
tabulador, retorno de carro y nueva línea.
'id' =>array(
) ;
172
Boolean
El campo debe contener un valor booleano. Los valores aceptados son “true” o “false”, los
enteros 0 o 1 y las cadenas "0" o "1".
'myCheckbox' =>array(
'rule' =>array('boolean') ,
) ;
Cc
Esta regla es usada para verificar si los datos corresponden a un número de tarjeta de crédito
válido. Acepta tres parámetros: ‘type’, ‘deep’ y ‘regex’.
Bankcard
Diners
Disc
Electron
Enroute
Jcb
Maestro
Mc
Solo
Switch
Visa
Voyager
Si ‘type’ es dejado en ‘fast’, se validan los datos contra el formato numérico de las principales
tarjetas de crédito. También se puede dejar ‘type’ como un arreglo con todos los tipos de
validaciones que se quiere satisfacer.
173
El índice ‘deep’ debería dejarse con un valor booleano. Si es verdadero, la validación usará el
algoritmo de Luhn para tarjetas de crédito (http://en.wikipedia.org/wiki/Luhn_algorithm). Por
defecto el valor se asume como falso.
El índice ‘regex’ permite indicar una expresión regular propia que será usada para validar el
número de tarjeta de crédito.
'ccnumber' =>array(
) ;
Esta regla es usada para comparar valores numéricos. Soporta “is greater”, “is less”,
“greaterorequal”, “lessorequal”, “is less”, “equalto”, y “notequal”. A continuación algunos
ejemplos:
'age' =>array(
174
) ) ;
'age' =>array(
) ;
Comparison
Esta regla es usada para comparar valores numéricos. Soporta “is greater”, “is less”,
“greaterorequal”, “lessorequal”, “is less”, “equalto”, y “notequal”. A continuación algunos
ejemplos:
'age' =>array(
) ) ;
'age' =>array(
175
'rule' =>array('comparison', 'greaterorequal', 18) ,
) ;
Date
Esta regla asegura que los datos enviados estén en un formato de fecha válido. Un único
parámetro (que puede ser un arreglo) puede ser pasado y que será usado para verificar el
formato de la fecha indicada. El valor del parámetro puede ser uno de los siguientes formatos:
dmy’ por ejemplo 27-12-2006 o 27-12-06 (los separadores pueden ser espacio, punto,
guion, slash).
‘mdy’ por ejemplo 12-27-2006 or 12-27-06 (los separadores pueden ser espacio,
punto, guion, slash).
‘ymd’ por ejemplo 2006-12-27 or 06-12-27 (los separadores pueden ser espacio,
punto, guion, slash).
‘dMy’ por ejemplo 27 December 2006 o 27 Dec 2006.
‘Mdy’ por ejemplo December 27, 2006 o Dec 27, 2006 (la coma es opcional).
‘My’ por ejemplo (December 2006 o Dec 2006).
‘my’ por ejemplo 12/2006 o 12/06 (los separadores pueden ser espacio, punto, guion,
slash).
'born' =>array(
176
'message' => 'Ingrese una fecha válida usando el
formato AA-MM-DD.',
) ;
Decimal
Esta regla asegura que el dato es un número decimal válido. Se puede pasar un parámetro
para especificar la cantidad de dígitos requeridos después del punto decimal. Si no se pasa
ningún parámetro, el dato será validado como un número de punto flotante científico, que
causará que la validación no sea satisfecha si es que no se encuentra ningún dígito después del
punto decimal.
'price' =>array(
'rule' =>array('decimal', 2)
) ;
177
Email
Esta regla verifica que el dato sea una dirección de correo electrónico válida. Al pasar un valor
booleano verdadero como segundo parámetro se tratará también de verificar que el host de la
dirección sea válido.
'email' =>array(
) ;
equalTo
Esta regla asegura que el valor sea equivalente a, y del mismo tipo que el valor indicado.
'food' =>array(
178
)
) ;
Extensión
Esta regla verifica que la extensión de archivo sea como .jpg o .png. Para permitir múltiples
extensiones estas se deben pasar dentro de un arreglo.
'image' =>array(
) ;
Ip
Esta regla asegura que haya sido ingresada una dirección IPv4 válida.
'clientip' =>array(
179
'message' => 'Por favor ingrese una dirección IP
válida.'
) ;
isUnique
El dato para este campo debe ser único, no puede ser usado por ningún otro registro.
'login' =>array(
) ;
minLength
Esta regla asegura que el dato cumple con un requisito de largo mínimo.
'login' =>array(
180
'message' => 'Los nombres de usuario deben tener un
largo de al menos 8 caracteres.'
) ;
maxLength
Esta regla asegura que el dato siempre esté dentro del requisito de largo máximo.
'login' =>array(
) ;
Money
Esta regla asegura que el valor sea una cantidad en formato monetario válido.
181
'salary' =>array(
) ;
Multiple
Empleado para validar campos input selectmultiple. Soporta los paramentros "in", "max" y
"min".
'multiple' =>array(
) ;
182
inList
Esta regla asegura que el valor está dentro de un conjunto dado. Necesita de un arreglo de
valores. El valor es válido si coincide con uno de los valores del arreglo indicado.
'allowedChoice' =>array(
) ;
Numeric
Verifica si el dato ingresado es un número válido.
'cars' =>array(
183
) ;
notEmpty
Regla básica para asegurar que un campo no este vacío.
'title' =>array(
) ;
Range
Esta regla asegura que el valor esté dentro de un rango dado. Si no se indica un rango, la regla
va a verificar si el valor es un número finito válido en la actual plataforma.url
'number' =>array(
184
)
) ;
El ejemplo de arriba aceptará cualquier valor mayor a 0 (por ejemplo 0.01) y menor a 10 (por
ejemplo 9.99).
url
Esta regla verifica formatos de URL válidos. Soporta los protocolos http(s), ftp(s), file, news, y
gopher.
) ;
Si la técnica de validación que necesitas usar puede ser completada usando expresiones
regulares, puedes definir una expresión personalizada como una regla de validación de un
campo.
'login' =>array(
185
'message' => 'Sólo letras y enteros, mínimo 3
caracteres'
) ;
El ejemplo de arriba verifica si login contiene sólo letras y enteros, con un largo mínimo de tres
caracteres.
<?php
) ;
186
functionlimitDuplicates($data, $limit)
?>
Notar que los métodos del model/behavior son verificados primero, antes de buscar un
método en la clase Validation. Esto significa que puedes sobreescribir métodos de validación
existentes (como por ejemplo alphaNumeric()) en el nivel de aplicación (agregando el método
a AppModel) , o en el nivel de modelo.
$this->ModelName->set( $this->data ) ;
187
Luego, para verificar si los datos se validan correctamente, usa el método validates del
modelo, que retornará true si es que se valida y false si es que no:
if ($this->ModelName->validates())
} else {
Es importante notar que los datos se deben primero setear al modelo antes de poder
validarlos. Esto es diferente al método save que permite pasar los datos como un parámetro.
También, ten en cuenta que no es necesario llamar a validates antes de llamar a save ya que
save validará automáticamente los datos antes realmente de guardarlos.
188
{
var$paginate=array('limit'=>25,
'order'=>array(
'Post.title'=> 'asc'
) ;
var$paginate=array(
'fields'=>array('Post.id', 'Post.created') ,
'limit'=>25,
'order'=>array(
'Post.title'=> 'asc'
189
)
) ;
Pueden incluirse otras claves en el array $paginate similares a los parámetros del método
Model>find('all'), esto es: conditons, fields, order, limit, page, contain y recursive. De hecho,
puedes definir más de un conjunto de valores de paginación por defecto en el controlador,
simplemente nombra cada parte del array según el modelo que desees configurar:
var$paginate=array('Recipe'=>array(...) ,
'Author'=>array(...)
) ;
190
var$paginate=array(
'limit'=>25,
'contain'=>array('Article')
) ;
Una vez que la variable $paginate ha sido definida, podemos llamar al método paginate() en
las acciones del controlador. Este método devuelve los resultados de find('all') del modelo
(aplicándoles los parámetros de la paginación), y obtiene algunas estadísticas de paginación
adicionales, que son pasadas a la Vista de forma invisible. Este método también añade
PaginatorHelper a la lista de helpers en tu controlador, si es que no estaba ya.
functionlist_recipes()
// similartofindAll(), butfetchespagedresults
$data=$this->paginate('Recipe') ;
$this->set(compact('data')) ;
Puedes filtrar los registros pasando condiciones como segundo parámetro al método
paginate()
191
$data=$this->paginate('Recipe',array('Recipe.title LIKE'=> 'a
%')) ;
2 Paginación en views
Es cosa tuya decidir cómo mostrar los registros al usuario, aunque lo más habitual es hacerlo
mediante tablas HTML. Los ejemplos que siguen asumen una disposición tabular, pero el
PaginatorHelper, disponible en las vistas, no siempre necesita restringirse de ese modo.
// app/views/recipes/list_recipes.ctp
<table>
<tr>
</tr>
<?phpforeach($dataas$recipe): ?>
<tr>
192
</tr>
<?phpendforeach; ?>
</table>
Los enlaces generados por el método sort() de PaginatorHelper permiten a los usuarios hacer
clic en las cabeceras de las tablas y alternar la ordenación de los datos por un campo dado.
<table>
<tr>
</tr>
<?phpforeach($dataas$recipe): ?>
<tr>
</tr>
193
<?phpendforeach; ?>
</table>
<?phpecho$paginator->numbers(); ?>
<?php
echo$paginator->prev('« Previous
',null,null,array('class'=>'disabled')) ;
echo$paginator->next(' Next
»',null,null,array('class'=>'disabled')) ;
?>
<?phpecho$paginator->counter();?>
194
<?php
echo$paginator->counter(array(
?>
Para pasar todos los argumentos de la URL a las funciones del paginador, añade lo siguiente a
tu vista:
$paginator->options(array('url'=>$this->passedArgs)) ;
$paginator->options(array('url'=>array("0","1"))) ;
Todos los parámetros son opcionales. Si create() es llamado sin parámetros, asume que estás
construyendo un formulario que será enviado al controlador actual, ya sea vía la acción add() o
edit(). El método por omisión para el envío es POST. El elemento form es regresado con un ID
DOM. El ID es generado usando el nombre del modelo y el nombre de la acción del controlador
en formato CamelCased. Si fuera a llamar create() dentro de una vista de UsersController, vería
algo como lo siguiente en la vista:
195
<form id="UserAddForm" method="post" action="/users/add">
Puedes también pasar false para el parámetro $modelo. Esto pondrá los datos de tu
formulario en el array: $this->data (en lugar de ponerlos en un sub-array: $this>data['Model']).
Esto puede ser muy útil para formularios cortos que quizá no representen nada en tu base de
datos.
//Output:
2 Cerrando formularios
El FormHelpertambién incluye un método end() que completa el código del formulario. A
menudo, el método end() solo escribe la etiqueta de cierre del formulario, pero el usar end()
también hace que el FormHelper inserte los elementos hidden necesarios en el formulario
para los métodos que dependen de este.
Si una cadena es colocada como primer parámetro del end(), el FormHelper agregará un botón
submit llamado de esa manera además de la etiqueta de cierre del formulario.
196
Output:
<div class="submit">
</div>
</form>
Salida:
197
<?php
echo $this->Form->button('A Button') ;
echo $this->Form->button('Another Button',
array('type'=>'button'));
echo $this->Form->button('Resetthe Form',
array('type'=>'reset'));
echo $this->Form->button('Submit Form',
array('type'=>'submit')) ; ?>
Salida:
<buttontype="submit">A Button</button>
<buttontype="button">Another Button</button>
<buttontype="reset">Resetthe Form</button>
<buttontype="submit">Submit Form</button>
198
Salida:
<select name="data[User][purchased][year]"
id="UserPurchasedYear">
<optionvalue=""></option>
<optionvalue="2009">2009</option>
<optionvalue="2008">2008</option>
<optionvalue="2007">2007</option>
<optionvalue="2006">2006</option>
<optionvalue="2005">2005</option>
<optionvalue="2004">2004</option>
<optionvalue="2003">2003</option>
<optionvalue="2002">2002</option>
<optionvalue="2001">2001v/option>
<optionvalue="2000">2000</option>
</select>
199
month(string $fieldName, mixed $selected, array $attributes, boolean
$showEmpty)
Genera un rango de valores seleccionables con meses.
Salida:
<optionvalue=""></option>
<optionvalue="01">January</option>
<optionvalue="02">February</option>
<optionvalue="03">March</option>
<optionvalue="04">April</option>
<optionvalue="05">May</option>
<optionvalue="06">June</option>
<optionvalue="07">July</option>
<optionvalue="08">August</option>
<optionvalue="09">September</option>
<optionvalue="10">October</option>
200
<optionvalue="11">November</option>
<optionvalue="12">December</option>
</select>
Salida:
<optionvalue=""></option>
<optionvalue="01">1</option>
<optionvalue="02">2</option>
<optionvalue="03">3</option> ...
<optionvalue="31">31</option>
201
</select>
<?php
echo $this->Form->hidden('id') ;
?>
Salida:
isFieldError(string $fieldName)
Devuelve verdadero si $fieldNametiene una validación de error.
<?php
202
if ($this->Form->isFieldError('gender'))
echo $this->Form->error('gender') ;
?>
Salida:
<?php
203
$options=array('M'=>'Male','F'=>'Female') ;
$attributes=array('legend'=>false) ;
echo $this->Form->radio('gender',$options,$attributes) ;
?>
Salida:
<label for="UserGenderM">Male</label>
<label for="UserGenderF">Female</label>
<?php
204
$options = array('M' => 'Male', 'F' => 'Female') ;
?>
Salida:
<optionvalue=""></option>
<optionvalue="M">Male</option>
<optionvalue="F">Female</option>
</select>
<?php
echo $this->Form->submit() ;
?>
Salida:
205
<div class="submit"><input value="Submit" type="submit"></div>
También puedes usar referencias relativas o absolutas UTL a una imagen para ser usado de
título.
Salida:
Salida:
<?php
echo $this->Form->textarea('notes') ;
206
?>
Salida:
Antes de dar un vistazo a los métodos de HtmlHelper, vas a necesitar conocimientos sobre
configuración y usos en las situaciones que te puede ayudar esta clase. En primer lugar, en un
esfuerzo para aliviar a aquellos que usan las etiquetas cortas (< ?= ?>) de forma intensiva o
muchas llamadas a echo() en el código de sus vistas que todos los métodos del HtmlHelper son
pasados por el método output(). Si deseas activar automáticamente la salida para generar
HTML con el ayudante simplemente implementa output() en tu AppHelper.
function output($cadena)
echo$cadena;
Atributos Deseados:
<tagclass="algunaClase"/>
Arreglo de Parámetros:
207
array('name'=> 'foo', 'value'=> 'bar')
El HtmlHelper está disponible en todas las vistas de forma predeterminada. Si usted está
recibiendo un error que le informa que no está ahí, es por lo general debido a su nombre que
está faltando y puede configurarlo manualmente en la variable $helpers del controlador.
charset(string $charset=null)
Usada para crear metadatos que especificarán la codificación de los caracteres del documento.
<?php echo$html->charset();?>
O sinó también:
Salida:
208
meta(string $type, string $url=null,array$attributes=array(), boolean $inline=true)
image(string $path,array$htmlAttributes=array())
script(mixed$url,mixed$options)
tableHeaders(array$names,array$trOptions=null,array$thOptions=null)
tableCells(array$data,array$oddTrOptions=null,array$evenTrOptions=null, $useCount=false,
$continueOddEven=true)
209