Está en la página 1de 209

Contenido

Tema 1: Comenzando con PHP....................................................................................................6


1 Historia de PHP......................................................................................................................6
2 Significado de PHP.................................................................................................................7
3 Características más importantes de PHP...............................................................................8
4 Trabajos que podemos realizar con PHP...............................................................................9
5 Cuando es conveniente utilizar PHP....................................................................................10
6 ASP o PHP............................................................................................................................10
7 Requisitos para trabajar con PHP........................................................................................10
Tema 2: Instalación desde cero..................................................................................................11
1 Opciones de instalación.......................................................................................................11
2 Detalles de la instalación paso a paso.................................................................................11
6 Uso del directorio www.......................................................................................................12
Tema 3: Sintaxis básica...............................................................................................................12
1 Extensiones.........................................................................................................................12
2 Delimitadores del código.....................................................................................................12
3 Espacios en blanco..............................................................................................................13
4 Separación de instrucciones................................................................................................14
5 Comillas...............................................................................................................................14
6 Fin de línea..........................................................................................................................15
7 Construcción de bloques.....................................................................................................15
8 Líneas de comentarios.........................................................................................................16
9 Mayúsculas y minúsculas....................................................................................................16
10 Inclusión de ficheros externos...........................................................................................17
11 Práctica: Mi primer texto...................................................................................................18
12 Práctica: Include................................................................................................................18
Tema 4: Variables y Constantes.................................................................................................18
El valor de las variables......................................................................................................19
Referencias.........................................................................................................................19
Tipos de variables...............................................................................................................19
Forzando los tipos de las variables.....................................................................................20
Operaciones con diferentes tipos de variables...................................................................21
Vectores.............................................................................................................................21
2 Verificación de asignación previa........................................................................................21
3 Variables predefinidas.........................................................................................................22

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.

NOTA: Un CGI, Common Gateway Interface, es un programa que se ejecuta en el servidor,


puede utilizarse para tratar información, como pasarela de una aplicación, como base de datos
o para generar páginas HTML de forma automática.

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.

Nota: No podemos dejar de mencionar el efecto de Internet en la enseñanza. En los últimos


años, ha habido un proceso de adaptación entre el aprendizaje y la red. Son muchas las
entidades dedicadas a la formación (universidades, centros de enseñanza, colegios, etc.) que

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).

La enseñanza se ha globalizado, existe la posibilidad de llegar a cualquier usuario sin


limitaciones geográficas u horarias. No sólo se compite a nivel nacional como antes, la
competencia ha traspasado todas las fronteras, lo que implica una mejora continua en la
calidad de los productos ofrecidos. Las denominadas plataformas de teleformación son el
último avance de los cursos a distancia; implican una formación personalizada, con un
seguimiento continuado, detallado y progresivo de los movimientos de cada usuario del curso,
perfeccionando el proceso de aprendizaje con contenidos interactivos multimedia (audio,
vídeos, simulaciones…) de gran calidad. Hay mayor flexibilidad y personalización a los
estudiantes o a trabajadores que desean ampliar conocimientos.

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.

A continuación, le mostraremos un ejemplo de una misma página programada en HTML y su


homóloga en PHP. Verá como el código PHP va dentro del HTML sin alterarlo.

<? echo'
<html>
<head>
<title>Primera página</title>
<body>
<p> Buenas, me llamo Ana Gessa </p>
</body>
</html>
' ?>

Ésta es la misma página en modo PHP.

<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.

 Del lado servidor: Es un lenguaje reconocido, ejecutado e interpretado en el mismo


servidor, generando un archivo HTML que es enviado al cliente. PHP y ASP, entre
otros, pertenecen a este tipo de lenguaje.
 Del lado cliente: Es aquel lenguaje que puede ser “dirigido” por el navegador y que no
necesita un tratamiento previo. Destacamos: HTML, Java y JavaScript.

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:

 PHP no distingue mayúsculas y minúsculas, salvo en el tratamiento de objetos


 En PHP no se declaran las variables ni tienen un tipo fijo, sino que las variables pueden
almacenar valores de todo tipo.

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.

4 Trabajos que podemos realizar con PHP


Con este lenguaje se puede realizar todo aquello que pueda crearse con un script CGI, por
ejemplo, generar páginas con contenidos dinámicos, mandar o recibir cookies, procesar los
resultados de los formularios, funciones de correo electrónico, gestiones con bases de datos,
trabajar con archivos, tratamiento de imágenes…

NOTA: Una cookie es un mecanismo que permite al servidor almacenar en el cliente


información relativa a la transacción o al usuario.

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…

5 Cuando es conveniente utilizar PHP


Tanto si se desarrolla bajo una plataforma UNIX o Linux, debe elegir entre Perl y PHP. Este
último es considerado por muchos programadores más simple a la hora de escribir script,
haciéndolo más productivo en proyectos no demasiado grandes. Por supuesto, se pueden
utilizar ambos lenguajes simultáneamente.

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.

A continuación se enumeran una serie de ventajas del PHP:

 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.

PHP también presenta algunas desventajas:

 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.

7 Requisitos para trabajar con PHP


Si usted tiene limitado el acceso a Internet y programa de manera local, para visualizar las
páginas creadas con PHP necesita instalar un servidor Web como Apache. Necesitará el
módulo PHP, que es el responsable de interpretar el código y mostrarlo en el navegador. Si
quiere trabajar con bases de datos desde PHP, deberá instalar un gestor de base de datos
como MySQL. Para crear las páginas en PHP, con cualquier editor de textos podrá desarrollar y
guardar las páginas con extensión .php.

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.

Tema 2: Instalación desde cero


Antes de comenzar a explicar el proceso de instalación en esta lección, es imprescindible
conocer la definición de servidor, los requisitos que tiene que cumplir un PC para que funcione
como tal y conocer cómo se puede acceder a él y a sus recursos.

Un servidor es un PC que proporciona servicios a otros ordenadores. Un PC posee la condición


de servidor Web si está conectado a Internet o a una red de área local (Intranet), y a su vez,
está dotado de un software específico denominado software de servidor HTTP, que posibilita
el acceso desde los PC clientes a los recursos que contiene, ya sean archivos o dispositivos.

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.

2 Detalles de la instalación paso a paso


Los requisitos mínimos para comenzar a trabajar con PHP son:

 Un servidor Apache, que será el que gestione el acceso a las páginas.


 El módulo PHP, que es el conjunto de archivos necesarios para interpretar
correctamente las páginas con extensión .php.
 Y si va a trabajar con bases de datos para crear páginas dinámicas, es conveniente
instalar también MySQL, que se encargará de las bases de datos compatibles con 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.

Si desea abrir cualquier otro fichero, escriba en la Barra de direcciones


http://localhost/nombre_archivo.

Tema 3: Sintaxis básica


A lo largo de esta lección, nos introduciremos en la sintaxis básica para comenzar a programar
en PHP. Es importante familiarizarse con estas nociones iniciales, puesto que son la base de
este lenguaje.

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:

 .php3 - es código PHP 3.x.


 .php4 - es código PHP 4.x.
 .php - es una extensión genérica, y la más utilizada.
 .phtml - en desuso.

2 Delimitadores del código


El código PHP se introduce en el código HTML, pero para que el servidor detecte la parte en
PHP de una página, éste tiene que estar delimitado con unas etiquetas especiales que van al
principio y al final del código PHP.

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.

Existen cuatro opciones para delimitar el código PHP, éstas son:

Etiquetas cortas:

<? echo ‘Primer tipo de delimitador en el código PHP'; ?>

12
Etiquetas canónicas:

<?php echo ‘Segundo método, y más utilizado; ?>

Etiquetas estilos HTML:

<script language=”php”>

echo ‘Algunos editores solo entienden este delimitador de PHP;

</script>

Etiquetas estilos ASP:

<% echo ‘Método compatible con el código ASP'; %>

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.

 EJEMPLO: Un ejemplo práctico del uso del código PHP es:

<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.

La etiqueta de cierre ?> implica el fin del script.

<? echo “Separación de instrucciones” ; ?>

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.

Existen dos tipos de comillas:

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.

Existen dos tipos de comillas:

 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.

EJEMPLO: Ejemplo práctico de textos equivalentes:

<?php

echo ‘Estos dos textos se mostrarán


iguales en
el navegador';

echo ‘Estos dos textos se mostrarán iguales en el navegador';

?>

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:

 En las variables, diferenciar entre mayúsculas y minúsculas es muy importante.


 En los nombres de funciones y en construcciones del lenguaje, PHP no es sensitivo a
diferenciar entre mayúsculas y minúsculas.

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 ) {

print ( “ Correcto, el resultado es 5.<br> ” ) ;

print ( “ Pero no te equivoques. <br> ” ) ;

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.

Para varias líneas de comentario, PHP utiliza:

 /* al comienzo de la primera línea.


 */ al final de la última 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.

• # Comentario estilo Bash/Perl. Cubre solo hasta el fin de línea.

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:

 En las variables, diferenciar entre mayúsculas y minúsculas es muy importante.


 En los nombres de funciones y en construcciones del lenguaje, PHP no es sensitivo a
diferenciar entre mayúsculas y minúsculas.

En las variables, diferenciar entre mayúsculas y minúsculas es muy importante.

<?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 .
?>

En los nombres de funciones y en construcciones del lenguaje, PHP no es sensitivo a


diferenciar entre mayúsculas y minúsculas. Es indiferente que se escriba la función PRINT() o
print(), puesto que el resultado será el igual.

<?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.
?>

10 Inclusión de ficheros externos


Una forma muy útil de agregar código PHP a nuestro programa es insertando dicho código en
otro fichero e invocarlo mediante las funciones include() y require().

A continuación, veremos un ejemplo:

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:

Realizar un programa que muestre este texto por pantalla:

“Este texto es un ejemplo muy fácil y seguramente lo hagamos bien.


Si no es así, debemos repasar la lección.”.

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:

Realizar un programa que muestre el mismo texto de la práctica anterior


utilizando el mismo archivo.

<?php
include(“practica.php”);
?>

practica2.php

Tema 4: Variables y Constantes


En esta lección, le explicaremos detalladamente las variables y las constantes. Hablaremos de
las variables predefinidas, de sus usos y características. Tenga presente a la hora de afrontar
esta lección, que éstos son conceptos esenciales que debe dominar desde el inicio para
controlar la programación en 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:

 Todas las variables en PHP comienzan con el símbolo “$”.


 Son asignadas con el operador ‘='. La variable a la izquierda del operador y la expresión
a evaluar a la derecha.

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 de diferentes tipos de variables:

EJEMPLO: <?php
$variableCadena = "Variable";
$variableNumero = 57;
$variableDecimal = 8.5;
?>

El valor de las variables


Los valores de las variables cambian continuamente, pero siempre serán iguales al último valor
fijado. En PHP, las variables se asocian a un contenido del tipo que sea, y dichas variables se
modifican cuantas veces lo haga su contenido.

EJEMPLO: $variable = “Cadena de texto”;

$variable = 6; // Ahora la variable es un entero


$variable = 5,7 * $variable; // Ahora la variable es un float
$variable = nueva funcion(); // Ahora la variable es un objeto

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.

Las variables pueden ser de 3 tipos:

 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

Tipo Definición Ejemplo

Integer Para valores numéricos comprendidos entre -231 y 231. $a=2547896

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.

Forzando los tipos de las variables


En PHP se pueden forzar los tipos de las variables, es decir, se puede asignar un determinado
tipo a una determinada variable, independientemente de su valor real.

Forzado de una variable a tipo Integer

Se consigue anteponiendo a su valor una de estas expresiones: (Integer) o (int). Un ejemplo


sería:

$variable=((Integer)3.8) o $variable=((int)3.8)

Forzado de una variable a tipo Double

Se obliga a la variable anteponiéndole a su valor una de estas expresiones: (double) o (real) o


(float).

$variable=((double)57) o $variable=((real)57) o $variable=((float)57)

Forzado de una variable a tipo String

Se obtiene introduciendo antes que el valor la expresión (string).

$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)

La función settype realiza la conversión y devuelve un valor verdadero o falso.

Operaciones con diferentes tipos de variables


PHP permite realizar operaciones aritméticas con los tres tipos de variables. Pero tenemos que
tener en cuenta las siguientes consecuencias:

 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]";

?>

Otra forma de declarar vectores es la siguiente:

<?php

$v=array(a=>”Sevilla”,b=>”Huelva”,c=>”Granada”);
echo “$v[a], $v[b], $v[c]”;

?>

2 Verificación de asignación previa


Podemos verificar si una variable ha sido anteriormente asignada con la función IsSet () de la
siguiente manera:

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.

A continuación le indicamos algunas de estas variables predefinidas, y le especificamos la


información que muestran.

VARIABLES PREDIFINIDAS

 GATEWAY_INTERFACE: Indica qué revisión de la especificación CGI está usando el


servidor.
 SERVER_NAME: Muestra el nombre del servidor en el que se ejecuta el script de PHP.
 SERVER_SOFTWARE: De scribe la cadena de identificación del servidor que aparece en
las cabeceras al responderse a las peticiones.
 SERVER_PROTOCOL: Da el nombre del protocolo a través del que se solicitó la página.
 REQUEST_METHOD: Nos dice el método de petición que se utilizó para ir a la página.
 QUERY_STRING: Muestra la cadena de petición con la que se accedió a la página.
 DOCUMENT_ROOT: Revela el directorio raíz del documento bajo que se ejecuta el
script, tal y como está definido en el fichero de configuración del servidor.
 HTTP_ACCEPT: Enseña los tipos MIME que el cliente puede recibir.
 HTTP_ACCEPT_CHARSET: Indica cuáles son los contenidos de la cabecera Accept-
Charset de la petición actual.
 HTTP_ENCODING: Permite ver los contenidos de la cabecera Accept-Encoding de la
petición actual.
 HTTP_ACCEPT_LANGUAGE: Da los contenidos de la cabecera Accept-Language de la
petición actual.
 HTTP_CONNECTION: Enseña el tipo de conexión HTTP que está en uso. Generalmente
Keep-Alive, esto indica que el servidor no debe cerrar la conexión con el cliente.
 HTTP_HOST: Describe los contenidos de la cabecera Host de la petición actual.
 HTTP_REFERER: Revela la dirección de la página desde la que el navegador accedió a la
página actual.
 HTTP_USER_AGENT: Muestra desde qué navegador se está accediendo para ver la
página.
 REMOTE_ADDR: Permite visualizar la dirección IP desde la que el usuario está viendo
la página actual.

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.

Donde antes se ponía el nombre de la variable, ahora se pone $HTTP_SERVER_VARS[‘nombre


de la variable']. Un ejemplo claro sería:

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++;
}
?>

A partir de ahora, cuando llamemos a la función Prueba(), se representará el valor de “$var” y


se incrementará.

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";
?>

A partir de ahora, ya tenemos definidas y almacenadas dos variables en el árbol de símbolos de


PHP: una sería $variable, que contiene la cadena "hola", y la otra sería $hola, que contiene la

25
cadena "mundo". Por lo tanto, estas dos sentencias producen el mismo resultado: “hola
mundo”.

<?php
echo "$variable ${$variable}";
?>

<?php
echo “$variable $hola”;
?>

6 Definición de una constante


En PHP tenemos que definir las constantes utilizando la función define(), cuya declaración es:

define(“nombre”, “valor” [, noMayusculas])

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:

 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.

Un ejemplo de declaración y uso de constantes en PHP sería:

<?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:

 __FILE__: Recoge el nombre del archivo de comandos que se está ejecutando


actualmente y también la ruta completa de su ubicación en el servidor.
 __LINE__: Registra el número de línea, también considera las líneas en blanco dentro
del archivo PHP que está siendo interpretado en la actualidad. Si se usa dentro de un
archivo incluido o requerido, entonces se da la posición dentro del archivo incluido. Es
una constante muy útil, puesto que con ella se pueden depurar las páginas PHP.

NOTA: No olvide, que tanto la constante FILE como LINE llevan dos rayas delante y otras dos
detrás.

 PHP_VERSION: Recoge la versión PHP en uso por el servidor.


 PHP_OS: Indicará información del sistema operativo que utiliza el servidor en el cuál se
está interpretando el fichero PHP.
 TRUE: Valor verdadero.
 FALSE: Valor falso.
 E_ERROR: Denota un error distinto de un error de interpretación del cual no es posible
recuperarse.
 E_WARNING: Denota una condición donde PHP reconoce que hay algo erróneo, pero
continuará de todas formas; pueden ser capturados por el propio archivo de
comandos.
 E_PARSE: Indicará que el intérprete encontró sintaxis inválida en el archivo de
comandos, y que la recuperación no es posible.
 E_NOTICE: Ocurrió algo que pudo ser o no un error. La ejecución continúa. Los
ejemplos incluyen usar una cadena sin comillas como un índice "hash", o acceder a
una variable que no ha sido inicializada.

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:

Realizar un programa que cumpla los siguientes requisitos:


1. El título de la página será “CONSTANTES”.
2. Deberá mostrar la ruta del fichero, la versión de PHP
que estamos utilizando y el sistema operativo
utilizado.
3. Deberemos incluir comentarios.
4. Crear una constante, la cual nos deberá mostrar su
nombre y primer apellido.

<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.

1 Que son los operadores


Los operadores se definen como símbolos que expresan operaciones que se pueden realizar
entre dos o más elementos, a éstos los llamaremos operandos.

Por medio de dichos operadores, las variables pueden ser creadas, modificadas y comparadas
entre sí.

2 Operadores de asignación y de concatenación


Los operadores de asignación y de concatenación son los más simples. Pero también son los
más usados por los programadores.

 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.

Los principales operadores aritméticos son:

+ Suma

- Resta

* Multiplicación

/ División

% Devuelve el resto de la división

Por ejemplo, 2 % 2 dará como resultado 0, mientras que 6 % 5 dará 1.

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

$b = 6; // Asignamos a “b” el valor 6


echo 'a = ' . $a . ', b = ' . $b . '<P>';

// 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).

Podemos estudiar los siguientes operadores de comparación:

== Igualdad

!= Desigualdad

< Menor que

<= Menor o igual que

> Mayor que

>= Mayor o igual que

31
Como ejemplo de cada uno de ellos, tenemos:

- $a == $b: Es verdadero si $a es igual a $b.


- $a != $b: Es verdadero si $a es distinto que $b.
- $a < $b: Es verdadero si $a es menor que $b.
- $a <= $b: Es verdadero si $a es menor o igual que $b.
- $a > $b: Es verdadero si $a es mayor que $b.
- $a >= $b: Es verdadero si $a es mayor o igual que $b.

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.

Los principales operadores lógicos son:

&& And (Y)

|| Or (O)

! NOT (Negación)

Un ejemplo claro de cada operador lógico sería:

 $a && $b: (Y) Es verdadero si tanto $a como $b son verdaderos.


 $a || $b: (O) Es verdadero si $a o $b son verdaderos.
 ! $a: (Negación) Es verdadero si $a no es verdadero.

Vamos a realizar un ejemplo de operadores lógicos. Partiendo de tres variables (a, b y c) y


vamos a realizar distintas operaciones con ellas:

<HTML>

<BODY>
<?php
$a = 10; // Asignamos a la variable “a” el valor 10

$b = 6; // Asignamos a la variable “b” el valor 6


$c = 11; // Asignamos a la variable “c” el valor 11
echo 'a = ' . $a . ', b = ' . $b . ', c = ' . $c . '<P>';

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:

$variable++ Aumenta en 1 el valor de la variable indicada

$variable-- Disminuye en 1 el valor de la variable indicad

A la hora de insertar un operador de incremento o decremento en nuestro código PHP, hay


que hacerlo de la siguiente manera:

 $a++: Devuelve $a y después incrementa $a en una unidad.


 $a--: Devuelve $a y después decrece su valor en una unidad.

7 Sentencias Condicionales If, Else-If, Elseif, Else


PHP, como lenguaje de programación que es, posee órdenes de control de flujo, es decir,
permiten al programa tomar decisiones lógicas según los parámetros que reciba. Por ejemplo,
si hace frío ponte un abrigo; pero si hace calor déjalo en tu casa.

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;

...

Veamos un ejemplo para entenderlo mejor:

<?php

$edad = "";

if ($edad < 18)

echo "Lo siento, no puedes entrar aquí";

else

echo "Adelante, puedes entrar";

?>

No es necesario usar la declaración “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

if (($precio <= 3000)&& ($km <= 45000))


{ echo “Este coche me lo voy a comprar”;
}
?>

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, 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. Con esto, simplificamos un poco el
ejemplo anterior:

if (condición1)
{
Sentencia 1;
Sentencia 2;
...
}
elseif (condición2)
{
Sentencia 3;
Sentencia 4;
...
}
else
{
Sentencia 5;
...
}

Un ejemplo de esta instrucción sería:

<?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”.

8 Práctica: Mayor de dos números


MAYOR DE DOS NÚMEROS:

Programa que asigne dos valores distintos a dos variables y nos diga cuál es la
mayor de las dos.

El programa nos deberá mostrar lo siguiente:

<?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.”;
}
?>

9 Práctica: Carne del polideportivo


CARNE DEL POLIDEPORTIVO:

Realizar un programa que, según la edad que escribamos, nos diga cuánto
vale sacarse un carné en el polideportivo.

Deberemos seguir estos pasos:

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.

Deberemos conseguir que nos aparezca por pantalla lo siguiente:

<?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.
?>

10 Práctica: Valor de variable


PEDIDO 1:

Realizar un programa que, según el valor de la variable $var que se defina


al comienzo, imprima alguno de estos mensajes:

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.";
}
?>

11 Práctica: Ordenar de menor a mayor


ORDENAR:

Realizar un programa donde se dé valor a tres variables y se ordenen de menor a


mayor.

<?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;
...
}

Un breve ejemplo sería:

<?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.

EJEMPLO:A continuación vemos un ejemplo. En él se recorre una cadena hasta


que encontremos un determinado carácter. Si encuentra dicho carácter, se
muestra la posición en que lo ha encontrado; si por el contrario, no lo encuentra,
nos muestra un mensaje de error advirtiéndolo.

<?

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)

Un breve ejemplo para entender este bucle sería:

<?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:

 Valor inicial de la variable de control.


 Valor final de la variable de control.
 Incremento de dicha variable.

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”.

La sintaxis de un bucle For es la siguiente:

for (valor_inicial ; valor_final ; incremento/decremento)

{ 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

for ($i = 1; $i <=10; print $i, $i++);


?>

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:

Foreach ($array as $clave=>$valor)


{
Instrucción1;
Instrucción2;
…;
}

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.

Vamos a realizar un ejemplo práctico de cómo se ejecuta un bucle “Foreach”:

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

$matriz = array ('uno', 'dos', 'tres', 'cuatro', 'para', 'cinco');


while (list (, $contar) = each ($matriz)) {
if ($contar == 'para') {
break;
}
echo "$contar<br>\n";
}
?>

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";
}

Por lo tanto, la sentencia “Switch” tiene la siguiente sintaxis:

<?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.

8 Práctica: Días de la semana


DIAS DE LA SEMANA:

Realizar un programa que según el día de la semana que marquemos, nos


diga la actividad que tenemos que realizar dicho día.

Esta práctica la realizaremos mediante la sentencia “switch”. Por ejemplo, si


escribimos jueves el programa nos deberá mostrar:

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.";
}
?>

9 Práctica: Buscando una letra


BUSCANDO UNA LETRA:

Realizar un programa que me diga si hay alguna letra “u” en una


determinada cadena y en qué posición se encuentra.

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

$texto = "Esto es un ejercicio de repaso.";


$i=0;
do {
$i++;
}while ($texto[$i]!="u" && $i< strlen($texto));
if ($i==strlen($texto))
echo "En el texto no existe ninguna letra u.";
else
echo "La hemos encontrado. Está en la posición $i.";
?>

10 Práctica: Números divisibles entre 5


NÚMEROS DIVISIBLES:

Elaborar un programa que imprima en pantalla todos los números del 1 al


100 divisibles entre 5 así como su suma.

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.";
?>

11 Práctica: Valores entre dos enteros


VALORES:

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)
?>

12 Práctica: Tablas de multiplicar


TABLAS DE MULTIPLICAR:

Realizar un programa que muestre las tablas del multiplicar del 1 al 10.

El resultado sería:

<?php

for($i=1; $i<=10; $i++)


{
echo "Tabla del $i<BR>";

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.

1 Qué es una Función


Una función es un conjunto de instrucciones donde tenemos que procesar variables para
obtener el resultado buscado. Las funciones en PHP son muy fáciles de manejar. Para que la
función realice la tarea determinada, debemos llamar correctamente a la función, definiendo
los parámetros y variables oportunos.

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")

A continuación, vamos a crear un archivo que lo llamaremos “encabezado.php”, en el que


almacenaremos una cabecera para nuestra página. A dicho archivo, lo podremos llamar
cuando queramos en nuestro script:

<?php function crear_cabecera($titulo)


{
$nombre="<HTML>\n<HEAD>\n\t$titulo\n</HEAD>\n";
echo $nombre;
}
?>

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);
?>

2 Cómo se crea una Función


Para crear una función debemos poner siempre en el inicio la palabra “function” seguida del
nombre de la función. Entre paréntesis deberemos escribir los valores que vamos a utilizar en
nuestra función. Su sintaxis sería la siguiente:

<?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.

NOTA: Por otro lado, es lo mismo escribir nombre_de_la_función que


NOMBRE_DE_LA_FUNCIÓN, ya que PHP no distingue entre mayúsculas y minúsculas. Es
recomendable escribir las funciones y demás código de la misma manera, ya que facilita la
corrección de los posibles errores de sintaxis que pudiéramos tener en nuestro código.

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.

Veamos a continuación un ejemplo de una función:

<?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.

3 Cómo se invoca una Función


Para invocar una función, basta con poner el nombre de la función seguido de un punto y
coma (;) como podemos ver aquí:

<?php nombre_de_la_funcion (); ?>

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:

function numerar ($x=4,$z=7)

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:

function numerar ($x,$z)

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);

Veamos unos ejemplos para comprenderlo mejor:

<?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>”;
?>

4 Funciones para la gestión de archivos


Las funciones para la gestión de archivos más importante son:

Copy
Esta función coge el archivo escrito en $origen y lo copia en $destino.

copy ($origen, $destino)

Rename
Esta función coge el nombre del archivo $antes y lo cambia por el archivo $después.

rename ($antes, $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:

- “r” solo lectura.

- “r+” lectura y escritura.

- “w” solo escritura.

- “w+” lectura y escritura. Suprime el contenido anterior y el archivo es creado si no existe.

- “a” solo escritura. El archivo se crea si no existe y el puntero se coloca al final.

- “a+” lectura y escritura. El archivo se crea si no existe y el puntero se coloca al final del
fichero.

$id = fopen ($archivo, $modo)

Fgets
Esta función lee una línea de un archivo en concreto hasta un número máximo de caracteres.

fgets ($id, $max)

Fwrite
Esta función permite escribir una cadena dentro del archivo señalado.

fwrite ($id, $cadena)

55
Fseek
Esta función avanza o retrocede un puntero tantas posiciones como indiquemos.

fseek ($id, $posición)

Feof
Esta función realiza la comprobación de que el puntero llegó al final de la función.

feof ($id) feof ($id)

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)

5 Funciones para la gestión de directorios


Las funciones para la gestión de directorios más importante son:

Opendir
Esta función abre el directorio situado en $path y le asigna el valor $dir.

$dir = opendir ($path)

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.

mkdir ($path, $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//

while ($elemento = readdir ($dir))


{
echo $elemento."<br>";
}
//cerrar directorio//

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.

La sintaxis de return sería:

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.

7 Práctica: El número mayor


NÚMERO MAYOR:

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 = "";

if ($a > $b) {


$cadena = $a." es mayor que ".$b.”.”;

58
} else {
$cadena = $b." es mayor que ".$a.”.”;
}
return $cadena;
}

echo mayor(7,3),"<br>";
?>

8 Práctica: Media aritmética


MEDIA ARITMETICA:

Realizar un programa que nos muestre la media aritmética de dos números


cualquiera.

En esta práctica utilizaremos la orden return. Además, el título de la página será


“FUNCIONES”. Nos debe salir como resultado lo siguiente:

<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:

Realizar un listado de todo el contenido de la carpeta /www donde están


alojadas sus páginas Web.

<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.

Los atributos más destacados son los siguientes:

 ACTION: Indica la dirección del script que va a procesar la información.


 METHOD: Especifica la forma de envío de los datos. Existen dos opciones: POST y GET.
Dependiendo de la finalidad que busquemos en el formulario utilizaremos uno u otro.
Utilizamos POST cuando enviamos los datos por la entrada estándar STDIO, y GET para
enviar los datos por la URL.

<FORM ACTION="ejemplo.php" METHOD="POST/GET">

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.

EJEMPLO: A continuación vemos un ejemplo:

<FORM ACTION="ejemplo.php" METHOD="POST">


Nombre:   <INPUT TYPE="text" NAME="nombre" SIZE="20" />
<br><br>
Apellido:    <INPUT TYPE="text" NAME="apellido" SIZE="20" />
<br><br>
Telefono:  <INPUT TYPE="text" NAME="telefono" SIZE="20" />
<br><br>
<INPUT TYPE="submit" NAME="aceptar" VALUE="ACEPTAR"/>
</FORM>

El ejemplo anterior genera tres campos en los que nuestro usuario


escribirá su nombre, apellido y teléfono. Cuando éste pulse el botón
ACEPTAR, los datos se enviarán al archivo “ejemplo.php” en la
primera línea. Dicho ejemplo se verá en nuestra pantalla de la forma
siguiente:

2 Campos de entrada de datos


Como hemos visto en el punto anterior, en el interior de las etiquetas <FORM> y </FORM>
insertamos los campos deseados de entrada de datos. A continuación explicaremos algunos de
estos campos.

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.

<INPUT TYPE="text" NAME="nombre" SIZE="20" VALUE="Javier">

El resultado que aparece en pantalla es el siguiente:

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 “ ”.

Nombre   <INPUT TYPE="text" NAME="nombre" SIZE="20" VALUE="Javier">

En pantalla nos deberá aparecer:

4 Cuadro de texto con barras de desplazamiento


Este campo se utiliza cuando el texto es demasiado largo y queremos que se muestre y se
pueda leer completamente. Para desplazarnos dentro del cuadro usamos las barras de
desplazamiento.

<TEXTAREA ROWS="5" NAME="largo" COLS="20">Es un texto largo y ocupa más de


una línea.</textarea>

En nuestro navegador veremos lo siguiente:

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.

Estas casillas tienen la forma siguiente:

Debemos escribir lo siguiente:

<INPUT TYPE="checkbox" NAME=" amarillo " VALUE="ON">   Amarillo <br>


<INPUT TYPE="checkbox" NAME="rojo" VALUE="ON">  Rojo<br>
<INPUT TYPE="checkbox" NAME="verde" VALUE="ON">  Verde<br>
<INPUT TYPE="checkbox" NAME="azul" VALUE="ON">  Azul<br>
<INPUT TYPE="checkbox" NAME="naranja" VALUE="ON">  Blanco <br>

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.

Debemos escribir lo siguiente:

Día de la semana:<br>

<INPUT TYPE="radio" VALUE="lun" NAME="dia">  Lunes<br>


<INPUT TYPE="radio" VALUE="mar" NAME="dia">  Martes<br>
<INPUT TYPE="radio" VALUE="mier" NAME="dia">  Miércoles<br>
<INPUT TYPE="radio" VALUE="juev" NAME="dia">  Jueves<br>
<INPUT TYPE="radio" VALUE="viern" NAME="dia">  Viernes<br>
<INPUT TYPE="radio" VALUE="sab" CHECKED NAME="dia">  Sábado<br>
<INPUT TYPE="radio" VALUE="dom" NAME="dia">  Domingo<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.

En el navegador deberá aparecer lo siguiente:

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>.

Debemos escribir el siguiente código:

63
Estudios:<br>
<SELECT NAME=”estudios”>
<OPTION SELECTED> ESO
<OPTION> Bachillerato
<OPTION> Ciclos Formativos
<OPTION>Garantía Social
</SELECT>

Y en nuestro navegador nos aparecerá:

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.

<INPUT TYPE="submit" VALUE="Aceptar" NAME="aceptar">

En nuestro navegador se muestra como:

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.

Para insertar un campo oculto deberemos escribir lo siguiente:

<INPUT TYPE="hidden" NAME="salario" VALUE="900">

En este caso asignamos el valor de 900 a este campo, pero no lo podremos ver, ya que es un
campo oculto (hidden).

A continuación vamos a realizar un sencillo cuestionario utilizando la mayoría de los campos de


entrada de datos que hemos explicado anteriormente:

<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

<select size="1" name="deporte">


<option selected value="Fútbol">Fútbol</option>
<option value="Tenis">Tenis</option>
<option value="Baloncesto">Baloncesto</option>
<option value="Golf">Golf</option>
<option value="Atletismo">Atletismo</option>
<option value="Balonmano">Balonmano</option>

<option value=&qmargin-left: 75"><option value="Otro">Otro</option>


</select></p>
<p>Aficiones

<br><input type="checkbox" name="aficiones[]" value="Deporte"> Deporte


<br><input type="checkbox" name="aficiones[]" value="Música"> Música
<br><input type="checkbox" name="aficiones[]" value="Motor"> Motor
<br><input type="checkbox" name="aficiones[]" value="Leer"> Leer
<br><input type="checkbox" name="aficiones[]" value="Escribir"> Escribir
<br><input type="checkbox" name="aficiones[]" value="Otras"> Otras
</p>
<p>¿Cuál es tu sexo?</p>

<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>";
?>

Este cuestionario mostrará en pantalla:

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:

En esta práctica vamos a realizar un sencillo cuestionario en el que


realizaremos una serie de preguntas, las cuales tendrán tres respuestas
cada una, siendo una de ellas la respuesta correcta. Utilizaremos botones
de opción para cada una de las respuestas. El resultado debe ser una cosa
parecida a la siguiente:

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>";
}
?>

12 Práctica: Formulario de solicitud de información


FORMULARIO:

En esta práctica, vamos a realizar un formulario que solicite información


personal, como el que aparece en la imagen. Al pulsar “MANDAR” se
enviará la información a un archivo de texto llamado fichero.txt.

Por último, crearemos un archivo que lea el contenido del fichero.txt y lo


muestre en pantalla.

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>

9: Bases de Datos MySQL I


En el desarrollo de esta lección aprenderemos a manejar bases de datos, las cuales pueden
servir a nuestro sitio para almacenar contenidos de una forma ordenada para buscarlos y
editarlos rápidamente. Existen varios programas destinados a facilitar el trabajo con bases de
datos, nosotros utilizaremos en esta lección MySQL - Front.

1 Introducción a MySQL – Front


Una base de datos es un conjunto de tablas en las que podemos almacenar diferentes
registros, los cuales son catalogados en función de distintos parámetros que los caracterizan.

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.

2 Instalando MySQL – Front


3 Empezando con bases de datos
4 Creación de una base de datos

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.

6 Añadir campos a una tabla


7 Modificar campos de una tabla
8 Borrar campos de una tabla
9 Operaciones con los registros de una tabla
10 Editor SQL
11 Práctica: Realizar una base de datos para clientes
BASE DE DATOS:

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:

Añada a la base de datos los siguientes elementos:

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","");

Tema 10: Bases de Datos MySQL II


PHP dispone de un gran número de funciones que nos permiten conectar y trabajar con la
mayoría de bases de datos vía Web. Estas funciones se valen de un potente lenguaje universal
para la comunicación con las bases de datos llamado SQL (Structured Query Language).

A lo largo de este último capítulo, aprenderemos a conectar y realizar las operaciones


principales con bases de datos MySQL (realizar listados de contenidos, añadir, borrar o
modificar registros de las tablas, etc.). Para ello haremos uso de las principales funciones de la
amplia colección de la que dispone PHP para trabajar con bases de datos MySQL y algunas
sentencias básicas SQL que utilizarán estas funciones.

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.

2 Conexión con la base de datos


Antes de realizar cualquier tipo de operación con una base de datos desde una Web, debemos
realizar una conexión al servidor MySQL y a la propia base de datos. Esto se hace mediante las
funciones mysql_connect y mysql_select_db respectivamente cuya sintaxis es:

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");
?>

Para trabajar con nuestro servidor local.

<?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";

Para nuestra Web crearemos el siguiente archivo:

<?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:

Mysql_query (“sentencia SQL”);

Una forma de hacerlo sería la siguiente:

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>

<B>Nombre</B> <INPUT TYPE=TEXT NAME=nombre maxlength="20"><BR>


<B>Primer apellido</B> <INPUT TYPE=TEXT NAME=ape1 maxlength="15"><BR>
<B>Segundo apellido</B> <INPUT TYPE=TEXT NAME=ape2 maxlength="15"><BR>
<B>DNI</B> <INPUT TYPE=TEXT NAME=dni maxlength="10"><BR>
<B>Estado Civil </B> <INPUT TYPE=radio NAME=civil VALUE=Soltero> Soltero
<INPUT TYPE=radio NAME=civil VALUE=Casado> Casado<BR>
<B>Domicilio</B> <INPUT TYPE=TEXT NAME=domicilio maxlength="50"><BR>

<B>Localidad</B> <INPUT TYPE=TEXT NAME=localidad maxlength="15"><BR>


<B>Provincia </B> <INPUT TYPE=TEXT NAME=provincia maxlength="15"><BR>
<B>Empresa </B> <INPUT TYPE=TEXT NAME=empresa maxlength="30"><BR>
<B>Teléfono fijo</B> <INPUT TYPE=TEXT NAME=teleff maxlength="11"><BR>
<B>Teléfono móvil</B> <INPUT TYPE=TEXT NAME=telefm maxlength="11"><BR>
<B>Fax</B> <INPUT TYPE=TEXT NAME=fax maxlength="11"><BR>
<B>Comentario</B><BR><TEXTAREA NAME=coment COLS=30 ROWS=10>
</TEXTAREA><BR>
<INPUT TYPE=HIDDEN NAME=v VALUE=1> <INPUT TYPE=RESET NAME=reset
VALUE=RESET>

<INPUT TYPE=SUBMIT NAME=añadir VALUE=AÑADIR></FONT>


</FORM>
</CENTER>
<?php }
/*Definimos la función anadir donde se añadirá la información a la base de datos.

Es necesario pasar las variables que contienen la información a añadir.*/


function anadir ($nombre,$ape1,$ape2,$dni,$civil,$domicilio,$localidad,
$provincia,$empresa,$teleff,$telefm,$fax,$coment)

include ("conectar.php");

$res=mysql_query("insert into cliente (nombre,apellido1,apellido2,dni,

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){?>

<B><CENTER>Error al insertar la información.</CENTER></B><P>


<center><a href=index.php><b>Volver</b></a></center>
<?php exit;

}?>

<CENTER><B>El nuevo cliente ha sido añadido correctamente.<P>


<center><a href=index.php><b>Volver</b></a></center>
<?php }
/*Si no existe $v se ejecutará la función funcionario que pedirá

la información necesaria y dará valor 1 a $v.


Si existe $v procederemos a añadir en la base de datos
la información que ofrece el formulario.*/
if(empty ($v))

{
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.

Posteriormente, mostramos la información de $res mediante la función mysql_fetch_array


que devuelve una variable array con los contenidos de un registro a la vez que se posiciona
sobre el siguiente. Utilizamos un bucle while para mostrar de forma secuencial cada uno de los
registros.

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>

<CENTER><TABLE width='60%' border=1>

<TR><TD align='center'><B><FONT size=2>CÓDIGO</FONT></B></TD>


<TD align='center'><B><FONT size=2>NOMBRE</FONT></B></TD>
<TD align='center'><B><FONT size=2>PRIMER APELLIDO</FONT></B></TD>
<TD align='center'><B><FONT size=2>SEGUNDO APELLIDO</FONT></B></TD>
<TD align='center'><B><FONT size=2>DNI</FONT></B></TD>
<TD align='center'><B><FONT size=2>ESTADO CIVIL</FONT></B>v/TD>
<TD align='center'><B><FONT size=2>DOMICILIO</FONT></B></TD>
<TD align='center'><B><FONT size=2>LOCALIDAD</FONT>v/B></TD>
<TD align='center'><B><FONT size=2>PROVINCIA</FONT></B></TD>

<TD align='center'><B><FONT size=2>EMPRESA</FONT></B></TD>


<TD align='center'><B><FONT size=2>TELÉFONO FIJO</FONT></B></TD>
<TD align='center'><B><FONT size=2>TELÉFONO MÓVIL</FONT></B></TD>
<TD align='center'><B><FONT size=2>FAX</FONT></B></TD>
<TD align='center'><B><FONT size=2>COMENTARIO</FONT></B></TD></TR>
<?php

//Mostramos la información obtenida en la consulta anterior.


while($file=mysql_fetch_array($res))

$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'.

Recuerde que los usuarios que borre de la base de datos son


irrecuperables.</CENTER></B>

81
<FORM ACTION=borracli.php METHOD=GET>

<CENTER ><TABLE width='60%' border=1><TR><TD align='center'><B><FONT


size='2'>MARCAR</FONT></B></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'>PRIMER APELLIDO</FONT></B></TD><TD align='center'><B><FONT
size='2'>SEGUNDO APELLIDO</FONT></B></TD></TR>

<?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");<

/*Si no existe $aux se ejecutará la función mostrar que


listará la información de clientes y creará la variable aux con valor 1.
Si existe $aux procederemos a eliminar de la
base de datos los clientes indicados.*/
if(empty ($aux))
{
mostrar();
}
else
{
borrar($borrar);
}
?>
</body>

</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

//Definimos la función formulario que pedirá el DNI del cliente a modificar.


function formulario ()
{?>
<B><CENTER>Introduzca su DNI.</CENTER></B>

<CENTER><FORM ACTION=modifcli.php METHOD=POST>

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>

<INPUT TYPE=SUBMIT NAME=añadir VALUE=ENVIAR></FONT>


</FORM></CENTER>
<?php }
/*Definimos la función formulario que muestra un formulario con
la información del cliente seleccionado anteriormente.*/
function modificar ($dni)
{
include ("conectar.php");
$res=mysql_query("select * from cliente where dni='$dni'");
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;
}
$file=mysql_fetch_array($res);
$cod=$file["cod"];
$nombre=$file["nombre"];
$ape1=$file["apellido1"];
$ape2=$file["apellido2"];
$dni=$file["dni"];
$civil=$file["civil"];
$domicilio=$file["domicilio"];
$localidad=$file["localidad"];
$provincia=$file["apellido1"];
$empresa=$file["empresa"];
$telff=$file["telff"];
$telfm=$file["telfm"];
$fax=$file["fax"];
$coment=$file["coment"];
?>

<B><CENTER>Modifique los campos que crea oportunos y pulse 'modificar' para


realizar los cambios en nuestra base de datos.</CENTER></B>
<CENTER><FORM ACTION=modifcli2.php METHOD=POST>

<B>Nombre</B> <INPUT TYPE=TEXT NAME=nombre VALUE=<? echo "'$nombre'";?


> maxlength="20"><BR>

<B>Primer apellido</B> <INPUT TYPE=TEXT NAME=ape1 VALUE=<? echo "'$ape1'";?

84
> maxlength="15"><BR>
<B>Segundo apellido</B> <INPUT TYPE=TEXT NAME=ape2 VALUE=<? echo
"'$ape2'";?> maxlength="15"><BR>

<B>DNI</B> <INPUT TYPE=TEXT NAME=dni VALUE=<? echo "'$dni'";?>


maxlength="10"><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>
<? } ?>

<B>Domicilio</B> <INPUT TYPE=TEXT NAME=domicilio VALUE=<? echo


"'$domicilio'";?> maxlength="50"><BR>
<B>Localidad</B> <INPUT TYPE=TEXT NAME=localidad VALUE=<? echo
"'$localidad'";?> maxlength="15"><BR>
<B>Provincia</B> <INPUT TYPE=TEXT NAME=provincia VALUE=<? echo
"'$provincia'";?> maxlength="15"><BR>
<B>Empresa</B> <INPUT TYPE=TEXT NAME=empresa VALUE=<? echo
"'$empresa'";?> maxlength="30"><BR>

<B>Teléfono fijo</B> <INPUT TYPE=TEXT NAME=telff VALUE=<? echo "'$telff'";?>


maxlength="11"><BR>
<B>Teléfono móvil</B> <INPUT TYPE=TEXT NAME=telfm VALUE=<? echo "'$telfm'";?
> maxlength="11"><BR>
<B>Fax</B> <INPUT TYPE=TEXT NAME=fax VALUE=<? echo "'$fax'";?>
maxlength="11"><BR>
<B>Comentario</B><BR><TEXTAREA NAME=coment COLS=30 ROWS=10>
<? echo "$coment";?>

</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',

apellido2='$ape2', dni='$dni', civil='$civil', domicilio='$domicilio',


localidad='$localidad', provincia='$provincia', empresa='$empresa',
telff='$telff', telfm='$telfm', fax='$fax', coment='$coment' where
cod='$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>
</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:

La Web debe permitir agregar visitas, visualizarlas, modificarlas y borrarlas.

CREATE TABLE `visitas` (`Codigo` int(11) NOT NULL auto_increment,

`Nombre` varchar(50) NOT NULL default '',


`Correo` varchar(100) default NULL,
`Web` varchar(100) default NULL,
`Fecha` varchar(10) NOT NULL default '',
`Asunto` varchar(100) NOT NULL default '',
`Cuerpo` longtext NOT NULL,
PRIMARY KEY (`Codigo`)
) TYPE=MyISAM;

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'

para que sus comentarios aparezcan en nuestro libro de visitas. </CENTER></B>


<CENTER><FORM ACTION=enviarlv.php METHOD=POST>
<B>Nombre/nick</B> vINPUT TYPE=TEXT NAME=nombre SIZE=10><P>
<B>Correo electrónico</B> <INPUT TYPE=TEXT NAME=correo SIZE=20><P>
<B>Página web</B> <INPUT TYPE=TEXT NAME=web VALUE=http:// SIZE=30><P>
<B>Fecha:</B> <INPUT TYPE=TEXT NAME=fecha VALUE="<?php echo
date('d/m/y');?>" SIZE=10><P>
<B>Asunto</B> <INPUT TYPE=TEXT NAME=asunto><P>

<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)
{?>

<B><CENTER>Error al insertar el registro.</CENTER></B><P>


<center><a href=index.php><b>Volver</b></a></center>
<?php exit;
}?>

<CENTER><B>El comentario ha sido añadido correctamente.

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()

{?>

<B><CENTER>Seleccione el comentario que desee


eliminar de la base de datos y pulse sobre el botón 'borrar'.
</CENTER>< /B>
<?php include ("conectar.txt");
$res=mysql_query("select * from visitas order by Codigo Desc",$c);

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>

<CENTER>< TABLE width='60%' border=1>< TR>< TD align='center'> < B>MARCAR


</B>< /TD>
<TD align='center'>< B>ASUNTO< /B>< /TD>
<TD align='center'>< B>FECHA< /B>< /TD>< /TR>
<?php while($file=mysql_fetch_array($res))
{
$codigo=$file["Codigo"];
$titulo=$file["Asunto"];
$fecha=$file["Fecha"];
?> <TR><TD align='center'><INPUT TYPE=CHECKBOX NAME=borrar[] 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=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>

<center><a href=index.php>< b>Volver< /b>< /a></center>


<?php exit;
}
}?>
<CENTER>< B>Los comentarios seleccionados han sido
borrados de la base de datos. </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"];
?>

<B><CENTER>Realice los cambios oportunos y pulse 'MODIFICAR'


para que las modificaciones se lleven a cabo.</CENTER></B>
<CENTER><FORM ACTION=modiflv2.php METHOD=POST>
<B>Nombre/nick</B> <INPUT TYPE=TEXT NAME=nombre SIZE=10
value=<?php echo "'$nombre'";?>><P>

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:

 Comunidad activa y amistosa.


 Licencia flexible.
 Compatible con PHP4 y PHP5.
 CRUD integrado para la interacción con la base de datos.
 Soporte de aplicación [scaffolding].
 Generación de código.
 Arquitectura Modelo Vista Controlador (MVC).
 Despachador de peticiones [dispatcher], con URLs y rutas personalizadas y limpias.
 Validación integrada.
 Plantillas rápidas y flexibles (sintaxis de PHP, con ayudantes[helpers]).
 Ayudantes para AJAX, Javascript, formularios HTML y más.
 Componentes de Email, Cookie, Seguridad, Sesión y Manejo de solicitudes.
 Listas de control de acceso flexibles.
 Limpieza de datos.
 Caché flexible.
 Localización.
 Funciona en cualquier subdirectorio del sitio web, con poca o ninguna configuración
de Apache.

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.

1. Ricardo hace clic en el enlace apuntando a


http://www.ejemplo.com/pasteles/comprar, y su navegador hace una petición al
servidor web.
2. El despachador comprueba la URL de la petición (/pasteles/comprar), y le pasa la
petición al controlador adecuado.
3. El controlador realiza lógica de aplicación específica. Por ejemplo, puede comprobar si
Ricardo ha iniciado sesión.
4. El controlador también utiliza modelos para acceder a los datos de la aplicación. La
mayoría de las veces los modelos representan tablas de una base de datos, aunque
también pueden representar entradas LDAP, canales RSS, o ficheros en el sistema. En
este ejemplo, el controlador utiliza un modelo para buscar la última compra de Ricardo
en la base de datos.
5. Una vez que el controlador ha hecho su magia en los datos, se los pasa a la vista. La
vista toma los datos y los deja listos para su presentación al usuario. La mayoría de las
veces las vistas en CakePHP vienen en formato HTML, pero una vista puede ser
fácilmente un PDF, un documento XML, o un objeto JSON, dependiendo de tus
necesidades.
6. Una vez que el objeto encargado de procesar vistas en CakePHP ha utilizado los datos
del controlador para construir una vista completa, el contenido se devuelve al
navegador de Ricardo.

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.

El diseño modular permite a los diseñadores y a los desarrolladores trabajar conjuntamente,


así como realizar rápidamente el prototipado. Esta separación también permite hacer cambios
en una parte de la aplicación sin que las demás se vean afectadas.

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.

Tema 2: Principios básicos de cakephp


CakePHP incluye las clases Controlador [Controller], Modelo [Model] y Vista [View], pero
también incluye otras clases y objetos que hacen que el desarrollo en MVC sea un poco más
rápido y agradable. Los Componentes [Components], Comportamientos [Behaviors], y
Ayudantes [Helpers] son clases que proporcionan extensibilidad y reusabilidad; agregan
rápidamente funcionalidad a las clases base MVC de las aplicaciones. Como de momento nos
vamos a mantener en este nivel de dificultad, ve preparando los detalles acerca de cómo usar
estas herramientas.

Extensiones de los Controladores ("Componentes")


Un componente es una clase que ayuda a la lógica de un controlador. Si tienes alguna lógica y
la quieres compartir entre varios controladores (o aplicaciones), un componente suele ser una
buena elección. A modo de ejemplo, la clase del núcleo EmailComponent hace que la creación
y el envío de mensajes de correo electrónico sean tan sencillo como coser y cantar. En lugar de
escribir lógica en el método de un controlador, puedes empaquetarla en un componente para
poder compartirla.

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:

 beforeFilter(), se ejecuta antes que cualquier otra acción del controlador.


 beforeRender(), se ejecuta después de la lógica del controlador, pero antes de que la
vista se renderice.
 afterFilter(), se ejecuta después de toda la lógica del controlador, incluido el
renderizado de la vista. Puede que no haya ninguna diferencia entre afterRender() y
afterFilter(), a menos que hayas llamado manualmente a render() en el controlador y
hayas incluido alguna lógica después de esa llamada.

Extensiones de las Vistas


Un ayudante [Helper] es una clase que ayuda a la lógica de una vista. Del mismo modo que
varios controladores utilizan un componente, los ayudantes [helpers] hacen que varias vistas
accedan y compartan lógica presentacional. Con uno de los ayudantes del núcleo, el
AjaxHelper, el manejo de las peticiones Ajax en las vistas es mucho más fácil.

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.

Así como los controladores, los modelos también incluyen callbacks:

 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.

2 Una petición típica de cakephp


Hemos cubierto los ingredientes básicos de CakePHP, así que echemos un vistazo a cómo los
objetos trabajan juntos para completar una petición básica. Continuando con nuestro ejemplo
de petición original, imaginemos que nuestro amigo Ricardo acaba de hacer clic en el enlace

99
"¡Comprar un pastel personalizado ahora!" en una página de bienvenida de una aplicación
CakePHP.

Figura 2. Petición típica de Cake.

Negro = elemento requerido, Gris = elemento opcional, Azul = callback

 Ricardo hace clic en el enlace apuntando a http://www.ejemplo.com/tortas/comprar,


y su navegador hace una petición a su servidor Web.
 El enrutador analiza la URL para extraer los parámetros para esta petición: el
controlador, la acción, y cualquier otro argumento(s) que pueda afectar a la lógica de
negocio durante esta petición.
 Usando las rutas, una petición URL es mapeada a una acción de controlador (un
método en una clase de controlador específica). En este caso, es el método comprar()
del controlador PastelesController. El callback beforeFilter() del controlador es llamado
antes de que cualquier acción lógica del controlador sea ejecutada.
 El controlador puede usar modelos para ganar acceso a los datos de la aplicación. En
este ejemplo, el controlador usa un modelo para obtener información de la base de
datos de las últimas compras de Ricardo. Cualquier callback de modelo,
comportamiento [behavior], y orígenes de datos [DataSources] aplicables pueden
activarse durante esta operación. Mientras que el uso del modelo no es requerido,
todos los controladores de CakePHP inicialmente requieren al menos un modelo, salvo
que el desarrollador indique lo contrario.
 Después que el modelo ha obtenido toda la información, ésta es devuelta al
controlador. Pueden activarse callbacks del modelo.
 El controlador puede usar componentes para refinar aún más los datos o realizar otras
operaciones (manipulación de sesiones, autenticación, o envíos de email, por
ejemplo).
 Una vez que el controlador ha usado modelos y componentes para preparar
suficientemente la información, ésta es entregada a la vista usando el método set() del
controlador. Los callbacks de controlador pueden ser aplicados antes de que la
información sea enviada. La lógica de vista es ejecutada, la cual puede incluir el uso de

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.

3 Estructura de archivos de cakephp


Tras descargar y extraer CakePHP, estos serán los ficheros y carpetas que deberías ver:

 App
 Cake
 Vendors
 .htaccess
 index.php
 README

Observarás 3 carpetas principales:

 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.

Veamos un poco más de cerca las carpetas dentro de app.

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.

Convenciones de los nombres de archivos y clases


En general, los nombres de archivo llevan el símbolo guion bajo (underscore) "_", mientras que
los nombres de las clases usan Mayúsculas de primera palabra (CamelCase). La clase
MyNiftyClass puede ser encontrada en el archivo my_nifty_class.php, por ejemplo.

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.

El nombre de las tablas de unión entre modelos, usadas en relaciones hasAndBelongToMany


(HABTM), debería estar formado por el nombre de las tablas que une puestos en orden
alfabético (cebras_manzanas en vez de manzanas_cebras).

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.

También puedes cambiar la visibilidad de los métodos de los controladores en CakePHP


anteponiendo al nombre del método guiones bajos. Si un método de un controlador comienza

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. } } ?>

Mientras que la página http://www.example.com/noticias/ultimas/ está accesible de manera


normal, si alguien intenta acceder a la página
http://www.example.com/noticias/_buscaNuevosArticulos/ obtendrá un error porque el
nombre del método está precedido por un guion bajo.

Consideraciones de URL para nombres de controladores


Como se puede ver, los controladores con un nombre simple (de una sola palabra) pueden ser
fácilmente mapeados a una url en minúsculas. Por ejemplo, ApplesController (que se define en
el archivo 'apples_controller.php') y accedido desde http://example.com/apples.

Por otro lado múltiples combinaciones de palabras pueden ser transformadas


automáticamente en un mismo nombre de controlador:

 /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.

El patrón básico es: /app/views/controller/underscored_function_name.ctp

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:

 Tabla de Base de Datos: ‘people’.


 Clase de Modelo: ‘Person’, encontrada en /app/models/person.php.
 Clase de Controlador: ‘PeopleController’, encontrada en
/app/controllers/people_controller.php.
 Plantilla de Vista, encontrada en /app/views/people/index.ctp.

Usando estas convenciones, CakePHP entiende que la petición http://example.com/people/


apunta a la llamada de funciónindex() en el controlador, PeopleController, donde el modelo
Person está disponible automáticamente (y apunta automáticamente a la tabla ‘people’ en la
base de datos), y se renderiza en el archivo. Ninguna de estas relaciones han sido configuradas
por otra razón que crear clases y archivos que usted necesita crear.

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

2 Preparándose para instalar


CakePHP es rápido y fácil de instalar. Los requisitos mínimos son un servidor web y una copia
de Cake, ¡solo eso! Aunque este manual se enfoca primariamente en la configuración sobre
Apache (porque es el usado comúnmente), Tu puedes configurar Cake para correr sobre la
mayoría de servidores web, tales como, LightHTTPD o bien Microsoft IIS. Preparar la
instalación consta de los siguientes pasos:

 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.

Para descargar la última release principal de CakePHP, dirígete a la página web


http://www.cakephp.org

y haz clic en el enlace “DownloadNow”.

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.

Si tu servidor web está configurado correctamente, deberías encontrar tu aplicación Cake


accesible en http://www.ejemplo.com.

Apache y mod_rewrite (y .htaccess )


A pesar de que CakePHP está hecho para funcionar con mod_rewrite sin tocar nada, y
normalmente así es, hemos notado que algunos usuarios tienen dificultades para lograr que
todo funcione correctamente en sus sistemas.

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).

1. Asegúrate que la reescritura .htaccess esté permitida y que AllowOverride esté


establecido a All para el DocumentRoot adecuado. Deberías ver algo similar a:
# 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>
2. Asegúrate de estar cargando el módulo mod_rewrite correctamente. Debes ver algo
como:
LoadModulerewrite_modulelibexec/apache2/mod_rewrite.
En muchos sistemas esto estará comentado (comenzando la línea con #) por defecto,
así que sólo tendrás que quitar los símbolos # del principio.

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>

En muchos servicios de hosting (GoDaddy, 1and1), tu servidor web está realmente


siendo servido desde un directorio de usuario que ya utiliza mod_rewrite. Si estás
instalando CakePHP en un directorio de usuario
(http://ejemplo.com/~nombreusuario/cakephp), o en cualquier otra estructura que ya
utilice mod_rewrite necesitarás añadir sentencias RewriteBase a los archivos .htaccess
que utiliza CakePHP (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).

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.

¡Felicidades! Ya estás listo para crear tu primera aplicación CakePHP.

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.

Configuración de Base de Datos


CakePHP espera que los detalles de configuración de la base de datos estén en
app/config/database.php. Un ejemplo de configuración puede encontrarse en el archivo
app/config/database.php.default. Esta configuración debería verse como sigue:

var $default = array('driver' => 'mysql', 'persistent' => false,


'host' => 'localhost', 'login' => 'cakephpuser', 'password' =>
'c4k3roxx!', 'database' => 'mi_proyecto', 'prefix' => '' ) ;

El arreglo de configuración $default es el utilizado a menos que se especifique algún otro en la


propiedad $usDbConfig de los modelos. Por ejemplo, si mi aplicación tiene aplicaciones
legadas adicionales a la que se va a utilizar por defecto, podría utilizarla en mis modelos
creando un nuevo arreglo de configuración $legada que sea similar a $default, y asignado var
$useDbConfig = 'legada'; en los modelos correspondientes.

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:

Nota: La configuración de Cache también puede ser encontrada en el archivo core.php.

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.

6 Comprensión de las rutas


El enrutamiento permite hacer una relación entre URLs y acciones de los controller. Fue
añadido a CakePHP para hacer más bonitos los URLs, más configurables, y más flexibles. Usar
el mod_rewrite de Apache no es un requisito para utilizar el enrutamiento, pero hará lucir
mucho mejor tu barra de direcciones.

Enrutamiento por Defecto


CakePHP viene configurado con un conjunto de rutas por defecto. Estas rutas te llevarán
bastante lejos en cualquier aplicación. Puedes acceder a una acción directamente desde el URL
colocando su nombre en la petición. También puedes pasar parámetros a las acciones de tus
controladores usando el URL.

Patrón URL de las rutas por defecto:

http://example.com/controlador/accion/param1/param2/param3

El URL /articulos/ver dirige a la acciónver() action del ArticulosController, y


/productos/listaCompleta dirige a la acciónalista_completa() de ProductosController. Si no se
especifica ninguna acción en el URL, se asume que se trata de la acción index().

La configuración inicial de enrutamiento permite pasar parámetros a tus acciones usando el


URL. Una petición para /articulos/ver/25 sería equivalente a llamar ver(25) en el
ArticulosController, por ejemplo.

Parámetros con Nombre


Algo novedoso en CakePHP 1.2 es la habilidad de usar parámetros con nombre
(namedparameters). Puedes nombrar parámetros y enviar sus valores usando el URL. Una
petición para /articulos/ver/titulo:primer+articulo/categoria:general resultaría en una llamada
a la accion view() de ArticulosController. En dicha acción, puedes encontrar los valores del
título y la categoría dentro de $this->passedArgs['titulo'] and $this->passedArgs['categoria']
respectivamente.

Algunos ejemplos que resuman las rutas por defecto pueden resultar útil.

 URL: /monos/saltar Dirige a: MonosController->saltar() ;


 URL: /productos Dirige a: ProductosController->index() ;
 URL: /tareas/ver/45 Dirige a: TareasController->ver(45) ;
 URL: /donaciones/ver/recientes/2001
Dirige a: DonacionesController->ver('recientes', '2001') ;
URL: /contenidos/ver/capitulo:modelos/seccion:asociaciones
Dirige a: ContenidosController->ver() ;
$this->passedArgs['capitulo'] = 'modelos';
$this->passedArgs['seccion'] = 'asociaciones';

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.

El modelo Receta es manejado por el RecetasController, el modelo Producto es manejado por


el ProductosController, y así sucesivamente.

Los controladores de su aplicación son sub-clases de la clase AppController de CakePHP, que a


su vez extiende la clase principal Controller. La clase AppController puede ser definida en
/app/app_controller.php y debe contener métodos que son compartidos entre todos los
controladores de su aplicación. AppController es una sub-clase de Controller que es una clase
de la biblioteca estándar de Cake.

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í... } } ?>

Para que puedas usar un controlador de manera productiva en tu propia aplicación,


repasaremos algunos de los atributos y métodos provistos por los controladores de CakePHP.

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'; } ?>

$components, $helpers y $uses


Los siguientes atributos más comúnmente utilizados del controlador indican a CakePHP qué
ayudantes (helpers), componentes (components), y modelos (models) utilizarás en conjunción
con el controlador actual. Utilizar esos atributos hace que las clases MVC estén disponibles al
controlador como variable de clase($this->ModelName, por ejemplo).

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.

Atributos Relacionados con la Página: "$layout" y "$pageTitle"


Existen unos pocos atributos en los controladores de CakePHP que te dan control sobre cómo
se colocan tus vistas (views) dentro del diseño (layout).

Al atributo $layout se le puede asignar el nombre de un diseño (layout) guardado en


/app/views/layouts. Especificas un diseño al igualar $layout al nombre del archivo con el
diseño excluyendo la extensión .ctp. Si este atributo no ha sido definido, CakePHP renderiza el
diseño por defecto, default.ctp. Si no has definido un diseño en
/app/views/layouts/default.ctp, el diseño por defecto del núcleo de CakePHP’s será
renderizado.
?php // Usando <em>$layout</em> para definir un diseño alternativo
class RecipesController extends AppController { functionquickSave()
{ $this->layout = 'ajax'; } }

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.

Si $this->pageTitle no está establecido, se generará automáticamente un título basado en el


nombre del controlador, o el nombre del fichero de la vista en el caso de una página estática.

El Atributo de Parámetros ("$params")


Los parámetros del controlador están disponibles en $this->params en tu controlador de
CakePHP. Esta variable es usada para proporcionar acceso a la información sobre la petición
actual. El uso más común de $this->params es obtener acceso a información que ha sido
entregada al controlador a través de las operaciones POST o GET.

Form
$this->params['form']

Cualquier dato POST de cualquier formulario se almacena aquí, incluyendo información


también hallada en $_FILES.

Admin
$this->params['admin']

Almacena un 1 si el diseño (layout) actual está vacío; 0 si no.

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') ;

El cual al ser renderizado, se ve parecido a:


<input name="data[User][first_name]" value="" type="text" />

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']

Almacena cualquier parámetro con nombre /clave:valor/ de la cadena de petición de la URL.


Por ejemplo, si se pidió la URL /posts/view/var1:3/var2:4, entonces $this>params['named']
debería contener el array:
[named] => Array ( [var1] => 3 [var2] => 4 )

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.

El atributo $cacheAction ayuda en el "cacheado" (caching) de vistas (views), y el atributo


$paginate es usado para establecer las opciones por defecto de paginado para el controlador.
Para más información sobre cómo utilizar esos atributos.

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.

Interactuando con Vistas


Set(string $variable, mixed $valor)

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

// Primero pasas datos desde el controlador:

$this->set('color', 'azul') ;

// Después, en la vista, puedes utilizar el dato:

?>

Has seleccionado <?php echo $color; ?>de la tarta.

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.

Flash (string $message, string $url, integer $pause)

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.

El primer parámetro debería contener el mensaje a mostrar, y el segundo parámetro es una


URL relativa a CakePHP. CakePHP mostrará el mensaje en $message durante el número de
segundos en $pause antes de reenviar al usuario a otra página.

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.

Aquí presentamos un ejemplo simple de definición de modelo en CakePHP:


<?php classIngredient extends AppModel { var $name = 'Ingredient'; } ?
>

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/.

Crea tu fichero modelo en PHP en el directorio /app/models/ o en un subdirectorio de


/app/models/. CakePHP lo encontrará en cualquier lugar en el directorio. Por convención,
debería tener el mismo nombre que la clase; para este ejemplo, ingredient.php.

CakePHP creará dinámicamente un objeto modelo por ti si no puede encontrar un archivo


correspondiente en /app/models. Esto también significa que si, accidentalmente, nombras tu
archivo de manera errónea (p.ej. Ingredient.php o ingredients.php) CakePHP utilizará
AppModel en lugar de tu archivo de modelo con nombre incorrecto. Si estás tratando de

117
utilizar un método de un modelo personalizado y estás obteniendo errores SQL, normalmente
es porque CakePHP no puede encontrar tu modelo.

La propiedad $name es necesaria para PHP4 pero opcional para PHP5.

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') ; } } ?>

Si no has añadido el modelo a través de la propiedad $uses entonces necesitarás importar el


modelo manualmente e instanciarlo dentro de la acción.
<?php classRecipeController extends AppController { var $uses =
array('Recipe') ; function index() { $this->Recipe->find('all') ;
App::import('Model', 'User') ; $user = new User() ; $user->find('all')
; } } ?>

2 Creando tablas de bases de datos


A pesar de que CakePHP puede tener orígenes de datos (datasources) que no son manejadas
por sistemas de gestión de bases de datos, la mayoría de las veces lo son. CakePHP está
diseñado para ser agnóstico y funcionará con MySQL, MSSQL, Oracle, PostgreSQL y otros.
Puedes crear tus tablas de base de datos como lo harías normalmente. Cuando creas tus clases
del Modelo, automáticamente se mapean a las tablas que has creado.

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.

Asociaciones de Tipo de Dato por Base de Datos


Todo RDMS define tipos de datos de manera ligeramente diferente. Dentro de la clase de
origen de datos (o "fuente de datos", datasource) para cada sistema de base de datos,
CakePHP "mapea" dichos tipos a algo que reconoce y crea una interfaz unificada sin importar
en qué sistema de bases de datos necesitas ejecutarlo.

El siguiente desglose describe cómo está "mapeado" cada uno:

MySQL

Un campo de tipo tinyint(1) es considerado booleano por CakePHP.

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.

Creado y modificado ("created" y "modified" )


Al definir un campo created (creado) o modified (modificado) en tu tabla de la base de datos
como campo de tipo datetime, CakePHP reconocerá esos campos y los rellenará
automaticamente cuando un registro sea creado o grabado en la base de datos.

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.

Nota: Un campo llamado updated (actualizado) exhibirá el mismo comportamiento que


modified. Estos campos necesitan ser del tipo datetime con el valor por defecto establecido a
NULL para ser reconocidos por CakePHP.

Utilizando UUIDs como Claves Primarias


Las claves primarias son normalmente definidas como campos INT. La base de datos
incrementará automáticamente el campo, comenzando en 1, para cada nuevo registro que se
añade. Alternativamente, si especificas tu clave primaria como CHAR(36), CakePHP generará
automáticamente UUIDs( Identificadores Únicos Universales) cuando son creados nuevos
registros.

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

3 Recuperando tus datos


Find($tipo, $parametros)
$tipo es 'all', 'first', 'count', 'neighbors', 'list' o 'threaded'. 'first' es el tipo de búsqueda
predeterminado.

$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') ) ) ;

Si estás utilizando find('neighbors'), la clave 'field' en $parametros define el campo a analizar, y


la clave 'value' en el array $parametros define el valor a mirar para determinar el siguiente y el
anterior. Notar que las claves 'field' y 'value' no son usadas para find('all') y este es un caso
especial para find('neighbors').
// asumiendo que tenermosid's de 1 a 10, veremos
assumingwehaveid'sfrom 110 , veremos prev establecido a 1 y next
establecido a 3 $this->Post->id = 2; $one = $this->Post-
>find('neighbors') ; // para obtener los datos vecinos utilizando un
campo diferente... $two = $this->Post->find('neighbors',
array('field'=> 'Post.title','value'=> $data['Post']['title']) ) ;

Para compatibilidad hacia atrás, find también acepta la sintasix previa:


find(string $condiciones, array $campos, string $orden, int
$recursivo)

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 ) )

No hay parámetros adicionales usador por find('first').

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)).

No hay parámetros adicionales usados con find('count').

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.

Los resultados de llamar a find('all') serán de la siguiente forma


Array ( [0] => Array ( [ModelName] => Array ( [id] => 83 [field1] =>
value1 [field2] => value2 [field3] => value3 ) [AssociatedModelName]
=> Array ( [id] => 1 [field1] => value1 [field2] => value2 [field3] =>
value3 ) ) )

Aquí no hay parámetros condicionales usados por find('all').

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'))) ; ... }

En el ejemplo siguiente $allAuthors va a contener todos los usuarios de la tabalousuers, no se


le aplica ninguna condición para filtrar la búsqueda que lleva a cabo find.

Los resultado tras llamar al método find('list') tendrán el siguiente aspecto:


Array ( //[id] => 'displayValue', => 'displayValue1', =>
'displayValue2', => 'displayValue4', => 'displayValue5', =>
'displayValue6', [3] => 'displayValue3', )

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.

Ejemplo findAllBy<x> en PHP5 Fragmento SQL Correspondiente

$this->Product->findAllByOrderStatus(‘3’); Product.order_status = 3

$this->Recipe->findAllByType(‘Cookie’); Recipe.type = ‘Cookie’

$this->User->findAllByLastName(‘Anderson’); User.last_name = ‘Anderson’

$this->Cake->findById(7); Cake.id = 7 $this->User->findByUserName(‘psychic’);


User.user_name = ‘psychic’

Los usuarios de PHP4 han de utilizar esta función de manera un poco diferente debido a cierto
caseinsensitivity en PHP4:

Ejemplo findAllBy<x> en PHP4 Fragmento SQL Correspondiente

$this->Product->findAllByOrder_status(‘3’); Product.order_status = 3

$this->Recipe->findAllByType(‘Cookie’); Recipe.type = ‘Cookie’

$this->User->findAllByLast_name(‘Anderson’); User.last_name = ‘Anderson’

$this->Cake->findById(7); Cake.id = 7

$this->User->findByUser_name(‘psychic’); User.user_name = ‘psychic’

El resultado devuelto es un array formateado tal y como sería en find() o findAll().

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 ) ) )

field(string $nombre, string $condiciones, string $orden)


Devuelve el valor de un campo singular, especificado en $name, del primer registro que
cumpla $condiciones estando ordenado por $orden.

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.

Condiciones Complejas de Búsqueda


La mayoría de las llamadas de búsqueda del modelo involucran pasar conjuntos de condiciones
de una u otra manera. La aproximación más simple a ello es utilizar la cláusula WHERE de SQL.
Si ves que necesitas más control, puedes utilizar arrays.

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.

En su forma más básica, una consulta basada en array es así:

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, ) )

Para manejar consultas con BETWEEN, puedes usar lo siguiente:


array('Articulo.id BETWEEN ? AND ?' =>array(1,10))

Nota: CakePHP entrecomillará los valores numéricos dependiendo del tipo de campo definido
en tu base de datos.

4 Guardando tus datos


CakePHP hace que el salvado de los datos del modelo sea instantáneo. Los datos listos para ser
salvados deberán ser pasados al método save() del modelo usando el formato básico siguiente:
Array ( [NombreModelo] => Array ( [nombrecampo1] => 'valor'
[nombrecampo2] => 'valor' ) )

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;

Cuando se llama a save() en un bucle, no olvides llamar a create().


create(array $datos = array())

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)

Usado para salvar un único valor de un campo. Establece el ID del modelo


($this>nombreModelo->id = $id) antes de llamar a saveField(). Cuando usas este método,
$nombreCampo debería contener sólo el nombre del campo, no el nombre del modelo y
campo.

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') ;

updateAll(array $campos, array $condiciones)


Actualiza varios registros en una única llamada. Los registros a ser actualizados están
identificados por el array $conditions, y los campos a ser actualizados, así como sus valores,
están identificados por el array $fields.

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 ) ) )

Guardando Datos de Modelos Relacionados (hasOne, hasMany,


belongsTo)
Cuando estamos trabajando con modelos asociados, es importante tener en cuenta que al
guardar los datos de un modelo hay que hacerlo con el correspondiente modelo de CakePHP.
Si estás guardando una nueva Entrada y sus Comentarios asociados, entonces deberías usar
ambos modelos, Entrada y Comentario, durante la operación de guardado.

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.

El nombrado de campos de arriba es necesario para la asociación hasMany. Si la asociación


entre los modelos es hasOne, necesitarás usar la notación NombreModelo.nombreCampo para
el modelo asociado.

Ahora, en nuestro compañias_controler.php podemos crear una acción add():


function add() { if(!empty($this->data)) { $this->Compañia-
>saveAll($this->data, array('validate'=>'first')) ; } }

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.

Guardando Datos de Modelos Relacionados (HABTM )


Grabar modelos que están asociados por hasOne, belongsTo y hasMany es bastante simple:

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.

deleteAll(mixed $condiciones, $cascada = true)


De la misma manera que del() y remove(), excepto que deleteAll() borra todos los registros
que cumplen las condiciones dadas. El array $condiciones debería ser pasado como un
fragmento SQL o array.

6 Asociaciones - enlazando modelos


Una de las características más potentes de CakePHP es la habilidad para enlazar el mapeado
relacional proporcionado por el modelo. En CakePHP, los enlaces entre modelos son
manejados mediante asociaciones.

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' ) ) ; } ?>

En el ejemplo de arriba, la primera instancia de la palabra 'Receta' es lo que se llama un 'Alias'.


Este es un identificador para la relación y puede ser cualquier cosa que escojas. Normalmente,
escogerás el mismo nombre que la clase que referencia. De todos modos, los alias han de ser
únicos dentro de un modelo dado y en ambas partes de una relación belongsTo/hasMany o
belongsTo/hasOne.

Escoger nombres no únicos para alias puede causar comportamientos inesperados.

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

Usuario hasOne Perfil perfiles.usuario_id

Doctor hasOne Mentor mentores.doctor_id

El archivo del modelo Usuario será grabado en /app/models/usuario.php. Para definir la


asociación 'Usuario hasOne Perfil', añade la propiedad $hasOne a la clase del modelo.
Recuerda tener un modelo Perfil en /app/models/perfil.php, o la asociación no funcionará.
<?php class Usuario extends AppModel { var $name = 'Usuario'; var
$hasOne = 'Perfil'; } ?>

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 ) ); } ?>

Las claves posibles para los arrays de asociaciones hasOne incluyen:

 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

Platano belongsTo Manzana platanos.manzana_id

Perfil belongsTo Usuario perfiles.usuarios_id

Mentor belongsTo Doctor mentores.doctores_id

Si un modelo (tabla) contiene una clave foránea, "perteneceA" (belongsTo) el otro modelo
(tabla).

Podemos definir la asociación belongsTo en nuestro modelo Perfil en


/app/models/perfil.phpusando la sintaxis de cadena de caracteres así:
<?php class Perfil extends AppModel { var $name = 'Perfil'; var
$belongsTo = 'Usuario'; } ?>

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' ) ); } ?>

Claves posibles para los arrays de la asociación belongsTo son:

 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

Usuario hasMany Comentario comentarios.usuario_id

Cake hasMany Virtud virtudes.cake_id

Producto hasManyOpcion opciones.producto_id

Podemos definir la asociación hasMany en nuestro modelo Usuario en


/app/models/usuario.php usando la sintaxis de cadena de caracteres así:
<?php class Usuario extends AppModel { var $name = 'Usuario'; var
$hasMany = 'Comentario'; } ?>

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 ) ); } ?>

Las claves posibles para los arrays de la asociación hasMany son:

 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 ) ) )

Algo a recordar es que necesitarás la asociación complementaria 'Comentario belongsTo


Usuario' para obtener los datos en ambas direcciones. Lo que hemos esbozado en esta sección
te permite obtener datos de Comentario desde Usuario. Añadir la asociación 'Comentario
belongsTo Usuario' en el modelo comentario te permite obtener los datos de Usuario desde el
modelo Comentario, completando la conexión y permitiendo el flujo de la información desde
ambas perspectivas del modelo.

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.

Tratemos el último tipo de relación: hasAndBelongsToMany (tieneYPerteneceAMuchos), o


HABTM. Esta asociación es usada cuando tienes dos modelos que necesitas unir,
repetidamente, muchas veces, de muchas maneras distintas.

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

Receta HABTM Etiqueta id, etiquetas_recetas.receta_id,


etiquetas_recetas.etiqueta_id

Cake HABTM id, cakes_fans.cake_id, cakes_fans.fan_id


Fan

FooHABTM Bar id, bars_foos.foo_id, bars_foos.bar_id

Los nombres de las tablas están, por convención, en orden alfabético.

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' => '' ) ); } ?>

Claves posibles para los arrays de asociaciones HABTM son:

 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.

Devuelve todos los campos por defecto.

 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.

También es posible ejecutar consultas de búsqueda personalizadas basadas en relaciones


HABTM. Considera los ejemplos siguientes:

Asumiendo la misma estructura en el ejemplo de arriba (Receta HABTM Etiqueta), digamos


que queremos obtener todas las Recetas con la etiqueta 'Postre', una manera potencial (pero
errónea) de conseguirlo sería aplicar una condición a la misma asociación:
$this->Receta->bindModel(array( 'hasAndBelongsToMany'
=>array( 'Etiqueta' =>array( 'conditions'=>array('Etiqueta.name'=>
'Postre') ) ) ) ) ; $this->Receta->find('all') ; // Datos devueltos
Array ( => 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 ( [0] => Array ( [id] =>
124 [name] => Postre ) ) ) => Array { [Receta] => Array ( [id] => 2745
[name] => Pasteles de Cangrejo [created] => 2008-05-01 10:31:01
[usuario_id] => 2349 ) [Etiqueta] => Array ( } } }

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') )) ;

Ambos devolverán los siguientes datos:


Array ( 0 => Array { [Receta] => Array ( [id] => 2745 [name] => Bombas
de Chocolate con Azúcar Glaseada [created] => 2007-05-01 10:31:01

140
[usuario_id] => 2346 ) [Etiqueta] => Array ( => Array ( [id] => 123
[name] => Desayuno ) => Array ( [id] => 124 [name] => Postre ) =>
Array ( [id] => 125 [name] => Enfermedad del corazón ) ) }

7 Datasources (fuentes de datos)


DataSources son el enlace entre los modelos y la fuente de datos que cada modelo representa.
En muchos casos, los datos son recuperados de una base de datos relacional, como MySQL,
PostgreSQL o MSSQL. CakePHP se distribuye con varias datasources específicas para varias
bases de datos (consulta los archivos de clases dbo_* class files en
cake/libs/model/datasources/dbo/), aquí se lista un resumen de los mismos para tu
comodidad:

 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

Cuando se especifica una configuración de conexión a base de datos en


app/config/database.php, CakePHP usa de forma transparente la datasource correspondiente
a la base de datos para todas las operaciones con modelos. Por eso, aunque creas que no
sabes nada de datasources, ya las has estado usando desde siempre.

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:

 layouts (diseños): ficheros de vista que contienen el código de presentación que se


encuentra envolviendo muchas interfaces en tu aplicación. La mayoría de vistas son
'renderizadas' (presentadas) dentro de un layout (diseño).
 elements (elementos): trozo de código de vista más pequeño y reutilizable. Los
elementos generalmente son renderizados dentro de vistas.
 helpers (ayudantes): estas clases encapsulan lógica de vista que es necesaria en
muchas partes en la capa vista. Además de otras cosas, los ayudantes en CakePHP
pueden ayudarte a construir formularios, construir funcionalidad AJAX, paginar los
datos del modelo o servir feeds RSS.

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.

Los ficheros de diseño deberían situarse en /app/views/layouts. El diseño por defecto de


CakePHP puede ser sustituido creando un nuevo diseño por defecto en
/app/views/layouts/default.ctp. Una vez que ha sido creado un nuevo diseño, el código de la
vista renderizado por el controlador se coloca dentro del diseño por defecto cuando la página
es renderizada.

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>

$scripts_for_layout contiene cualquier fichero externo y scripts incluidos con el ayudante


HTML incrustado. Es últil para incluir ficheros javascript y CSS de las vistas.

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).

$content_for_layout contiene la vista. Aquí es donde será colocado el código de la vista.

$title_for_layout contiene el título de la página.

Para establecer el título para el diseño, es fácil hacerlo en el controlador, estableciendo el


valor de la variable $title_for_layout.
<?php classUsuariosControllerextends AppController
{ functionverActivos() { $this->set('title_for_layout', 'Ver Usuarios
Activos') ; } } ?>

Puedes crear tantos diseños como desees: simplemente colócalos en el directorio


app/views/layouts e intercambialos dentro de tus acciones del controlador usando la variable
$layout del cotrolador, o la función setLayout().

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'); ?>

Pasar Variables a un elemento


Puedes pasarle datos a un elemento usando el segundo argumento de element():

<?php

echo$this->element('helpbox',array("helptext"=>"Oh, this text is


veryhelpful.")) ;

?>

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.

Las dos opciones son 'cache' y 'plugin'. Un ejemplo:


<?php echo $this->element('helpbox',array( "helptext"=>"Esto es pasado
al elemento como $helptext" "foobar"=>"Esto es pasado al elemento como
$foobar" "cache"=>"+2 days"//setea el 'cacheo' a +2 días.
"plugin"=>""//para renderizar un elemento desde un plugin ) ) ; ?>

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') )

Puedes aprovechar bien los elementos usandorequestAction(). La función requestAction() trae


las variables desde una acción de controlador y las retorna como un array. Esto permite que
tus elementos cumplan con el diseño MVC. Crea una acción de controlador que prepare las
variables de la vista para tus elementos, luego haz la llamada requestAction() dentro del
segundo parámetro de element() para proveerle al elemento las variables de vista desde tu
controlador.

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'); ?>

<?php foreach($postsas$post): ?>

<ol>

<li><?php echo$post['Post']['title']; ?
></li>

</ol>

<?php endforeach; ?>

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.

En tu archivo vista puedes hacer:


$this->set('activeMenuButton', 'posts') ;

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.

error(int $code, string $name, string $message)


Muestra una página de error al usuario. Usa layouts/error.ctppara renderizar la página.
$this->error(404, 'Notfound', 'This page wasnotfound, sorry') ;

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 un archivo de vista no puede ser encontrado en el tema, CakePHP tratará de localizarlo en la


carpeta /app/views/. De esta forma, puedes crear archivos de vista maestros y simplemente
sobreescribirlos según cada caso dentro de la carpeta de tu tema.

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

var$helpers=array('Form', 'Html', 'Javascript', 'Time') ;

?>

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

// El helper Time no es cargado aquí, no


estará disponible.

?>

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)

// Lógica para crear un link con un formato


específico va aqui...

?>

Existen algunos métodos incluidos en la clase de Helper en CakePHP de la cual quisieras sacar
ventaja:

output(string $string)

Usa esta función para enviar cualquier información de regreso a tu vista.

150
<?php

functionmakeEdit($title,$url)

// Usa la función de salida del helper para enviar

// datos con formato de regreso a la vista:

return$this->output("<div class=\"editOuter\"><a href=\"$url\"


class=\"edit\"> $title</a >

</div>") ;

?>

3 Incluyendo otros helpers


Es posible que necesites usar alguna funcionalidad existente en otro helper. Para hacerlo,
puedes especificar los helpers que deseas utilizar con un arreglo $helpers, con el formato que
usarías en un controlador.

<?php

/* /app/views/helpers/link.php (usando otros helpers) */

classLinkHelperextendsAppHelper

151
{

var$helpers=array('Html') ;

functionmakeEdit($title,$url)

// Usa el helper de HTML para mostrar

// información con formato:

$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:

<!-- crear un link usando el nuevo helper-->

152
<?phpecho$link->makeEdit('Change this Recipe',
'/recipes/edit/5') ?>

Recuerda incluir el FormHelper en el array de $helpers si es apropiado. Los ayudantes Html y


Session (si esta activa una sesión) siempre estarán disponibles.

5 Creando funcionalidad para todos los helpers


Todos los helpers extienden a una clase especial, AppHelper (así como los modelos extienden
AppModel y los controladores extienden AppController). Para crear funcionalidad que podría
estar disponible para todos los helpers, crea /app/app_helper.php.

<?php

class AppHelper extends Helper

functioncustomMethod()

?>

6 Helpers del core


CakePHP contiene un buen número de helpers que ayudan en la creación de la vista. Ellos
asisten en crear notación (markup) con buen formato (incluyendo formas), ayudan a dar
formato a texto, tiempo y números, y también pueden acelerar la funcionalidad de Ajax. Aquí
está un resumen de los helpers disponibles por defecto.

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.

Todo lo que se necesita para crear un scaffold (plataforma temporal) es un modelo y su


controlador. Una vez que se declare la variable $scaffold en el controlador, ya estás listo y
corriendo.

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.

Para reducir el estrés en el desarrollador, el scaffolding ha sido incluido en CakePHP. El


scaffolding analiza sus tablas en la base de datos y crea listas estándar con botones de agregar,
borrar y editar, forms estándar para editar y vistas estándar para inspeccionar un único
elemento en la base de datos.

Para agregar scaffolding a tu aplicación, en el controlador, agrega la variable $scaffold:

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

class User extends AppModel

var$name= 'User';

var$displayField= 'first_name';

?>

Creando un simple interface Admin con scaffolding


Debes tener habilitada el enruta del admin en app/config/core.php, con
Configure::write('Routing.prefixes', array('admin'));una vez habilitada, podrás usar scaffolding
para generar el interface Admin.

Una vez habilitado asigne su prefijo a una variable scaffolding.

var$scaffold= 'admin';

Ahora tendrás acceso a acciones adminscafoldeadas:

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.

Personalizando Vistas Scaffold


Si estás buscando para algo un poco diferente a tus vistas scaffolded, puedes crear templates.
Nosotros aún no recomendamos esta técnica para aplicaciones de producción, pero semejante
personalización puede ser muy útil durante el desarrollo de prototipos.

La personalización se hace creando templates de vistas:

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í.

(string$string_id, boolean $return=false)

Esta función gestiona la localización en las aplicaciones CakePHP. El parámetro


$string_ididentifica la ID de una traducción, mientras que el segundo parámetro indica si se
debe mostrar automáticamente la cadena (por defecto), o devolverla para su procesamiento
(pasar el valor true para que esto suceda).

a(mixed$uno,$dos,$tres...)

Devuelve un array con los parámetros pasados a la función.

print_r(a('foo', 'bar'));

// salida:

array(

=> 'foo',

=> 'bar'

aa(array$uno,$dos,$tres...)

Crea arrays asociativos a partir de los parámetros enviados a la función.

// 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.

debug(mixed$var, boolean $showHtml=false)

Si el nivel de depuración, variable de configuración DEBUG, es distinto de cero, se muestra


$var. Si $showHTML es true, los datos se formatean para mostrarlos adecuadamente en los
navegadores web.

e(mixed$datos)

Simplifica la llamada a la función echo().

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.

h(string $texto, string $charset)

Alias de la función htmlspecialchars().

ife($condicion,$siNoVacia,$siVacia)

158
Útil en operaciones ternarias. Si $condicion no es vacía, devuelve $siNoVacia; si no, devuelve
$siVacia.

low(string $cadena)

Alias de la función strtolower().

pr(mixed$var)

Alias de la función print_r(), añadiendo la etiqueta <pre> a la salida.

r(string $cadena_buscada, string $cadena_sustituta, string $cadena_original)

Alias de la función str_replace().

up(string $cadena)

Alias de la función strtoupper().

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

Tema 9: Tareas comunes con cakephp


1 Validacion de datos
La validación de los datos es una parte importante de cualquier aplicación, ya que asegura que
los datos en un modelo están conformes a las reglas de negocio de la aplicación. Por ejemplo,
podrías querer que los passwords tengan a lo menos un largo de ocho caracteres, o asegurar
que los username sean únicos. Definir reglas de validación hace que el manejo de los
formularios sea muchísimo más fácil.

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.

El primer paso en la validación de datos es la creación de las reglas de validación en el Modelo.

Para hacer eso, usa el arreglo Model::validate en la definición del Modelo, por ejemplo:

<?php

class User extends AppModel

var $name = 'User';

var $validate = array() ;

?>

En el ejemplo de arriba, el arreglo $validate se agrega al modelo User, pero el arreglo no


contiene reglas de validación. Asumiendo que la tabla users tiene los campos login, password,
email y born, el ejemplo de abajo muestra algunas simples reglas de validación que se aplican
a esos campos:

<?php

class User extends AppModel

161
var $name = 'User';

var $validate = array('login' => 'alphaNumeric',

'email' => 'email',

'born' => 'date'

) ;

?>

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:

<?php class User extends AppModel {

var $name = 'User';

var $validate = array(

'login' =>array(

'alphaNumeric' =>array(

162
'rule' => 'alphaNumeric',

'required' => true,

'message' => 'Sólo letras y números'

) ,

'between' =>array(

'rule' =>array('between', 5, 15) ,

'message' => 'Entre 5 y 15 caracteres'

) ,

'password' =>array(

'rule' =>array('minLength', '8') ,

'message' => 'Largo mínimo de 8 caracteres'

) ,

'email' => 'email',

'born' =>array(

'rule' => 'date',

163
'message' => 'Ingrese una fecha válida',

'allowEmpty' => true

) ;

?>

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.

La sintaxis para la definición de reglas usando esta manera es:

var $validate = array('fieldName' => 'ruleName');

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:

var $validate = array( 'fieldName1' => array(

'rule' => 'ruleName', // ó: array('ruleName', 'param1',


'param2' ...)

'required' => true,

'allowEmpty' => false,

'on' => 'create', // ó: 'update'

'message' => 'Su mensaje de error'

) ;

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(

'rule' => 'alphaNumeric'

) ;

Si la regla requiere algunos parámetros (como max, min o range), entonces ‘rule’ debería ser
un arreglo:

var $validate = array(

'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(

'rule' => 'alphaNumeric',

'required' => true

) ) ;

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) ,

'message' => 'Password debe tener a lo menos 8


caracteres'

) ;

3 Múltiples reglas por campo


La técnica descrita anteriormente nos entrega mayor flexibilidad que la asignación de reglas
simples, pero hay un paso adicional que podemos tomar para lograr un control más fino de la
validación de datos. La siguiente técnica que revisaremos nos permite asignar múltiples reglas
de validación por cada campo de un modelo.

Si quieres asignar múltiples reglas de validación a un sólo campo, básicamente así es cómo se
verá:

var $validate = array(

'nombreCampo' =>array(

'nombreRegla' =>array(

'rule' => 'nombreRegla',

// aquí van índices extra como on, required, etc.

) ,

'nombreRegla2' =>array(

168
'rule' => 'nombreRegla2',

// aquí van índices extra como on, required, etc.

) ;

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.

Esto se entiende mejor con un ejemplo práctico:

&login' =>array(

'alphanumeric' =>array(

'rule' => 'alphaNumeric',

'message' => 'Se permiten sólo letras y números',

'last' => true

) ,

'minlength' =>array(

169
'rule' =>array('minLength', '8'),

'message' => 'Largo mínimo de 8 caracteres'

),

) ;

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:

echo $form->input('login', array('label' => __('Login', true),

'error' =>array(

'alphanumeric' => __('Se permiten sólo letras y


números', true) ,

'minlength' => __('Largo mínimo de 8 caracteres',


true)

170
) ) ;

El campo ahora está totalmente internacionalizado, y puedes eliminar los mensajes del
modelo.

4 Reglas de validación incorporadas


La clase Validation de CakePHP contiene muchas reglas de validación incorporadas que pueden
hacer mucho más fácil la validación de datos. Esta clase contiene muchas técnicas de
validación frecuentemente usadas que no necesitarás escribir por tu cuenta. Abajo
encontrarás una lista completa de todas las reglas, junto ejemplos de uso.

alphaNumeric
Los datos para el campo deben contener sólo letras y números.

var $validate = array(

'login' =>array(

'rule' => 'alphaNumeric',

'message' => 'Los nombres de usuario deben contener


sólo letras y números.'

) ;

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(

'rule' =>array('between', 5, 15) ,

'message' => 'Las contraseñas deben tener un largo


entre 5 y 15 caracteres.'

) ;

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.

var $validate = array(

'id' =>array(

'rule' => 'blank',

'on' => 'create'

) ;

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".

var $validate = array(

'myCheckbox' =>array(

'rule' =>array('boolean') ,

'message' => 'Valor incorrecto en myCheckbox'

) ;

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’.

El ‘type’ puede ser ‘fast’, ‘all’ o cualquiera de los siguientes:

 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.

var $validate = array(

'ccnumber' =>array(

'rule' =>array('cc', array('visa', 'maestro'),


false, null) ,

'message' => 'El número de tarjeta de crédito que ha


suministrado no es válido.'

) ;

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:

var $validate = array(

'age' =>array(

'rule' =>array('comparison', '>=', 18) ,

'message' => 'Debe tener al menos 18 años para


calificar.'

174
) ) ;

var $validate = array(

'age' =>array(

'rule' =>array('comparison', 'greaterorequal', 18) ,

'message' => 'Debe tener al menos 18 años para


calificar.'

) ;

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:

var $validate = array(

'age' =>array(

'rule' =>array('comparison', '>=', 18) ,

'message' => 'Debe tener al menos 18 años para


calificar.'

) ) ;

var $validate = array(

'age' =>array(

175
'rule' =>array('comparison', 'greaterorequal', 18) ,

'message' => 'Debe tener al menos 18 años para


calificar.'

) ;

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).

Si no especifica ningún índice, se usará el índice por defecto ‘ymd’.

var $validate = array(

'born' =>array(

'rule' => 'date',

176
'message' => 'Ingrese una fecha válida usando el
formato AA-MM-DD.',

'allowEmpty' => true

) ;

Mientras que muchos almacenes de datos (motores de bases de datos)


requieren cierto formato de datos, podrías considerar aceptar una amplia
variedad de formatos de fechas y luego convertirlos, en vez de forzar a los
usuarios a ingresar cierto formato. Entre más trabajo puedas hacer por tus
usuarios, mejor.

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.

var $validate = array(

'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.

var $validate = array('email' => array('rule' => 'email')) ;

var $validate = array(

'email' =>array(

'rule' =>array('email', true) ,

'message' => 'Por favor indique una dirección de


correo electrónico válida.'

) ;

equalTo
Esta regla asegura que el valor sea equivalente a, y del mismo tipo que el valor indicado.

var $validate = array(

'food' =>array(

'rule' =>array('equalTo', 'cake'),

'message' => 'El valor debe ser el string cake'

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.

var $validate = array(

'image' =>array(

'rule' =>array('extension', array('gif', 'jpeg',


'png', 'jpg') ,

'message' => 'Por favor indique una imágen válida.'

) ;

Ip
Esta regla asegura que haya sido ingresada una dirección IPv4 válida.

var $validate = array(

'clientip' =>array(

'rule' => 'ip',

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.

var $validate = array(

'login' =>array(

'rule' => 'isUnique',

'message' => 'Este nombre de usuario ya ha sido


asignado.'

) ;

minLength
Esta regla asegura que el dato cumple con un requisito de largo mínimo.

var $validate = array(

'login' =>array(

'rule' =>array('minLength', '8'),

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.

var $validate = array(

'login' =>array(

'rule' =>array('maxLength', '15'),

'message' => 'Los nombres de usuario no pueden tener


un largo mayor a 15 caracteres.'

) ;

Money
Esta regla asegura que el valor sea una cantidad en formato monetario válido.

El segundo parámetro define dónde se ubica el símbolo: left/right (izquierda/derecha).

var $validate = array(

181
'salary' =>array(

'rule' =>array('money', 'left') ,

'message' => 'Por favor ingrere una cantidad


monetaria válida.'

) ;

Multiple
Empleado para validar campos input selectmultiple. Soporta los paramentros "in", "max" y
"min".

var $validate = array(

'multiple' =>array(

'rule' =>array('multiple', array('in' =>


array('foo', 'bar'), 'min' => 1, 'max' => 3)) ,

'message' => 'Por favor seleccione una, dos o tres


opciones'

) ;

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.

var $validate = array('function' => array(

'allowedChoice' =>array(

'rule' =>array('inList', array('Foo', 'Bar')) ,

'message' => 'Ingreso Foo o ingrese Bar.'

) ;

Numeric
Verifica si el dato ingresado es un número válido.

var $validate = array(

'cars' =>array(

'rule' => 'numeric',

'message' => 'Por favor indique la cantidad de


vehículos.'

183
) ;

notEmpty
Regla básica para asegurar que un campo no este vacío.

var $validate = array(

'title' =>array(

'rule' => 'notEmpty',

'message' => 'Este campo no puede quedar vacío.'

) ;

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

var $validate = array(

'number' =>array(

'rule' =>array('range', 0, 10) ,

'message' => 'Por favor ingrese un número entre 0 y


10'

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.

var $validate = array(

'website' =>array('rule' => 'url')

) ;

5 Reglas de validacion personalizadas


Si hasta el momento no has encontrado lo que buscabas, siempre podrás crear tus propias
reglas de validación personalizadas. Hay dos maneras de hacer esto: definiendo expresiones
regulares personalizadas, o creando métodos de validación personalizados.

Validación Personalizada Mediante Expresiones Regulares

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.

var $validate = array(

'login' =>array(

'rule' =>array('custom', '/^[a-z0-9]{3,}$/i'),

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.

Validación Mediante Métodos Personalizados


Algunas veces revisar los datos usando expresiones regulares no es suficiente. Por ejemplo, si
quieres asegurar que un código promocional sólo pueda ser usado 25 veces, necesitas agregar
una función de validación personalizada, como se muestra más abajo:

<?php

class User extends AppModel

var $name = 'User';

var $validate = array('promotion_code' => array(

'rule' =>array('limitDuplicates', 25) ,

'message' => 'Este código ha sido usado


demasiadas veces.'

) ;

186
functionlimitDuplicates($data, $limit)

$existing_promo_count = $this->find( 'count',


array('conditions' => $data, 'recursive' => -1)) ;

return $existing_promo_count< $limit;

?>

Si quieres pasar parámetros a tu función de validación personalizada, agrega elementos extra


al arreglo ‘rule’ y trátalos como parámetros extra (después del parámetro principal $data) en
tu función personalizada.

Tu función de validación personalizada puede estar en el modelo (como en el ejemplo de


arriba), o en un behavior implementado por el modelo. Esto incluye los modelos mapeados.

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.

Validando datos desde el Controlador


Mientras que normalmente sólo usarás el método save del modelo, habrá veces que te
gustaría validar los datos sin guardarlos. Por ejemplo, podrías querer mostrar algo de
información adicional al usuario antes de guardar los datos a la base de datos. Validar datos
requiere de un proceso ligeramente distinto al de sólo guardar los datos.

Primero, debes setear los datos al 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())

{ // paso la lógica de validación

} else {

// no paso la lógica de validadición

El método validates invoca el método invalidFields que le asignará un valor a la propiedad


validationErrors del modelo. El método invalidFields también retorna los datos como su
resultado.

$errors = $this->ModelName->invalidFields(); // contiene el


arregovalidationErrors

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.

Tema 10: Paginación


1 Preparación del controlador
En el controlador comenzamos definiendo los valores de paginación por defecto en la variable
$paginate. Es importante señalar que la clave 'order' debe estar definida en la estructura de
array dada.

class RecipesController extends AppController

188
{

var$paginate=array('limit'=>25,

'order'=>array(

'Post.title'=> 'asc'

) ;

También puedes incluir otras opciones para find(), como fields

class RecipesController extends AppController

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:

class RecipesController extends AppController

var$paginate=array('Recipe'=>array(...) ,

'Author'=>array(...)

) ;

Ejemplo de sintaxis usando Containable Behavior:

class RecipesController extends AppController

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
%')) ;

O también puedes ajustar la clave conditions en la variable paginate.

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.

Como ya se ha dicho, PaginatorHelper ofrece capacidades para ordenación que pueden


integrarse fácilmente en las cabeceras de las columnas de tus tablas:

// app/views/recipes/list_recipes.ctp

<table>

<tr>

<th><?php echo$paginator->sort('ID', 'id'); ?></th>

<th><?php echo$paginator->sort('Title', 'title'); ?></th>

</tr>

<?phpforeach($dataas$recipe): ?>

<tr>

<td><?php echo$recipe['Recipe']['id']; ?></td>

<td><?php echo$recipe['Recipe']['title']; ?></td>

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.

También es posible ordenar una columna en base a asociaciones:

<table>

<tr>

<th><?php echo$paginator->sort('Title', 'title'); ?></th>

<th><?php echo$paginator->sort('Author', 'Author.name'); ?></th>

</tr>

<?phpforeach($dataas$recipe): ?>

<tr>

<td><?php echo$recipe['Recipe']['title']; ?></td>

<td><?php echo$recipe['Author']['name']; ?></td>

</tr>

193
<?phpendforeach; ?>

</table>

El ingrediente final de la paginación en las vistas es añadir la navegación de páginas, que


también viene proporcionada por PaginationHelper.

<!-- Muestra los números de página -->

<?phpecho$paginator->numbers(); ?>

<!-- Muestra los enlaces para Anterior y Siguiente -->

<?php

echo$paginator->prev('« Previous
',null,null,array('class'=>'disabled')) ;

echo$paginator->next(' Next
»',null,null,array('class'=>'disabled')) ;

?>

<!-- Muestra X de Y, donde X es la página actual e Y el total


del páginas -->

<?phpecho$paginator->counter();?>

El texto generado por el método counter() puede personalizarse usando marcadores


especiales:

194
<?php

echo$paginator->counter(array(

'format'=> 'Page %page% of %pages%, showing %current


% records out of

%count% total, starting on record %start%, ending on %end%'));

?>

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)) ;

También puedes especificar qué parámetros pasar manualmente:

$paginator->options(array('url'=>array("0","1"))) ;

Tema 11: Formularios


1 Creando formularios
El primer método que necesitarás para poder aprovechar el FormHelper es create(). Este
método se encarga de escribir la etiqueta de apertura del formulario.

create(string $modelo = null, array $opciones = array())

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.

<?php echo $form->create('Recipe'); ?>

//Output:

<form id="RecipeAddForm" method="post" action="/recipes/add">

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.

<?php echo $form->create(); ?>

<!-- Form elements gohere -->

<?php echo $form->end(); ?>

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.

<?php echo $form->end('Finish'); ?>

196
Output:

<div class="submit">

<input type="submit" value="Finish" />

</div>

</form>

3 Form – métodos de elementos específicos


checkbox(string $fieldName, array $options)
Crea un elemento checkbox.

<?php echo $this->Form->checkbox('done'); ?>

Salida:

<input type="hidden" name="data[User][done]" value="0"


id="UserDone_" />

<input type="checkbox" name="data[User][done]" value="1"


id="UserDone" />

button(string $title, array $options = array())


Crea un botón HTML. Configurando$options['type']generará uno de los tres tipos de botones:

 submit: botón por defecto$this->Form->submit.


 reset: crear el botón reset.
 button: crea un botón estándar.

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>

year(string $fieldName, int $minYear, int $maxYear, mixed $selected,


array $attributes)
Genera un rango de valores seleccionables con años desde$minYeara$maxYear.

<?php echo $this->Form->year('purchased',2000,date('Y')) ; ?>

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.

<?php echo $this->Form->month('mob') ; ?>

Salida:

<select name="data[User][mob][month]" id="UserMobMonth">

<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>

dateTime($fieldName, $dateFormat = 'DMY', $timeFormat = '12',


$selected = null, $attributes = array())
Crea un elemento Select para fecha y hora. Valores válidos para $dateformat: ‘DMY’, ‘MDY’,
‘YMD’ o ‘NONE’. Valores válidos para $timeFormatson ‘12’, ‘24’y null.

day(string $fieldName, mixed $selected, array $attributes, boolean


$showEmpty)
Crea un elemento Select con (numerico) los días de los meses.

Puedes crear una opción vacía para crear la siguiente estructura:

<?php echo $this->Form->day('created') ; ?>

Salida:

<select name="data[User][created][day]" id="UserCreatedDay">

<optionvalue=""></option>

<optionvalue="01">1</option>

<optionvalue="02">2</option>

<optionvalue="03">3</option> ...

<optionvalue="31">31</option>

201
</select>

hour(string $fieldName, boolean $format24Hours, mixed $selected,


array $attributes, boolean $showEmpty)
Crea un elemento Select para la hora del día.

minute(string $fieldName, mixed $selected, array $attributes,


boolean $showEmpty)
Crea un elemento Select para minutos de una hora.

meridian(string $fieldName, mixed $selected, array $attributes,


boolean $showEmpty)
Crea un elemento Selectcon ‘am’ y ‘pm’.

hidden(string $fieldName, array $options)


Crea un elemento Form input oculto. Ejemplo:

<?php

echo $this->Form->hidden('id') ;

?>

Salida:

<input name="data[User][id]" value="10" id="UserId"


type="hidden">

isFieldError(string $fieldName)
Devuelve verdadero si $fieldNametiene una validación de error.

<?php

202
if ($this->Form->isFieldError('gender'))

echo $this->Form->error('gender') ;

?>

password(string $fieldName, array $options)

Crea un campo de tipo password.

<?php echo $this->Form->password('password') ; ?>

Salida:

<input name="data[User][password]" value="" id="UserPassword"


type="password">

radio(string $fieldName, array $options, array $attributes)


Crea un elemento de entrada Radio button. Use $attributes['value']para configurar los valores
que deban estar seleccionado por defecto.

Use $attributes['separator']para especificar HTML entre radio buttons (ej:<br />).

Estos elementos pueden encontrarse dentro de etiquetas y fieldsetpor defecto.Configure


$attributes['legend']a false para eliminarlos.

<?php

203
$options=array('M'=>'Male','F'=>'Female') ;

$attributes=array('legend'=>false) ;

echo $this->Form->radio('gender',$options,$attributes) ;

?>

Salida:

<input name="data[User][gender]" id="UserGender_" value=""


type="hidden">

<input name="data[User][gender]" id="UserGenderM" value="M"


type="radio">

<label for="UserGenderM">Male</label>

<input name="data[User][gender]" id="UserGenderF" value="F"


type="radio">

<label for="UserGenderF">Female</label>

select(string $fieldName, array $options, mixed $selected, array


$attributes)
Crea un elemento Select, para incluir itemsen$options, aquellos que tengan especificado
$selectedmuestran los seleccionados por defecto. Si deseas mostrar tus propias opciones por
defecto,añade el valor 'empty' en la variable$attributes, o configúralo a falso para deshabilitar
la opción ‘empty’.

<?php

204
$options = array('M' => 'Male', 'F' => 'Female') ;

echo $this->Form->select('gender', $options)

?>

Salida:

<select name="data[User][gender]" id="UserGender">

<optionvalue=""></option>

<optionvalue="M">Male</option>

<optionvalue="F">Female</option>

</select>

submit(string $caption, array $options)


Crea un boton Submit con el título$caption. Si el valor$captiones una URL a una imagen,el
Submitrenderizará una imagen.

<?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.

<?php echo $this->Form->submit('ok.png') ; ?>

Salida:

<div class="submit"><input type="image" src="/img/ok.png"></div>

text(string $fieldName, array $options)


Crea un campo de texto.

<?php echo $this->Form->text('first_name') ; ?>

Salida:

<input name="data[User][first_name]" value="" id="UserFirstName"


type="text">

textarea(string $fieldName, array $options)


Crea un campo TextArea.

<?php

echo $this->Form->textarea('notes') ;

206
?>

Salida:

<textarea name="data[User][notes]" id="UserNotes"></textarea>

Tema 12: Html


1 Introducción

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;

Haciendo esto no necesitarás agregar llamadas a echo en el código de tus vistas.

Muchos métodos HtmlHelper incluyen parámetros $htmlAttributes, esto te permite hilvanar


cualquier atributo extra en tus tags. Aquí hay algunos ejemplos de cómo se usan los
parámetros $htmlAttributes:

Atributos Deseados:

<tagclass="algunaClase"/>

Arreglo de Parámetros: array('class'=>'algunaClase') Atributos Deseados:<tag


name="foo"value="bar"/>

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.

2 Inserción de elementos HTML


Lo más importante de usar HtmlHelper es la correcta creación de marcas perfectamente
estructuradas; así como mejoras en la caché ahorrando muchos ciclos de CPU en las vistas. En
ésta sección veremos algunos métodos de HtmlHelper y cómo usarlos.

charset(string $charset=null)
Usada para crear metadatos que especificarán la codificación de los caracteres del documento.

El valor por defecto es UTF-8.

<?php echo$html->charset();?>

Generará como salida:

<meta http-equiv="Content-Type"content="text/html; charset=utf-


8"/>

O sinó también:

<?php echo$html->charset('ISO-8859-1'); ?>

Salida:

<meta http-equiv="Content-Type"content="text/html; charset=ISO-


8859-1"/>

css(mixed$path, string $rel=null,array$htmlAttributes=array(),


boolean $inline=true)

208
meta(string $type, string $url=null,array$attributes=array(), boolean $inline=true)

docType(string $type= 'xhtml-strict')

style(array$data, boolean $oneline=true)

image(string $path,array$htmlAttributes=array())

link(string $title,mixed$url=null,array$options=array(), string$confirmMessage=false)

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)

url(mixed$url=NULL, boolean $full=false)

209

También podría gustarte