You are on page 1of 526

PHP y MySQL

Tecnologías para el desarrollo de


aplicaciones web

III
IV
ÁNGEL COBO
PATRICIA GÓMEZ
DANIEL PÉREZ
ROCÍO ROCHA

PHP y MySQL
Tecnologías para el desarrollo de
aplicaciones web

V
© Ángel Cobo, Patricia Gómez, Daniel Pérez y Rocío Rocha, 2005
«No está permitida la reproducción total o parcial de este libro, ni su
tratamiento informático, ni la transmisión de ninguna forma o por
cualquier medio, ya sea electrónico, mecánico por fotocopia, por registro
u otros métodos, sin el permiso previo y por escrito de los titulares del
Copyright.»

Ediciones Díaz de Santos


Internet: http//www.diazdesantos.es/ediciones
E-mail: ediciones@diazdesantos.es

ISBN: 84-7978-706-6
Depósito Legal: M. 27.919-2005

Fotocomposición: P55 Servicios Culturales


Diseño de cubierta: P55 Servicios Culturales
Impresión: Fernández Ciudad
Encuadernación: Rústica-Hilo

Printed in Spain - Impreso en España

VI
A Valeria

VII
VIII
Índice

Agradecimientos ............................................................................................. VII

Prefacio ............................................................................................. XVII

1. INTERNET Y LA PROGRAMACIÓN DE ORDENADORES ............. 1


1.1. INTRODUCCIÓN ............................................................................ 1
1.2. INTERNET ....................................................................................... 3
1.2.1. El servicio web ..................................................................... 4
1.2.2. Relación cliente/servidor ...................................................... 5
1.2.3. Proceso de creación y publicación de páginas web ............. 7
1.2.4. Dinamismo e interactividad en las páginas web .................. 8
1.3. PROGRAMACIÓN DE ORDENADORES ..................................... 9
1.3.1. Tipos de lenguajes de programación .................................... 11
1.4. PROGRAMACIÓN EN INTERNET ............................................... 15
1.4.1. Programación del lado del cliente vs programación del
lado del servidor ................................................................... 16
1.4.2. Tecnologías de programación del lado del cliente ................ 18
1.4.3. Tecnologías de programación del lado del servidor ............. 20

2. OPEN SOURCE Y SOFTWARE LIBRE .................................................. 25


2.1. INTRODUCCIÓN ............................................................................ 25
2.1.1 ¿Qué es open source? .......................................................... 27

IX
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

2.2. BREVE RESEÑA CRONOLÓGICA ............................................... 28


2.2.1. Primera etapa, antecedentes ................................................. 28
2.2.2. Segunda etapa, desarrollo .................................................... 28
2.2.3. Tercera etapa, expansión ..................................................... 29
2.3. LA CORRIENTE OPEN SOURCE Y SOFTWARE LIBRE,
FILOSOFÍA Y CARACTERÍSTICAS ............................................. 31
2.4. LICENCIAS ...................................................................................... 35
2.4.1. Licencias propietarias .......................................................... 36
2.4.2. Licencias libres .................................................................... 37
2.4.3. Licencias semilibres ............................................................. 38
2.5. SITUACIÓN ACTUA DEL SOFTWARE OPEN SOURCE ............ 40
2.5.1. Software open source, aplicaciones para todo .................... 40
2.5.2. Comunidades open source ................................................... 47
2.5.3. Usuarios de software open source ....................................... 48
2.6. VENTAJAS, INCONVENIENTES Y PERSPECTIVAS DE
FUTURO ........................................................................................... 51
2.6.1. Ventajas ................................................................................ 51
2.6.2. Inconvenientes ...................................................................... 52
2.6.3 Perspectivas de futuro .......................................................... 52

3. CREACIÓN DE PÁGINAS WEB MEDIANTE EL


LENGUAJE HTML ................................................................................. 55
3.1. INTRODUCCIÓN ............................................................................ 55
3.1.1. Definición de HTML ........................................................... 57
3.2. HISTORIA DE HTML ..................................................................... 58
3.3. SOFTWARE NECESARIO PARA TRABAJAR CON HTML ....... 60
3.3.1. Navegadores......................................................................... 60
3.3.2. Editores ................................................................................ 60
3.4. ESTRUCTURA DE UNA PÁGINA WEB ....................................... 62
3.4.1. Complementos a la estructura básica: metatags .................. 62
3.5. CARACTERÍSTICAS GENERALES DEL LENGUAJE
Y SINTAXIS DE SUS COMANDOS .............................................. 66
3.5.1. Caracteres especiales ........................................................... 67
3.6. COMANDOS BÁSICOS .................................................................. 68
3.6.1. Comandos de cabeceras para definición de títulos
y secciones ........................................................................... 68
3.6.2. Comandos de cambio de estilo de texto ............................... 68
3.6.3. Bloques de texto y párrafos ................................................. 69
3.6.4. Comandos para la generación de listas ................................ 71

X
ÍNDICE

3.6.5. Creación de Tablas ............................................................... 76


3.6.6. Inserción de imágenes .......................................................... 79
3.6.7. Tratamiento del color ........................................................... 81
3.6.8. Enlaces o hipervínculos ....................................................... 82
3.7. MARCOS O FRAMES ...................................................................... 85
3.7.1. Construcción de páginas con marcos ................................... 85
3.7.2. Enlaces en páginas con marcos ............................................ 87
3.8. FORMULARIOS .............................................................................. 90

4. INTRODUCCIÓN A PHP .......................................................................... 99


4.1. EL LENGUAJE PHP ........................................................................ 99
4.2. ORÍGENES Y EVOLUCIÓN DEL LENGUAJE ............................. 100
4.3. PROGRAMACIÓN EN PHP: PRIMEROS EJEMPLOS ................ 102
4.4. FORMAS DE INCRUSTAR EL CÓDIGO PHP
EN LOS DOCUMENTOS HTML ................................................... 108
4.5. ESCRITURA DEL CÓDIGO FUENTE PHP .................................. 111
4.5.1. Aspectos sobre la sintaxis del lenguaje ................................ 111
4.5.2. Inserción de comentarios en el código ................................. 112
4.6. ELEMENTOS BÁSICOS DEL LENGUAJE ................................... 113
4.6.1. Tipos de datos ...................................................................... 113
4.6.2. Variables .............................................................................. 114
4.6.3. Constantes ............................................................................ 119
4.6.4. Cadenas de caracteres y variables ....................................... 120
4.6.5. Operadores ........................................................................... 124

5. PHP Y LOS FORMULARIOS DE HTML ............................................... 137


5.1. FORMULARIOS DE HTML ........................................................... 137
5.2. ENVÍO DE DATOS A PROGRAMAS PHP .................................... 139
5.3. MÉTODOS DE ACCESO A LAS VARIABLES
DEL FORMULARIO........................................................................ 141
5.4. MÉTODOS DE TRANSFERENCIA DE DATOS
EN FORMULARIOS........................................................................ 143
5.4.1. Método GET ........................................................................ 144
5.4.2. Método POST ...................................................................... 145
5.4.3. Diferencias entre ambos métodos ........................................ 146
5.5. TRANSFERENCIA DE DATOS AL SCRIPT DESDE
EL URL ............................................................................................. 147
5.6. TRATAMIENTO DE FORMULARIOS CON LISTAS
DE SELECCIÓN MÚLTIPLE .......................................................... 153

XI
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

6. SENTENCIAS DE CONTROL ................................................................. 157


6.1. INTRODUCCIÓN ............................................................................ 157
6.2. ESTRUCTURAS CONDICIONALES ............................................ 158
6.2.1. Sentencia IF ......................................................................... 158
6.2.2. La cláusula ELSE ................................................................ 162
6.2.3. Sentencia If ... ELSEIF ... ELSE ......................................... 165
6.2.4. Sintaxis alternativa de las sentencias IF .............................. 167
6.2.5. Estructuras condicionales SWITCH ... CASE .................... 169
6.3. ESTRUCTURAS ITERATIVAS ...................................................... 175
6.3.1. Sentencia WHILE ................................................................ 175
6.3.2. Sentencia DO ... WHILE ..................................................... 176
6.3.3. Sentencia FOR ..................................................................... 179
6.3.4. Sentencia FOREACH .......................................................... 187
6.3.5. Sentencias BREAK y CONTINUE ..................................... 188

7. DEFINICIÓN DE FUNCIONES ............................................................... 193


7.1. ¿CÓMO SE DEFINEN FUNCIONES EN PHP? ............................. 193
7.2. LLAMADA A LAS FUNCIONES ................................................... 196
7.3. ARGUMENTOS DE UNA FUNCIÓN ............................................ 199
7.3.1. Argumentos opcionales ........................................................ 199
7.3.2. Argumentos con valores por defecto .................................... 200
7.3.3. Listas de argumentos de longitud variable ........................... 201
7.3.4. Paso de argumentos por valor o por referencia ................... 203
7.4. ÁMBITO DE LAS VARIABLES ..................................................... 206
7.4.1. Variables locales .................................................................. 206
7.4.2. Variables globales ................................................................ 207
7.4.3. Variables estáticas ................................................................ 208
7.5. CLÁUSULAS INCLUDE Y REQUIRE ........................................... 209
7.6. FUNCIONES VARIABLES ............................................................. 211

8. ARRAYS ............................................................................................. 215


8.1. CONCEPTOS FUNDAMENTALES ............................................... 215
8.1.1. Construcción de arrays ........................................................ 216
8.1.2. Arrays multidimensionales ................................................... 218
8.2. RECORRIDO DE TODOS LOS ELEMENTOS DE UN
ARRAY ............................................................................................. 219
8.3. FUNCIONES DE MANIPULACIÓN DE ARRAYS ....................... 225
8.3.1. Transformación de los índices ............................................. 225
8.3.2. Subdivisión .......................................................................... 226

XII
ÍNDICE

8.3.3. Contabilización de elementos ............................................... 227


8.3.4. Búsqueda de datos ............................................................... 228
8.3.5. Generación de arrays ........................................................... 232
8.3.6. Prolongación o truncamiento de un array ............................ 237
8.3.7. Combinación de arrays ........................................................ 238
8.3.8. Aplicación de funciones ....................................................... 240
8.3.9. Ordenación de los elementos de un array ............................. 244

9. FUNCIONES PREDEFINIDAS ................................................................ 249


9.1. INTRODUCCIÓN ............................................................................ 249
9.2. FUNCIONES DE MANIPULACIÓN DE CADENAS
DE CARACTERES .......................................................................... 250
9.2.1. Reconocimiento de caracteres .............................................. 250
9.2.2. Conversiones entre cadenas y arrays ................................... 250
9.2.3. Prolongación de una cadena................................................. 253
9.2.4. Modificación de una cadena ................................................ 254
9.2.5. Comparación de cadenas ..................................................... 256
9.2.6. Búsqueda de datos ............................................................... 256
9.2.7. Subdivisión de cadenas ........................................................ 258
9.2.8. Longitud de una cadena ....................................................... 259
9.3. FUNCIONES DE FECHA Y HORA ................................................ 259
9.4. FUNCIONES MATEMÁTICAS ...................................................... 267

10. PROGRAMACIÓN ORIENTADA A OBJETOS ................................... 269


10.1. INTRODUCCIÓN ............................................................................ 269
10.2. DEFINICIÓN DE UNA CLASE ...................................................... 272
10.2.1. Constructores ....................................................................... 275
10.3. CONSTRUCCIÓN DE OBJETOS ................................................... 277
10.3.1. Acceso a las variables y métodos del objeto ........................ 278
10.4. HERENCIA ...................................................................................... 281
10.4.1. Definición de subclases ........................................................ 283

11. COOKIES ............................................................................................. 285


11.1. ¿QUÉ SON LAS COOKIES? ........................................................... 285
11.2. GENERACIÓN DE COOKIES ........................................................ 286
11.3. RECUPERACIÓN DE LOS VALORES DE LAS COOKIES ........ 288
11.4. COOKIES DE SESIÓN Y COOKIES PERMANENTES ............... 291
11.5. VISIBILIDAD DE LAS COOKIES EN EL SITIO WEB ................ 294

XIII
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

12. MANEJO DE FICHEROS ........................................................................ 295


12.1. MECANISMOS DE ALMACENAMIENTO DE DATOS .............. 295
12.2. OPERACIONES DE MANIPULACIÓN DE FICHEROS .............. 296
12.2.1. Apertura y cierre de ficheros ............................................... 296
12.2.2. Operaciones de lectura de datos ........................................... 298
12.2.3. Lectura con formato ............................................................. 300
12.2.4. Operaciones de escritura de datos ........................................ 303
12.2.5. Otras funciones de manipulación de ficheros ...................... 306
12.3. ENVÍO DE FICHEROS A TRAVÉS DE FORMULARIOS HTML ... 307

13. BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL ............ 309


13.1. INTRODUCCIÓN ............................................................................ 309
13.2. DISEÑO DE BASES DE DATOS .................................................... 310
13.2.1. Modelo relacional ................................................................ 310
13.2.2. Diagramas entidad/relación ................................................ 311
13.3. UN EJEMPLO ILUSTRATIVO: CINEM@S .................................. 311
13.4. EL LENGUAJE SQL ........................................................................ 316
13.4.1. Introducción ......................................................................... 316
13.4.2. Sentencias de definición de datos ......................................... 317
13.4.3. La sentencia INSERT .......................................................... 324
13.4.4. La sentencia DELETE ......................................................... 328
13.4.5. La sentencia UPDATE ......................................................... 329
13.4.6. La sentencia SELECT ......................................................... 330

14. EL SISTEMA GESTOR DE BASES DE DATOS MYSQL .................. 339


14.1. ¿QUÉ ES MYSQL? .......................................................................... 339
14.2. UTILIZACIÓN DE MYSQL ............................................................ 340
14.2.1. Arranque del servidor MySQL ............................................ 340
14.2.2. Inicio del monitor de MySQL .............................................. 342
14.3. EJECUCIÓN DE SENTENCIAS SQL ............................................ 344
14.4. GESTIÓN DE USUARIOS .............................................................. 346
14.4.1. La tabla USER ..................................................................... 346
14.4.2. Eliminación de usuarios ....................................................... 349
14.4.3. Establecimiento de contraseñas para los usuarios ............... 350
14.4.4. Creación de nuevos usuarios................................................ 352
14.5. BASES DE DATOS Y TABLAS EN MYSQL ................................. 354
14.6. TIPOS DE DATOS ........................................................................... 356
14.6.1. Tipos Numéricos .................................................................. 356

XIV
ÍNDICE

14.6.2. Tipos cadena de caracteres .................................................. 359


14.6.3. Tipos enum y set .................................................................. 361
14.6.4. Tipos fecha/hora .................................................................. 362
14.7. INTEGRIDAD REFERENCIAL EN MYSQL ................................ 364
14.7.1. Definición de claves foráneas .............................................. 365
14.7.2. Inserción de registros en tablas relacionadas ....................... 372
14.7.3. Eliminación de registros en tablas relacionadas .................. 373
14.7.4. Actualización de registros en tablas relacionadas................ 379
14.8. IMPORTACIÓN Y EXPORTACIÓN de datos ................................. 381
14.8.1. Importación de datos ............................................................ 381
14.8.2. Exportación de datos............................................................ 385

15. PHPMYADMIN: ADMINISTRACIÓN DE BASES DE


DATOS MYSQL DESDE LA WEB ......................................................... 389
15.1. INTRODUCCIÓN ............................................................................ 389
15.2. ENTRADA A PHPMYADMIN ........................................................ 390
15.3. GESTIÓN DE BASES DE DATOS ................................................. 392
15.3.1. Consulta de las bases de datos ............................................. 392
15.3.2. Manipulación de las tablas .................................................. 393
15.3.3. Estructura de las tablas ........................................................ 398
15.4. CREACIÓN DE NUEVAS BASES DE DATOS ............................. 400
15.4.1. Creación de tablas ................................................................ 401
15.5. OPERACIONES DE IMPORTACIÓN Y EXPORTACIÓN
DE DATOS ....................................................................................... 403
15.5.1. Importación de datos externos en las tablas ........................ 403
15.5.2. Exportación de datos............................................................ 405
15.6. GESTIÓN DE USUARIOS .............................................................. 407
15.6.1. Usuarios y privilegios .......................................................... 407
15.6.2. Creación de usuarios ............................................................ 408

16. CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP ........ 413


16.1. INTRODUCCIÓN ............................................................................ 413
16.2. CONEXIÓN CON MYSQL DESDE PHP ....................................... 414
16.2.1. Apertura de la conexión ....................................................... 414
16.2.2. Cierre de la conexión ........................................................... 415
16.3. SELECCIÓN DE LA BASE DE DATOS ........................................ 416
16.4. EJECUCIÓN DE SENTENCIAS SQL SOBRE LA BASE
DE DATOS SELECCIONADA ........................................................ 417

XV
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

16.4.1. Inserción de datos a través de formularios........................... 419


16.4.2. Recuperación de los resultados de las consultas .................. 424
16.5. OTRAS FUNCIONES DE MANIPULACIÓN DE DATOS ........... 450

17. IMPLEMENTACIÓN DE FOROS .......................................................... 453


17.1. INTRODUCCIÓN ............................................................................ 453
17.2. ESTRUCTURA DE LA TABLA DE LA BASE DE DATOS .......... 454
17.3. GENERACIÓN DE LA PÁGINA PRINCIPAL DE LOS FOROS .... 455
17.4. CONSULTA DE UN MENSAJE CON SUS RESPUESTAS .......... 458
17.5. INSERCIÓN DE NUEVOS MENSAJES ........................................ 460

18. SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL ....... 465


18.1. INTRODUCCIÓN ............................................................................ 465
18.2. GESTORES DE CONTENIDO ....................................................... 466
18.2.1. Funcionamiento .................................................................... 468
18.2.2. Características ..................................................................... 468
18.2.3. Ventajas e inconvenientes ..................................................... 470
18.3. GESTORES DE CONTENIDO BASADOS EN PHP
Y MYSQL ......................................................................................... 471
18.3.1. PHP-NUKE ......................................................................... 471
18.3.2. POSTNUKE ........................................................................ 473
18.3.3. MAMBO SERVER.............................................................. 474
18.3.4. PHPWEBSITE .................................................................... 475
18.3.5. PHP-WCMS ........................................................................ 476
18.3.6. XOOPS ................................................................................ 477
18.3.7. DRUPAL .............................................................................. 478
18.3.8. SITEFRAME ....................................................................... 479
18.4. OTRAS SOLUCIONES OPEN SOURCE ....................................... 480
18.4.1. Weblogs ................................................................................ 480
18.4.2. Sistemas de foros ................................................................. 484
18.4.3. Plataformas de e-learning ................................................... 486
18.4.4. Entornos de comercio electrónico ........................................ 488
18.4.5. Sistemas de atención al cliente ............................................. 490
18.4.6. Herramientas de gestión de proyectos .................................. 493
18.4.7. Otras herramientas ............................................................... 495

Índice alfabético ............................................................................................. 497

XVI
Prefacio

El presente libro aborda una temática de plena actualidad y de gran auge en


los últimos años, como es el uso de soluciones open source para el desarrollo
de aplicaciones web. El uso conjunto del lenguaje PHP y el sistema gestor de
bases de datos MySQL permite la construcción, de una manera sencilla y
eficiente, de verdaderos sitios web dinámicos. En los últimos tiempos se está
observando cómo son cada vez más las empresas que optan por estas tecnologías
para el desarrollo de sus portales; incluso, en el caso de particulares, algunos
de los servicios gratuitos de alojamiento de páginas web ofrecen la posibilidad
de usar PHP en conjunción con MySQL.
Los autores de este libro somos profesores de la Universidad de Cantabria,
con experiencia en la impartición de cursos sobre tecnologías de programación,
desarrollo de aplicaciones web, informática de gestión y sistemas de información.
Fruto de nuestra dilatada experiencia docente de estos años surge el presente
libro. Parte del material que incluye ha sido usado exitosamente para la
impartición de varios cursos de verano y un módulo de desarrollo de aplicaciones
web en el Máster en e-Business que organiza la Universidad de Cantabria.
Nuestra intención ha sido escribir un libro que pueda ser seguido por personas
con conocimientos muy básicos de lenguajes de programación y con inquietudes
por el desarrollo de sitios web. En el campo de la informática, especialmente,
existe un gran número de personas autodidactas y con un carácter claramente
vocacional; este tipo de libros va dirigido a ellos.

XVII
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Es por ello que se ha buscado un enfoque eminentemente práctico, ilustrando


los diferentes conceptos con un gran número de ejemplos. De hecho, se pretende
que a lo largo de los diferentes capítulos se vaya describiendo paso a paso todo
el proceso de desarrollo de un sitio web verdaderamente dinámico y profesional.
Para ello hemos optado por mostrar el desarrollo del sitio web de una empresa
ficticia; en concreto consideraremos el sitio web de un multicine que hemos
bautizado como «Cinem@s» y que ofrecerá la posibilidad de consultar carteleras
dinámicas (mostrando siempre la información actualizada), consultar
disponibilidades de localidades, registrarse como cliente,...
El libro comienza con una rápida presentación de las características generales
de Internet y las diferentes tecnologías de programación que pueden ser usadas.
Para pasar posteriormente a analizar la filosofía y evolución de la conocida
como corriente open source. El tercer capítulo tiene por objeto presentar los
comandos básicos del lenguaje HTML que permitan diseñar unas sencillas
páginas web en torno a las que construir posteriormente la aplicación web.
Tras estos tres capítulos iniciales, los siguientes se dedican a la presentación
del lenguaje PHP, su interacción con los formularios de HTML, así como a
presentar las estructuras básicas presentes en todo lenguaje de programación
(sentencias de control, funciones y estructuras de datos). Se ha dedicado también
un capítulo a una introducción muy básica a la programación orientada a objetos;
así como sendos capítulos dedicados a manejo de cookies y ficheros.
La segunda parte del libro se centra en el uso del sistema MySQL, para lo
que se ha considerado oportuno introducir un capítulo previo de estudio del
modelo relacional de bases de datos y el lenguaje SQL. Tras analizar las
características de MySQL se muestra cómo es posible la administración remota
de las bases de datos mediante una aplicación desarrollada en PHP. Una vez
analizada esta aplicación de administración, los siguientes capítulos muestran
la sencillez de los procesos de conectividad a MySQL desde PHP.
El libro finaliza con un capítulo en el que se presentan muy brevemente
algunas de las aplicaciones open source más conocidas en Internet y que se
basan en las tecnologías explicadas en el libro. Llegado a este punto se espera
que el lector pueda no solo hacer uso de esas aplicaciones, sino también
modificarlas y adaptarlas a sus necesidades particulares, aprovechando de esta
forma la gran ventaja de las aplicaciones de código abierto.
Finalmente, quisiéramos mostrar nuestro agradecimiento a los Departamentos
de Matemática Aplicada y Ciencias de la Computación y de Administración de
Empresas de la Universidad de Cantabria por sus facilidades y apoyo para escribir

XVIII
PREFACIO

este libro. Agradecimiento que hacemos extensivo a todos nuestros alumnos


durante estos años; ellos nos han servido de incentivo para embarcarnos en
este proyecto editorial.

Ángel Cobo
Patricia Gómez
Daniel Pérez
Rocío Rocha
Santander, febrero de 2005

XIX
¡ALERTA!

XX
INTERNET Y LA
PROGRAMACIÓN DE
ORDENADORES

1.1. INTRODUCCIÓN

La aparición a principios de los noventa del servicio web supuso una verdadera
revolución en el campo de la informática y las telecomunicaciones. Con la irrupción de
este nuevo servicio, Internet inició una rápida transición hacia el ámbito empresarial y
supuso un enorme impulso al crecimiento de la red. Lo que había surgido en plena
guerra fría como un proyecto militar y que posteriormente fue dirigiéndose hacia el
ámbito científico y académico, se empezó a convertir en un perfecto “escaparate virtual”
en el que las empresas pudieran ofrecer sus productos y servicios rompiendo barreras
geográficas y de comunicaciones. En la actualidad las empresas no ven únicamente el
servicio web como un mero escaparate o medio publicitario de enorme difusión. Internet,
y en particular el servicio web, abre a las empresas enormes posibilidades. La utilización
de tecnologías web permite agilizar los procesos, mejorar la productividad y aumentar la
eficacia, además de abrir las puertas a nuevas formas de negocio en el mercado global
que facilita Internet (e-business).

1
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Por supuesto, no han sido las empresas las únicas beneficiadas con el desarrollo de
Internet y del servicio web. Las instituciones públicas tienen también nuevas
formas de ofrecer servicios a los ciudadanos (e-governement), los usuarios
individuales tienen nuevas formas de adquirir productos (e-commerce) o nuevas
formas de formarse e instruirse (e-learning),...

Para poder realmente obtener todos estos beneficios ha sido preciso desarrollar
nuevas tecnologías que consigan hacer del servicio web un servicio dinámico e
interactivo. En sus orígenes el servicio World Wide Web fue concebido como un
sistema flexible de compartir información multimedia entre equipos heterogéneos a
través de redes informáticas. Para ello fue desarrollado un sistema de generación de
documentos a través de un lenguaje estándar: el lenguaje HTML. Los documentos
generados de esta forma podían incorporar texto y elementos gráficos, pero eran
documentos totalmente estáticos. Posteriormente fueron desarrollándose diferentes
tecnologías que, trabajando en conjunción con el lenguaje HTML, pudieran paliar
estas carencias. Así por ejemplo, Netscape incorporó en la versión 2.0 de su célebre
navegador un intérprete de un nuevo lenguaje que podía ser intercalado entre el
código HTML y que permitía realizar operaciones no disponibles en un lenguaje
puramente descriptivo como es HTML; dicho lenguaje, llamado en sus orígenes
LiveScript, adquirió posteriormente el nombre de JavaScript. Unos años más tarde
la empresa Sun Microsystems lanzó un revolucionario lenguaje de programación,
el lenguaje Java, que permitía incrustar en las páginas web programas con las
prestaciones propias de cualquier lenguaje de programación. Microsoft por su parte
también se unió a esta evolución primero con sus lenguajes de script: VBScript
basado en Visual Basic y JScript, versión Microsoft de JavaScript, y, más
recientemente, con las tecnologías .NET. Igualmente se han venido desarrollando
diferentes extensiones del propio lenguaje HTML con objeto de aumentar su
dinamismo; en este contexto se podría citar el HTML dinámico (DHTML) y el
lenguaje XML.

Internet ha jugado un papel esencial en la expansión de la denominada corriente


open source. Los defensores de esta corriente defienden el desarrollo de
aplicaciones informáticas y su distribución libre, de forma gratuita; pero no solo
eso sino que también ponen a disposición de los usuarios el código fuente de los
programas desarrollados. Se trata, en definitiva, de que los usuarios puedan utilizar
los programas sin ninguna restricción y puedan conocer si lo desean su
funcionamiento interno. El ejemplo más emblemático de esta corriente open source
lo constituye el sistema operativo Linux. En los últimos años está corriente se ha
desarrollado enormemente y ya se pueden obtener en la propia red Internet todo
tipo de programas basados en esta filosofía: servidores y navegadores web,
entornos de programación, editores, herramientas ofimáticas,... Grandes empresas
como IBM o Yahoo, por ejemplo, han apostado muy fuerte por las soluciones open

2
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

source y, sin lugar a dudas, el impacto de este tipo de soluciones parece destinado a
incrementarse en el futuro debido a sus altas prestaciones y calidad, su menor coste
y su alta difusión.

Las dos herramientas que se analizarán en este libro surgen de esta corriente. Por
un lado el lenguaje PHP, que nació como un lenguaje para realizar un seguimiento
de visitas de páginas personales, se ha convertido en uno de los referentes actuales
en los denominados lenguajes de script. Por otro lado, el sistema gestor de bases de
datos MySQL se presenta como una herramienta con altas prestaciones para el
desarrollo de bases de datos, especialmente apropiado para ser usada por pequeñas
organizaciones o empresas. La utilización conjunta de ambos: PHP y MySQL
permite llegar a desarrollar interesantes aplicaciones web que puedan cubrir las
necesidades de pequeñas empresas que quieran fortalecer su presencia en Internet o
usuarios individuales que quieran generar verdaderas páginas dinámicas. Como
complemento a ambas herramientas, en Internet se pueden encontrar igualmente
gestores de contenidos, aplicaciones basadas en PHP que permiten a los usuarios
finales aprovechar las ventajas de estas tecnologías sin necesidad de tener grandes
conocimientos sobre su funcionamiento y sintaxis de los lenguajes. En el presente
libro se darán referencias de algunas de estas herramientas de gestión de contenidos
y otras herramientas para la creación de aplicaciones web que han sido
desarrolladas igualmente haciendo uso de las dos tecnologías que se analizarán en
este libro: el lenguaje PHP y el gestor de bases de datos MySQL. El Capítulo 18
presentará algunas de estas herramientas.

1.2. INTERNET

El objeto de esta sección no es tanto definir lo que es Internet como el poner de


manifiesto algunas de las características más destacadas de la misma que influyen
decisivamente en las tecnologías de desarrollo vinculadas al servicio web, como es
el caso del lenguaje PHP. Se asume que cualquier lector interesado en este libro es
usuario de Internet y conoce los diferentes servicios que la red ofrece,
posiblemente también su interés en el desarrollo de aplicaciones web es el que le ha
impulsado a adquirir este libro.

Internet (INTERconected NETwork) es una red de redes de ordenadores de todo


tipo que se comunican mediante un lenguaje común: el conocido como protocolo
TCP/IP. Esa primera característica de la heterogeneidad de los equipos conectados
es clave para entender el funcionamiento de todos los servicios de la red y para
comprender la necesidad de la portabilidad en cualquier desarrollo que se quiera
hacer en el ámbito de Internet. A nivel de programadores de aplicaciones web, que

3
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

es en el que se sitúa el presente libro, no es necesario disponer de conocimientos


técnicos sobre los protocolos de comunicación en los que se basa Internet.

Los desarrollos de aplicaciones realizados en Internet tienen también un campo de


aplicación en aquellas redes privadas que usan los mismos sistemas y protocolos
que Internet: las denominadas Intranets.

Otro de los aspectos a tener en cuenta es el carácter distribuido de la red. Ese


carácter totalmente distribuido se concreta a todos los niveles: en el aspecto
geográfico no existe ningún nodo central de la red, de hecho, los orígenes de
Internet se sitúan en un proyecto militar del Gobierno de los Estados Unidos para
crear una red que no fuera vulnerable ante el ataque a alguno de sus nodos. En el
aspecto económico, tampoco existe ningún gobierno o institución que mantenga la
red sino que son las propias subredes que la componen las encargadas de su propio
mantenimiento. El carácter distribuido también se manifiesta en el aspecto político
ante la ausencia de un gobierno central de la red; lo que sí existen son diversas
organizaciones o asociaciones que tratan de establecer diferentes estándares para el
desarrollo de la red.

Aunque el servicio web es actualmente el servicio más conocido y utilizado de la


red Internet, conviene recordar que no es el único. Los tres servicios originarios de
la red: correo electrónico (e-mail), transferencia de fichero (FTP) y acceso remoto
(Telnet), siguen estando presentes y siguen siendo ampliamente utilizados. Pero
podrían citarse otros servicios, algunos muy conocidos y otros en cierta decadencia
al haber absorbido el propio servicio web sus funciones: servicios de noticias
(news), gopher, servicios de búsqueda de archivos (Archie), Verónica, servicios de
localización,... En los últimos años también están teniendo mucho auge las
aplicaciones P2P.

1.2.1. EL SERVICIO WEB


El servicio WWW, o simplemente Web, se podría definir como un amplio sistema
multimedia de acceso a información heterogénea distribuida por toda la red en
forma de documentos hipertextuales (hipertextos). Como ya fue comentado en la
introducción de este capítulo, este servicio surgió en 1990 en el CERN (Centre
Européen de Recherche Nucléaire) con el objetivo de facilitar la distribución de
información entre equipos investigadores geográficamente dispersos. Se buscaba
que los recursos disponibles en formato electrónico fuesen accesibles para cada
investigador desde su propia terminal de forma clara y simple, posibilitando el
salto entre elementos de información conexos. En definitiva, se trataba de integrar
todos los recursos existentes en una red hipertextual. Aunque el nacimiento del

4
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

servicio se sitúa en 1990, es en 1991 cuando el sistema desarrollado en el CERN se


abre a Internet, apareciendo en 1992 el primer navegador web: Mosaic.

El término hipertexto que empezó a hacerse popular a partir de la aparición de este


servicio tiene, sin embargo, su definición en un trabajo de Ted Nelson en 1965, la
definición original del término es:

"Un cuerpo de material escrito o gráfico interconectado de un modo


complejo que no se puede representar convenientemente sobre el papel;
puede contener anotaciones, adiciones y notas de los estudiosos que lo
examinan".

En una definición más moderna y aplicable al concepto de hipertexto en Internet,


se podría decir que un hipertexto es un documento multimedia, es decir, integrando
bajo una plataforma informática todas las tecnologías de la información, y que
incorpora relaciones estructurales que enlazan el documento con otros documentos
o recursos.

Algunas de las características destacadas de los hipertextos son:

— Almacenamiento de un gran volumen de información.


— Facilidad de acceso y consulta.
— Presentación de una forma más agradable.
— Uso de todas las tecnologías de la información.
— Permiten una “navegación” individualizada.
— Estructuración multidimensional.
— Multiplataforma.
— Dinamismo e interactividad.

1.2.2. RELACIÓN CLIENTE/SERVIDOR


Todos los servicios que ofrece Internet, y por supuesto entre ellos el servicio web,
se basan en la denominada relación cliente/servidor. El comprender bien esta
relación es esencial para entender el funcionamiento posterior de lenguajes como
PHP. En Internet se pueden encontrar dos tipos de equipos conectados:

— Servidores: ordenadores que ofrecen sus servicios al resto de equipos


conectados. Suelen tener una presencia estable en la red, lo que se concreta en
tener asignadas direcciones IP permanentes. En ellos es donde están alojadas,
por ejemplo, las páginas web.

5
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— Clientes: equipos que los usuarios individuales utilizan para conectarse a la red y
solicitar servicios a los servidores. Durante el tiempo de conexión tienen presencia
física en la red. Normalmente los proveedores de acceso a Internet asignan a estos
equipos una dirección IP durante su conexión, pero esa dirección es variable, es
decir, cambia de unas conexiones a otras (IP dinámica).
Los conceptos de cliente y servidor se suelen utilizar con dos significados
diferentes, en referencia al hardware el sentido es el indicado anteriormente, el
servidor hace referencia al equipo remoto al que se realiza la conexión y el cliente
sería el equipo local utilizado para efectuar dicha conexión. Pero también se
utilizan esos conceptos en referencia al software:

— Programa servidor es el programa que debe estar ejecutándose en el equipo


servidor para que este pueda ofrecer su servicio. Un documento HTML sin más
almacenado en el equipo remoto no basta para que sea accesible como página
web por el resto de usuarios de Internet, en ese equipo debe estar ejecutándose
una aplicación servidor web. Uno de los programas servidores web más
conocido y utilizado es Apache, programa que también pertenece a la corriente
open source. Existen otros servidores web como el Personal Web Server
(PWS) o el IIS disponibles en los equipos Windows. En el caso de otros
servicios como el correo electrónico o la transferencia de ficheros se
necesitarían igualmente los correspondientes programas en el servidor.

— Programa cliente es en este caso el software necesario en el equipo cliente para


tener acceso al correspondiente servicio. Así por ejemplo, los navegadores como el
Internet Explorer o Mozilla son ejemplos de clientes web; un programa como
Outlook es un ejemplo de cliente de correo electrónico y programas como
WS_FTP o CuteFTP son ejemplos de clientes FTP.

Figura 1.1 Relación cliente/servidor. Los clientes realizan peticiones de servicio


a los servidores
6
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

1.2.3. PROCESO DE CREACIÓN Y PUBLICACIÓN DE


PÁGINAS WEB
El proceso de creación y publicación de una página web debe pasar por una serie
de fases:

— Definición de la página: toda página web tiene detrás un código fuente que la
define. Cuando se accede a una página web, aunque en el monitor se puedan
visualizar documentos con imágenes y texto de diferentes tamaños, colores y
formatos, debe tenerse presente que detrás de eso hay un documento de texto
sin ningún tipo de formato y que incorpora una serie de instrucciones o
comandos que son los que realmente generan la página que se visualiza. Ese
documento fuente está definido en un lenguaje especial: el conocido HTML
(HyperText Markup Language). Se trata de un lenguaje puramente descriptivo
que incorpara una serie de comandos o etiquetas (tags) que permiten definir la
estructura lógica del documento, dar formato al texto, añadir elementos no
textuales,... Se asume que los lectores interesados en este libro tienen un cierto
conocimiento de este lenguaje de definición de hipertextos, no obstante, se ha
considerado oportuno incluir un capítulo introductorio en el que se presenten
los comandos básicos de HTML (Capítulo 3). Para aquellos lectores sin
conocimientos de HTML, una comprensión rápida de los comandos expuestos
en dicho capítulo es más que suficiente para poder entender el resto del libro.

— Publicación del documento: una vez creado el documento HTML que define la
página web, el siguiente paso es evidentemente publicarla para que esté
disponible para el resto de usuarios de Internet. La publicación implica la
transferencia del documento a un equipo servidor que disponga de un programa
de servidor web. Puede optarse por utilizar algún servidor de alojamiento
gratuito de páginas o utilizar los espacios que los proveedores de acceso a
Internet suelen ofrecer a sus clientes. Otra posibilidad sería configurar un
equipo propio para que actúe de servidor, para ello sería preciso contratar con
algún proveedor una dirección IP fija y registrar el dominio que se quiera
utilizar.

— Acceso a las páginas web: en el momento en que una página es publicada en el


servidor, cualquier usuario de Internet podría acceder a ella. Para ello es
preciso, por un lado que el usuario utilice un programa adecuado (el
navegador, explorador o cliente web), y que el código que define la página sea
transferido por la red utilizando el protocolo http (hypertext transfer protocol).
Sobre este último aspecto, en principio la mayoría de usuarios no deberían
preocuparse. El navegador web es el que se encarga de interpretar los

7
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

comandos HTML que se reciben y producir a partir de ellos la página web.


Existen diferentes navegadores web que se pueden utilizar, por ejemplo,
Internet Explorer, Netscape Navigator, HotJava, Mozilla,... este último sigue la
corriente open source.

1.2.4. DINAMISMO E INTERACTIVIDAD EN LAS


PÁGINAS WEB
HTML es un lenguaje puramente descriptivo que permite definir las páginas web pero que
en modo alguno se puede considerar un lenguaje de programación. Con HTML no se
pueden generar estructuras iterativas o condicionales, no se pueden definir funciones que
sean utilizadas en distintos puntos del documento, no se pueden declarar variables, no se
pueden realizar cálculos matemáticos,... Las páginas creadas únicamente con HTML son
básicamente estáticas, es decir, siempre muestran la misma información y no ofrecen
ningún grado de interactividad con el usuario. Los únicos elementos de HTML que podrían
de alguna forma considerarse interactivos son los formularios a través de los cuales se
solicita información al usuario.

Si se requiere aumentar el dinamismo e interactividad de las páginas se hace por tanto


obligado el recurrir a otros lenguajes y tecnologías como las que se abordan en este libro.
Esas dos características: dinamismo e interactividad son los dos elementos clave que se
deben tratar de potenciar para desarrollar verdaderas aplicaciones web.

Pero, ¿qué es una página dinámica? Piénsese, por ejemplo, en un multicine que quiere
publicar en Internet la información actualizada sobre horarios y películas que se proyectan
en cada una de sus salas. Evidentemente, sería muy sencillo generar una simple página en
HTML con una tabla en la que se muestre esa información; incluso sin necesidad de tener
ningún tipo de conocimiento sobre HTML, por ejemplo, se podría escribir en Word y usar
la opción de “Guardar como página web...”. Hasta aquí sencillo, pero la información en sí
es un elemento dinámico, las películas que se proyectan en cada sala cambian y por tanto la
página web debería ser actualizada. ¿Tiene sentido tener que modificar el documento
HTML cada vez que se produzca un cambio en la cartelera?, ¿no sería muchísimo más
rentable disponer de un sistema que modifique de forma automática la información que
muestra la página web? Esto es dinamismo, y esto no se puede conseguir solo con HTML.
A lo largo de los diferentes capítulos de este libro el usuario aprenderá cómo resulta
muy sencillo generar una base de datos con MySQL con toda la información de las
películas a proyectar y una página web con un programa PHP que se encargue, cada
vez que un usuario solicita la página, de hacer una consulta a la base de datos para
obtener la cartelera actualizada y generar con ella de forma automática el código
HTML que se envía al usuario. Este mismo ejemplo se irá desarrollando paso a paso en
los próximos capítulos y servirá de hilo conductor del resto del libro.

8
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

Otro ejemplo de dinamismo puede ser el preprocesamiento de datos introducidos


en formularios, comprobando por ejemplo la validez sintáctica de direcciones de
correo electrónico o la pertenencia a determinados rangos de valores numéricos.

En lo referente a interactividad, se trata de permitir que entre el usuario que acceda


a la página y la propia página exista un cierto grado de comunicación que no se
limite a que la página muestre la información al usuario. El usuario, por ejemplo, le
podría solicitar a la página que realice algún cálculo. Volviendo al ejemplo de los
multicines, supongamos que se desea que el usuario pueda hacer un cálculo de
forma automática de los importes de las entradas; mediante un formulario el
usuario puede introducir el número de entradas a adquirir, la sesión para la que se
desean y determinados parámetros que puedan afectar al precio (ser estudiante,
disponer de un vale de descuento,...) y la página debe calcular de forma automática
el importe total a pagar. Esto es interactividad.

1.3. PROGRAMACIÓN DE ORDENADORES


La programación de ordenadores se podría definir como el conjunto de técnicas,
métodos y reglas para poder construir programas de ordenador legibles, correctos y
eficientes. Un programa de ordenador no es más que una secuencia de
instrucciones en las que se le indican a la máquina las órdenes o acciones a
realizar; se podría entender por tanto la programación como el arte de decir a una
máquina lo que queremos que haga de una manera que pueda entenderlo.

Como todos los campos de la informática, la programación de ordenadores ha


sufrido una importante evolución en las últimas décadas. Los orígenes se sitúan en
la década de los 50 con la aparición de los primeros lenguajes de programación:
Fortran (1954), Cobol (1954) y Algol (1957). Estos primeros lenguajes estaban
muy orientados hacia aplicaciones concretas; así por ejemplo, Fortran es un
lenguaje orientado hacia el cálculo científico mientras que Algol lo es hacia
aplicaciones de gestión. Los años 60 vienen marcados por el nacimiento de la
programación estructurada y la aparición de lenguajes como PL/1 de IBM (1960) o
el BASIC (1963).

Es en los años 70 cuando aparecen dos de los lenguajes estructurados de mayor


difusión: el Pascal (1970) y el C (1972); este último evolucionaría posteriormente
hacia el C++ y hoy en día es el lenguaje más utilizado en el desarrollo de
aplicaciones. La programación estructurada se basa en el desarrollo de módulos o
funciones independientes que puedan ser utilizadas en cualquier momento. Es
destacable también en esta década de los 70 el desarrollo del modelo relacional de

9
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

bases de datos, modelo en el que se basan la mayoría de los sistemas gestores de


bases de datos actuales, entre ellos MySQL.

Los 80 vienen marcados por la aparición del ordenador personal y el nacimiento de


la microinformática. La informática deja de ser algo exclusivo de las grandes
empresas e instituciones y se acerca al público en general. En esta época aparecen
también los primeros sistemas operativos con interfaces de usuario gráficas: el
célebre “Mac” de Apple Macintosh. Años más tarde Microsoft seguiría esos pasos
con su sistema operativo Windows. La aparición de este tipo de interfaces también
afectaría notablemente a la evolución de los lenguajes de programación, en
concreto surge la necesidad de desarrollo de técnicas de programación basadas en
eventos. En los años 80 aparece también una nueva forma de entender la
programación: la programación orientada a objetos, así surgen los lenguajes ADA
(1980) y C++ (1985). La base en la que se apoya este estilo de programación es el
entender los objetos como entidades compuestas de acciones y datos y, por tanto, a
la hora de programar las funciones (acciones) y las variables (datos) deben
entenderse como componentes de una misma unidad.

La década de los 90 se inicia con la aparición del revolucionario servicio web y


la necesidad cada vez más patente de orientar los desarrollos hacia la
integración de aplicaciones. El servicio web, como ya se comentó, rápidamente
crea la necesidad de nuevas formas de programación y así en 1995 nace el
lenguaje Java, primer lenguaje pensado para integrar directamente programas
en las páginas web. Los programas Java que se integran en esas páginas se
denominan applets.

En la actualidad, la evolución en los diferentes sistemas operativos, de los nuevos


servicios de Internet y del propio hardware influyen en las prestaciones
recomendadas que debe tener un lenguaje de programación, algunas de las que se
podrían citar son:

— Programación estructurada: en la actualidad todos los lenguajes de


programación soportan este tipo de programación, en la que las instrucciones
se agrupan en bloques constituyendo módulos que se llaman unos a otros.

— Programación orientada a objetos: los lenguajes de programación de mayor éxito


se basan en la construcción de clases de objetos. Cada clase engloba, por un lado
las acciones que pueden ser realizadas con esos objetos y, por otro, los datos o
características asociadas a los mismos. Algunos lenguajes actuales, aunque no
pueden ser considerados orientados a objetos, sí que incorporan algunas
características propias de estos lenguajes, trabajando también con objetos.

10
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

— Programación guiada por eventos: los programas deben ser capaces de dar
respuesta a las diferentes acciones que el usuario efectúa sobre la interfaze del
programa. Por ejemplo, cuando un usuario elige una opción de menú o pulsa
un botón se genera un evento que debe ser detectado, identificado y tratado por
el programa.

— Programación concurrente: la aparición cada vez con más frecuencia de


equipos con más de un procesador plantea nuevas formas de programación; un
programa podría ser susceptible de dividir en varias tareas que puedan estar
realizándose de forma simultánea, cada tarea puede ser ejecutada por un
procesador diferente o bien utilizar mecanismos de reparto del tiempo de
procesador. Esta es la base de la programación paralela o concurrente.

— Prestaciones multimedia: los programas deben ser capaces de manejar todo


tipo de información y recursos; deben de estar preparados para trabajar con
elementos gráficos en diferentes formatos, animaciones o vídeo, sonido,...

— Portabilidad: evidentemente los programas son desarrollados para que


puedan ser utilizados por diferentes usuarios y no siempre está garantizado
que los usuarios tengan equipos similares. La portabilidad de los programas
permite que estos puedan ser ejecutados sobre diferentes plataforma
informáticas. Sin embargo, la portabilidad puede entenderse a dos niveles: a
nivel de código fuente la portabilidad implica que el código puede ser
compilado sobre las dos plataformas para obtener dos versiones diferentes del
programa. En algunos casos, la portabilidad se consigue a nivel no de código
fuente sino del código resultado del proceso de compilación; esto es lo que
ocurre por ejemplo con el lenguaje Java. En Internet, la portabilidad es un
concepto clave por cuanto a la red están conectados todo tipo de equipos.

— Integración de aplicaciones: cada vez es más necesario que los lenguajes de


programación incorporen mecanismos sencillos para conectarse con otras
aplicaciones. Quizás el caso más claro de ello sea la conectividad a bases de
datos; los programas deben ser capaces de establecer esa conexión y realizar
consultas sobre los datos almacenados.

1.3.1. TIPOS DE LENGUAJES DE PROGRAMACIÓN


Los lenguajes de programación pueden ser clasificados de acuerdo a varios
criterios. Una de las primeras clasificaciones que se suele efectuar es la distinción
entre lenguajes de bajo nivel y de alto nivel. La programación en los primeros
resulta más dificultosa puesto que las instrucciones están muy próximas al

11
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

hardware del equipo y resultan difíciles de entender por un programador no


especialista. El ejemplo clásico de lenguaje de bajo nivel es el lenguaje
ensamblador.

La mayor parte de los programadores optan por utilizar lenguajes cuyo código
resulta más fácil de entender, por cuanto sus reglas sintácticas se asemejan más a la
forma de comunicarse las personas; son lenguajes que están “más cerca” del
programador pero más lejos de la máquina a la que van dirigidos. Estos lenguajes
son los denominados "lenguajes de alto nivel" y a ellos pertenecen los lenguajes de
programación más conocidos.

Cuando se está desarrollando un programa usando un lenguaje de programación se


genera un código (código fuente) que es comprensible para todo aquel usuario que
tenga los conocimientos suficientes sobre el correspondiente lenguaje, pero que en
ningún caso es comprensible directamente para la máquina. Los ordenadores
trabajan internamente mediante circuitos electrónicos que admiten dos posiciones:
abierto o cerrado (1 ó 0) y por tanto, toda orden a dar a la máquina debe ser
planteada en última instancia como secuencias de ceros y unos (código binario).
Parece claro por tanto que se necesita un proceso de “traducción” del código fuente
que nosotros entendemos a instrucciones entendibles por la máquina. Ese proceso
de traducción se puede realizar de dos maneras, y eso da pie a establecer una nueva
clasificación de los lenguajes de programación:

— Lenguajes compilados: en un lenguaje compilado el código fuente pasa por un


proceso denominado "compilación" en el que se genera un código denominado
"objeto", que una vez enlazado con otros posibles módulos de código objeto
necesarios, genera el fichero ejecutable con el programa. Ese fichero ejecutable
es lo único necesario para poder utilizar el programa y contiene todas las
instrucciones del mismo pero en el formato entendible por la máquina. El
aspecto más importante a destacar es que el proceso de compilación se realiza
con anterioridad a cualquier ejecución o uso del programa; en ese proceso se
comprueba la validez sintáctica del programa y si todo es correcto se genera el
ejecutable. Si se produce un error en la compilación el programa no podrá ser
utilizado.

— Lenguajes interpretados: en los lenguajes interpretados, la traducción de las


instrucciones se va realizando de forma secuencial por una aplicación,
denominada "intérprete", al mismo tiempo que se ejecuta el programa. De
esta forma, si llegado un punto del programa el intérprete se encuentra
con una instrucción errónea, el programa no continúa pero sí que habrá
podido ejecutar todas las sentencias previas. A diferencia de los lenguajes

12
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

compilados, la verificación de la corrección sintáctica del programa no se


realiza antes de la ejecución sino al mismo tiempo.

Por poner un símil que sirva para clarificar la diferencia entre ambos tipos de
programas, supóngase que una persona recibe una lista con una serie de tareas a
realizar. Podría optar por utilizar dos estrategias:

— Antes de comenzar la persona pierde unos minutos leyendo toda la lista y


analizando la coherencia o factibilidad de las tareas que se le están
encomendando. Si todas las tareas son coherentes realiza un proceso de
planificación para determinar la forma de realizarlas todas. Pero si detecta
alguna tarea que no entiende o le resulta incoherente, informa a la persona que
le ha encargado las tareas y opta por no iniciar sus labores a la espera de una
posible rectificación en el listado de tareas (enfoque de un programa
compilado)

— Nada más recibir la lista de tareas, la persona lee la primera labor


encomendada y la realiza. A continuación pasa a la segunda, la lee y la realiza,
y así sucesivamente. Si todo ha ido bien, habrá realizado todas las tareas, pero
si al llegar a un punto de la lista se encuentra con una tarea errónea o no
coherente, opta por abandonar el resto del trabajo e informar a la persona que
le encargó las tareas de tal extremo (enfoque de un programa interpretado)

Traducción
if(x<0) 01101101110
return 1; 10111101000
else ... 111....

Figura 1.2 Necesidad de un proceso de traducción del código fuente para que el
ordenador pueda entenderlo. Dicha traducción puede realizarse mediante un
proceso de complicación o mediante el uso de un intérprete

13
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

A primera vista, se podría pensar que un lenguaje compilado es más seguro en el


sentido de no producir errores a la hora de ejecutar el programa. En principio, si se
producen errores sintácticos en el programa, estos son detectados en la compilación
y por tanto el programa nunca se ejecutaría hasta que estos errores fuesen
corregidos. Efectivamente, esto es así, pero tampoco se puede descartar que, a
pesar de no haber errores sintácticos en el código fuente, se produzcan errores a la
hora de ejecutar el programa. Piénsese en un programa que tiene una instrucción en
la que se deben dividir dos números almacenados en dos variables y guardar el
resultado en una tercera variable; la instrucción puede ser sintácticamente correcta,
pero ¿qué pasa si a la hora de ejecutar el programa el segundo de los números es
cero?, se producirá un error de tipo aritmético debido a la división por cero y si el
programa no está preparado para ello, se abortará bruscamente su ejecución. Este
tipo de errores son los que se denominan errores en tiempo de ejecución.

En un lenguaje interpretado, todos los errores son detectados en tiempo de


ejecución, tanto los debidos a errores sintácticos como los debidos a condiciones
singulares producidas a la hora de ejecutar el programa.

Desde un punto de vista práctico los lenguajes compilados resultan más poderosos
pero los interpretados resultan más flexibles. El proceso de compilación genera
códigos ejecutables fuertemente dependientes de la máquina a la que van dirigidos,
con lo que se pierde la portabilidad del programa final aunque sí que se puede en
algunos casos tener portabilidad del código fuente. Por ejemplo, si se ha
desarrollado un programa en lenguaje C siguiendo el estándar ANSI, ese código
puede ser compilado por un compilador de C en Windows para generar la versión
ejecutable en Windows del programa, y posteriormente repetir la compilación en
Unix con un compilador diferente para obtener la versión Unix. Por supuesto, la
portabilidad del código solo es posible si no se hace uso en el programa de aspectos
particulares de una plataforma concreta.

Con un lenguaje interpretado se facilita la portabilidad, ya que lo único necesario


es disponer en cada plataforma del intérprete adecuado. Esta es la razón por la cual
muchos de los lenguajes para el desarrollo de aplicaciones web son interpretados,
ya que en Internet la portabilidad es imprescindible. Ejemplos de lenguajes
interpretados son JavaScript, VBScript y el propio PHP.

Otra de las ventajas de los lenguajes interpretados puede ser la mayor facilidad
para su aprendizaje y la simplificación en el proceso de desarrollo de las
aplicaciones. En el caso de los lenguajes interpretados para el desarrollo de
aplicaciones web, no se requiere además ningún tipo de herramienta de desarrollo
como puedan ser compiladores; los intérpretes van integrados en los navegadores
web en un caso y en los servidores web en otro. El código fuente además se

14
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

incrusta dentro del código HTML con lo que incluso no sería necesario ningún tipo
de editor específico.

Mención especial merece el lenguaje Java: se dice de él que es un lenguaje que


combina el poder de los lenguajes compilados y la flexibilidad de los interpretados.
Cuando se quiere integrar en una página web un programa Java (applet Java), se
necesita un proceso de compilación que genera un código binario a partir del
código fuente, pero este código no es ejecutable directamente sino que se ejecuta
por un intérprete que incorpora el navegador web que el usuario utilice al acceder a
la página. Este pequeño artificio es el que permite conseguir la portabilidad del
código compilado Java.

Los lenguajes interpretados que se utilizan en Internet para aumentar las


prestaciones de las páginas web se suelen denominar lenguajes de script y a los
programas con ellos desarrollados se les denomina scripts o guiones. Como ya se
ha comentado, el lenguaje PHP pertenece a esta categoría al igual que los otros dos
lenguajes de script más conocidos: JavaScript y VBScript.

1.4. PROGRAMACIÓN EN INTERNET


Como ya ha quedado de manifiesto, para poder hacer uso de toda la potencialidad del
servicio web cada vez más se requiere la utilización de lenguajes de programación que
complementen al lenguaje HTML. A la hora de decidir qué tecnología o lenguaje
concreto se puede utilizar para el desarrollo de una aplicación web deben plantearse
algunas preguntas cuya respuesta puede condicionar la elección final:

— ¿Cuándo se realizarán las acciones? Por ejemplo, se puede querer que el


programa sea ejecutado al cargar la página que lo integra o, por el contrario, no
ejecutar el programa hasta que se produzca determinado evento sobre la página
(mover el ratón, pulsar un botón, situar el curso sobre algún elemento de la
página,...). En este segundo caso se requiere un lenguaje que admita
programación guiada por eventos, y la elección de un lenguaje como
JavaScript, por ejemplo, sería más adecuada que la elección de PHP.

— ¿Cuál será el formato del conjunto de ordenes? Se puede optar por generar
programas de forma independiente que se integren en la página después de un
proceso de compilación, tal como ocurre en el caso de Java, o por el contrario
se puede desarrollar la aplicación en base a scripts o guiones que, sin
necesidad de compilación, sean incrustados directamente entre el código
HTML, tal como se hace en PHP, JavaScript o VBScript.

15
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— ¿Quién ejecutará o interpretará las ordenes? Como se ha comentado, en el servicio


web intervienen dos equipos, el servidor en el que está alojada la página y el cliente
que recibe el código HTML y genera la página en sí. Cuando existe también un
programa o script integrado en la página, la duda es cuál de los dos equipos es el
encargado de ejecutar las órdenes. En PHP, los programas son ejecutados por el
servidor mientras que en JavaScript es el cliente el que los ejecuta.

1.4.1. PROGRAMACIÓN DEL LADO DEL CLIENTE VS


PROGRAMACIÓN DEL LADO DEL SERVIDOR
La respuesta a la última pregunta planteada en la sección anterior da pie a la
clasificación de las tecnologías de programación en Internet en dos categorías:

— Programación del lado del cliente: los programas residen junto a la página web
en el servidor pero son transferidos al cliente para que este los ejecute. Java,
JavaScript, VBScript son lenguajes de programación del lado del cliente.

— Programación del lado del servidor: los programas son ejecutados por el
servidor y lo que se envía al cliente es la respuesta o resultado de dicha
ejecución. Lenguajes como PHP o Perl pertenecen a esta categoría.

Figura 1.3 Diferencia entre la programación del lado del servidor y la del lado del cliente

16
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

Cada una de estas estrategias tiene evidentemente sus ventajas y sus


inconvenientes, en cualquier caso no son excluyentes, ya que en una misma página
pueden incorporarse por ejemplo scripts en PHP para ser ejecutados por el servidor
y scripts en JavaScript para ser ejecutados por el cliente. En definitiva, se trata de
aprovechar las ventajas de cada tecnología en el desarrollo de las aplicaciones web.

Programación del lado del cliente Programación del lado del servidor
— Los programas residen en el servidor — Los programas residen y son ejecutados
pero se ejecutan en el cliente por el servidor

— Se descarga de trabajo a los servidores — El trabajo recae sobre los servidores


pudiendo llegar a sobrecargarse

— La ejecución del programa requiere una — Al cliente solo se les transfiere el


transmisión por la red del código resultado de la ejecución del programa
necesario para ello

— Las respuestas a las acciones de los — Una vez enviada al usuario la respuesta
usuarios sobre el programa pueden ser del programa, cualquier petición
invocadas sin necesidad de realizar adicional del cliente requiere una nueva
transmisiones por la red conexión con el servidor y la ejecución
en él de un nuevo programa

— Para la correcta ejecución del — En los equipos de los clientes no se


programa se requiere que el cliente necesita ningún software especial, todo
tenga instalados programas o plug-ins lo necesario debe estar instalado en el
adecuados servidor

— Si en un cliente no está instalado alguno — Todos los clientes podrán visualizar


de los programas intérpretes o plug-ins, correctamente la página
la página no se ejecutará correctamente

— Al transferirse el código, el cliente tiene — El código fuente permanece en el


acceso a dicho código y puede obtener servidor, se conserva su privacidad y
a partir de él información que pueda los clientes no tienen acceso a él
resultar comprometida

— Se pueden integrar los programas en — La mayoría de los servicios de


las páginas alojadas en cualquier alojamiento gratuito de páginas no
servidor web admiten este tipo de programación

Tabla 1.1 Diferencias entre la programación del lado del cliente y del lado del servidor

17
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

1.4.2. TECNOLOGÍAS DE PROGRAMACIÓN DEL


LADO DEL CLIENTE
En esta sección se presentan algunas de las tecnologías de programación del lado
del cliente más conocidas y utilizadas. Se trata únicamente de conocer sus
principales características para compararlas posteriormente con las del lenguaje
PHP.

JavaScript
JavaScript es un lenguaje interpretado basado en guiones que son integrados
directamente en el código HTML. El código es transferido al cliente para que este
lo interprete al cargar la página. Con JavaScript no pueden crearse programas
independientes.

La primera versión de este lenguaje apareció con el navegador Netscape 2.0 en


1995, con el nombre original de LiveScript y soportando gran cantidad de las
instrucciones que tiene en la actualidad. La versión JavaScript 1.1 se diseñó con la
llegada de las versiones 3.0 de los navegadores e incorporó algunas
funcionalidades nuevas como el tratamiento dinámico de imágenes y la creación de
arrays. Es esta versión la primera que se incorpora al explorador de Microsoft. En
los navegadores 4.0 de Microsoft y Netscape se incorporó ya un intérprete para una
nueva versión del lenguaje, el JavaScript 1.2. Con esta versión se inicia un proceso
de diferenciación en algunos aspectos de la implementación en los dos
navegadores, proceso que culminaría con el nacimiento de JScript, nombre con el
que Microsoft denomina a su versión de JavaScript. En la actualidad Microsoft ha
desarrollado su JScript.net.

Las principales características de este lenguaje son:

— Es un lenguaje interpretado.
— No necesita compilación.
— Multiplataforma.
— Lenguaje de alto nivel.
— Admite programación estructurada.
— Basado en objetos.
— Maneja la mayoría de los eventos que se pueden producir sobre la página
web.
— No se necesita ningún kit o entorno de desarrollo.

18
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

A diferencia de Java, JavaScript no dispone de elementos para crear interfaces


de usuario propias para los programas y tiene que utilizar para ello los
formularios de HTML a través de los denominados manejadores de eventos.

Java
Java es un lenguaje de programación clásico en cuanto a que requieren un proceso
de compilación. El código compilado puede ser integrado en la página web para
que sea ejecutado por el cliente.

El nacimiento formal del lenguaje se sitúa en enero de 1996 con el lanzamiento por
parte de la empresa creadora, Sun Microsystems, del JDK 1.0 (Java Development
Kit). Este entorno de desarrollo Java puede obtenerse de forma totalmente gratuita
a través de Internet (http://www.javasoft.com) e incorpora los elementos básicos
necesarios para el desarrollo de aplicaciones Java.

Con Java se pueden crear dos tipos de programas:

— Applets: programas que se integran en las páginas web y que, residiendo en el


servidor, son ejecutados por el cliente. La ejecución necesita de la
interpretación del código compilado por el software cliente.

— Aplicaciones: programas autónomos que se pueden ejecutar en cualquier


equipo. En este último caso puede optarse por generar código compilado
similar al de los applets y que para su ejecución necesita de un intérprete o
código compilado ejecutable directamente como en cualquier otro lenguaje de
programación.

En el caso de los applets, el código fuente no se incrusta directamente en el


documento HTML, sino que lo que se añade es un código binario resultado de la
compilación, el denominado JBC (Java Byte Code). Esto permite proteger el
código fuente, aunque hasta cierto punto, ya que las particularidades de este código
compilado hacen que sea factible el proceso inverso, es decir, la decompilación,
recuperar el código fuente a partir del compilado. En la propia Internet pueden
encontrarse programas capaces de hacerlo. La razón de todo esto está en el hecho
de que para conseguir la portabilidad de los programas el código compilado es un
código que se encuentra a mitad de camino entre un código fuente y un código
objeto fuertemente dependiente de una plataforma. Es por ello que se suele decir de
Java que es un lenguaje que combina la flexibilidad de los lenguajes interpretados
y el poder de los compilados.

19
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Por supuesto, Java es un lenguaje con unas altas prestaciones, mucho mayores que
las de lenguajes interpretados. Algunas de sus características son:

— Es un lenguaje orientado a objeto.


— Admite programación concurrente.
— Dispone de clases de objetos para la generación de interfaces gráficas de
usuario.
— Tiene prestaciones multimedia.
— Resulta un lenguaje familiar, al tener una sintaxis similar al C++, aunque
eliminando algunos de los problemas más engorrosos del lenguaje C: el uso de
punteros, la gestión de la memoria y el control de accesos a los elementos de
arrays.
— Es un lenguaje simple, robusto y seguro.
— A través de Internet se puede acceder a todo lo necesario para desarrollar
applets Java.

VBScript
VBScript es, al igual que JavaScript, un lenguaje basado en guiones que permite
integrar programas directamente en el código HTML. Admite un doble uso, por un
lado como lenguaje del lado del cliente, pero también como lenguaje del lado del
servidor para la generación de páginas ASP.

Es un lenguaje desarrollado por Microsoft tomando como referente de sintaxis el


VBA, Visual Basic para Aplicaciones. Por supuesto, no ofrece todas las
funcionalidades de un entorno de desarrollo visual como Visual Basic, pero si se
presenta como un herramienta poderosa y de fácil uso para generar páginas web
interactivas.

1.4.3. TECNOLOGÍAS DE PROGRAMACIÓN DEL


LADO DEL SERVIDOR
Al igual que se hizo en la sección anterior, se presentan a continuación algunas de
las tecnologías de programación del lado del servidor más conocidas. Dentro de
esta categoría es en la que se sitúa el lenguaje PHP, que se estudiará con detalle en
los próximos capítulos.

20
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

Programación CGI
CGI son las siglas de Common Gateway Interface (Interfaz de Pasarela Común) y
lo que define es un estándar para establecer la comunicación entre un servidor web
y un programa. Esta interfaz define una forma cómoda y simple de ejecutar
programas que se encuentran en la máquina en la que se aloja el servidor, a través
de la definición de una serie de reglas que deben cumplir tanto las aplicaciones
como los servidores para hacer posible la ejecución de los programas.
Al tratarse de una interfaz, no existe ningún tipo de dependencia con el lenguaje de
programación empleado. Para desarrollar programas CGI se puede utilizar
cualquier lenguaje. Los más habituales son: C, C++, Fortran, Perl, Tcl, Visual
Basic, AppleScript. Los lenguajes interpretados como Tcl y Perl, tienen mayor
facilidad de mantenimiento y depuración, presentan ventajas de seguridad, pero
resultan más lentos. Los lenguajes compilados (C, C++,...), por su parte, son
mucho más rápidos. En el caso de CGI la velocidad de ejecución es importante, ya
que habrá que sumar el tiempo de ejecución al tiempo de espera de red y a la
velocidad de transmisión.

ASP: Páginas de Servidor Activas


ASP (Active Server Pages) es la tecnología diseñada por Microsoft para facilitar la
creación de sitios web con una mayor sencillez que la empleada en la
programación CGI. El principal inconveniente es la fuerte dependencia del entorno
Microsoft, ya que requiere un servidor web de Microsoft, como puede ser el
Internet Information Server (IIS) o el Personal Web Server (PWS).

Para utilizar la tecnología ASP sobre otros servidores, por ejemplo servidores
Unix, se necesita un software intérprete (Chilisoft, Instant ASP).

El núcleo de funcionamiento de ASP es una aplicación ISAPI (Internet Server


API). Una aplicación ISAPI es una DLL de Windows que se ejecuta en el mismo
espacio de direcciones que el servidor web y que puede soportar varias peticiones
simultáneas.

ASP no es realmente un lenguaje como tal, el lenguaje usado en realidad para


programar ASP es Visual Basic Script o Jscript (versión Microsoft de JavaScript).

Servlets y JSP: Páginas de Servidor Java


Los servlets y Java Server Pages (JSPs) son dos métodos de creación de páginas
web dinámicas en servidor usando el lenguaje Java. Se trata de tecnologías
desarrolladas por la empresa Sun Microsystems.

21
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Las JSP se diferencian de otras tecnologías del lado del servidor como los CGI
o las ASP en dos aspectos principalmente: por un lado, los JSP y servlets se
ejecutan en una máquina virtual Java, lo cual permite que, en principio, se
puedan usar en cualquier tipo de ordenador, siempre que tenga instalado esa
máquina virtual. Por otro lado, un programa JSP se compila a un programa en
Java la primera vez que se invoca, y del programa en Java se crea una clase que
se empieza a ejecutar en el servidor como un servlet. De esta manera los
servlets no se ejecutan cada vez que se recibe una petición, sino que persisten
de una petición a la siguiente, lo que permite realizar operaciones como la
conexión a bases de datos o manejo de sesiones de una manera más eficiente.

Un JSP es una página web con etiquetas especiales y código Java incrustado,
mientras que un servlet es un programa que recibe peticiones y genera a partir de
ellas una página web. En ambos casos se necesita un programa servidor que se
encargue de recibir las peticiones, distribuirlas entre los servlets y realizar las
tareas de gestión propias de un servidor web. Estos programas suelen llamarse
contenedores de servlets o servlet engines, y, entre otros, podrían citarse como
ejemplos Resin, BEA Weblogic, JRun de Macromedia, Lutris Hendirá, o, quizás el
más popular y conocido: Toncat.

ColdFusion
ColdFusion es una tecnología desarrollada inicialmente por Allarie, que en la
actualidad pertenece a Macromedia. Es una herramienta sencilla de aprender y
bastante potente que funciona sobre la mayoría de servidores web. Los scripts se
desarrollan por medio de etiquetas al estilo HTML (ColdFusion en realidad se
denomina Cold Fusion Markup Language -CFML-). Estas etiquetas se sitúan
dentro del documento HTML y son ejecutadas por el servidor, de forma que el
cliente solo ve el resultado, no el código.

Básicamente ColdFusion está formado por tres componentes: una aplicación


servidor, un lenguaje de marcación (ColdFusion Markup Language, CFML) y un
programa administrador. La aplicación servidor es la encargada de leer e interpretar
las instrucciones que le son pasadas a través de páginas ColdFusion. Estas páginas
se identifican por tener la extensión .cfm o .cfc y contienen etiquetas HTML y
etiquetas específicas del lenguaje propio de ColdFusion: CFML.

Las etiquetas del lenguaje CFML tienen una sintaxis similar a las de HTML y se
distinguen del resto por tener nombres que siempre comienzan con cf. Además de
las etiquetas predefinidas, el programador puede crear nuevas etiquetas e incluso
puede integrar código en otros lenguajes como C, C++ o Java.

22
INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

Las aplicaciones ColdFusion pueden interactuar con cualquier base de datos que
soporte ODBC o JDBC.

PHP
PHP es un lenguaje interpretado del lado del servidor que surge dentro de la
corriente denominada código abierto (open source). Se caracteriza por su potencia,
versatilidad, robustez y modularidad. Al igual que ocurre con tecnologías similares,
los programas son integrados directamente dentro del código HTML. En este libro
se explicará en detalle la sintaxis y el funcionamiento de este lenguaje, de momento
se realiza a continuación una breve comparativa con las otras tecnologías del lado
del servidor descritas previamente.

Comparado con ASP, la principal ventaja de PHP es su carácter multiplataforma.


Por otro lado, los programas en ASP resultan más lentos y pesados, y también
menos estables. En los entornos Microsoft la ventaja de ASP es que los servidores
web de Microsoft soportan directamente ASP sin necesidad de ninguna instalación
adicional

Señalar también la existencia de herramientas que permiten convertir programas


desarrollados en ASP al lenguaje PHP, una de las más conocidas es asp2php.

Comparando el lenguaje PHP con el lenguaje Perl, utilizado habitualmente en la


programación CGI, puede decirse que PHP fue diseñado para desarrollo de scripts
orientados a web, mientras que Perl fue diseñado para hacer muchas más cosas y
debido a esto, se hace muy complicado. La sintaxis de PHP es menos confusa y
más estricta, pero sin perder la flexibilidad.

En comparación con ColdFusion, PHP es más rápido y eficiente para tareas


complejas de programación, además PHP resulta más estable y usa una menor
cantidad de recursos. Por el contrario, ColdFusion posee un mejor gestor de
errores, un buen motor de búsquedas, abstracciones de bases de datos y un gran
número de funcionalidades para el procesamiento de fechas. Finalmente,
ColdFusion no está disponible para todas las plataformas.

En definitiva, PHP es uno de los lenguajes más utilizados actualmente en el


desarrollo de aplicaciones web y viene experimentado un constante crecimiento en
su nivel de utilización en Internet. Este libro trata de humildemente contribuir a
continuar con el proceso de difusión de esta tecnología.

23
OPEN SOURCE Y
SOFTWARE LIBRE

2.1. INTRODUCCIÓN
El actual entorno mundial está claramente caracterizado por el fenómeno de la
1
globalización , que puede entenderse como un efecto acción reacción que ocurre a gran
velocidad, casi de forma simultánea, por el cual los acontecimientos significativos que
ocurren en una parte del planeta repercuten o hacen reaccionar casi inmediatamente al
resto. Como rasgos característicos de este entorno globalizante podemos destacar, por un
lado, la tendencia a la estandarización económica, social, cultural y, como no, tecnológica,
siguiendo como modelo los patrones del bloque económico más fuerte, Estados Unidos. Y,
por otro, el uso intensivo de las tecnologías de la información y las comunicaciones (TIC).
En este sentido, el constante crecimiento del numero de actividades sociales y
empresariales, que necesitan de las computadoras, y la incorporación y presencia masiva de
dispositivos digitales en cualquier actividad humana han aumentado la cantidad y

1
Las definiciones de globalización son múltiples, aquí interesa más comprender su
significado general que entrar en los matices de las distintas definiciones. No obstante, para
una mayor profundidad sobre el concepto se recomienda consultar las siguientes obras
Globalización: oportunidades y desafíos. (Maesso Corral, 2003) y Los limites a la
globalización (Noam Chomsky, 2002).

25
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

complejidad de los sistemas software, haciendo crecer por tanto la inversión y dependencia
de dichos sistemas y en definitiva de sus creadores.

Segmentos 2003 2004 % Cto Previsión


Diciembre Noviembre 03/04 2005
Hardware 140.129 142.032 1.35 147.351
Software 61.017 63.758 4.5 67.854
Servicios TI 114.938 117.301 2.05 122.272
Telecomunicaciones 292.287 303.507 3.83 316.941
Total 608.371 626.598 2.99 654.418

Tabla 2.1 Facturación del mercado de las TIC (en millones de euros) en Europa por
segmentos. Elaboración propia a partir de los datos de noviembre obtenidos en el Centro
de Predicción Económica de la Universidad Autónoma de Madrid (CEPREDE) y el
Observatorio de Tecnologías de la Información Europeo (EITO)

En el ámbito informático, que es el que interesa en este libro, este proceso


de homogenización y dependencia queda claramente reflejado en el software
y en especial en los sistemas operativos, donde las posibilidades de elección
del tipo de sistema para el usuario no técnico son muy reducidas, e incluso
son los propios fabricantes y no las necesidades del usuario los que obligan
a cambiar de una versión a otra en una aplicación. Como ejemplo de lo
anterior basta con preguntarse cuántos sistemas operativos conocemos, por
qué tenemos instalado y utilizamos ese sistema operativo y no otro, y si fue
esta nuestra la elección.

Inicialmente la estandarización de aplicaciones informáticas se ha visto


propiciada por los avances en las TIC, especialmente por la red Internet y sus
protocolos y servicios, que han eliminado las barreras físicas y geográficas
permitiendo una sociedad global comunicada de forma colectiva e interactiva.
Pero Internet, que crece y madura conforme aumenta su número de usuarios2,
se acerca de forma pausada, a su filosofía inicial, convirtiéndose en un medio
de comunicación de información, conocimiento y experiencias plural y
diverso, que se aleja de la estandarización y busca una mayor libertad
favoreciendo el desarrollo de importantes avances. Uno de los acontecimientos
más fascinantes se ha producido en el ámbito informático y de desarrollo de

2
Las últimas cifras registradas en agosto del 2004 por el Centro de Predicción Económica
de la Universidad Autónoma de Madrid (CEPERDE) revelan que en el mundo existen más
de 797millones de internautas, lo que supone un incremento del 121% respecto al año 2000,
de los que más de 14 millones de usuarios están en España, aproximadamente el 36 % de la
población del país.

26
OPEN SOURCE Y SOFTWARE LIBRE

aplicaciones con la aparición de la corriente denominada free software u open


source, que merece, como se verá a continuación, una especial atención por cuanto
supone una ruptura con los planteamientos tradicionales de la industria del
software, dominados por el principio de beneficio económico.

2.1.1. ¿QUÉ ES OPEN SOURCE?

A modo de aproximación inicial se puede decir que el término open source hace
referencia a la libre disponibilidad por parte del usuario de un software y de su código
fuente. El código fuente está formado por líneas de instrucciones escritas en un
determinado lenguaje de programación que permiten desarrollar una aplicación o
software y que este ejecute las tareas para las que ha sido creado. Para los que se acercan
al mundo de la informática por primera vez o no dominan aspectos más técnicos
podemos utilizar como símil del código fuente la formula de elaboración de un
medicamento. La importancia de conocer el código fuente no es trivial, pues quien
conozca el código, o fórmula siguiendo con el ejemplo, y disponga de los elementos
técnicos y conocimientos necesarios podrá generar por sí mismo el producto final
software o modificarlo según sus necesidades. Evidentemente, toda organización
empresarial con ánimo de lucro dedicada al desarrollo de aplicaciones guarda y protege
el código fuente de los programas que desarrollan como el mayor de sus tesoros.

Es importante aclarar que open source hace referencia a la libre disponibilidad en


cuanto a utilizar, modificar y distribuir el software y su código fuente y no al coste
o precio de adquisición. Por tanto, es posible encontrar software open source y
software libre que no sea gratis, que presente un precio de adquisición, que de
haberlo es generalmente muy reducido.

Conceptos muy diferentes son los términos free software y Shareware. El primero,
designa un software sin precio de adquisición, gratuito, que el usuario en algunos
casos, y según lo que exprese la licencia del producto, podrá copiar y distribuir,
incluso acceder a su código fuente o modificarlo. El segundo, Shareware, hace
referencia a software o versiones de software que es posible utilizar de forma
gratuita durante un periodo de tiempo, y una vez expirado este, para seguir
utilizando el programa con todas sus funcionalidades es necesario abonar un precio
y aceptar una licencia de uso. En realidad el software Shareware no constituye un
tipo de software, más bien responde a una estrategia promocional del tipo “periodo
de prueba gratuito” y, en ningún caso permite acceso al código fuente ni durante el
periodo promocional ni después del pago.

Con este primer acercamiento al significado de open source, que obviamente no


recoge de forma completa los planteamientos de la citada corriente, se pretende dar

27
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

un punto de partida para poder comprender los siguientes epígrafes en los que se
analizará la evolución cronológica de este movimiento, su filosofía y características
y la expansión espectacular que está teniendo en la actualidad.

2.2. BREVE RESEÑA CRONOLÓGICA


Para entender un fenómeno en su toda su magnitud no basta con tener una
definición del mismo (Yin, 20003), sino que es necesario tener en consideración
cómo y por qué se produce ese fenómeno, así como su evolución en el tiempo. En
este sentido, con la intención de lograr una mayor comprensión de lo que
representa la corriente open source, antes de dar una definición y mostrar sus
principales características, se realizará un breve repaso sobre su desarrollo
cronológico.

2.2.1. PRIMERA ETAPA, ANTECEDENTES

El precedente del open source está en los inicios de la informática moderna.


Entorno a los años sesenta y primeras décadas de los setenta, época en la que la
disponibilidad de equipos informáticos era muy limitada, casi exclusiva de
universidades y centros de investigación financiados generalmente por los
gobiernos. Además, en este periodo las computadoras no disponían de un entorno
tan amigable para el usuario como en la actualidad. No había distinción entre
desarrolladores de aplicaciones o informáticos y usuarios pues eran en realidad la
misma cosa, formando una comunidad reducida.

En este periodo la mayoría del software existente era compartido libremente entre
los usuarios, desarrolladores, con el fin de mejorarlo y avanzar en el desarrollo y
creación de nuevos programas.

2.2.2. SEGUNDA ETAPA, DESARROLLO


A partir de los años ochenta los avances en hardware con equipos más potentes,
pequeños y a menor coste que en periodos anteriores favorece la expansión
intensiva de las computadoras a los puestos de trabajo y hogares. Todo esto
produce un gran aumento de usuarios, cada vez menos técnicos, que favorece el
emergente negocio del desarrollo de aplicaciones, cada vez más fáciles de utilizar.

3
Yin R. (2000). “Case study evaluations: a decade of progress?” En: Evaluation models.
Viewpoints on educational and human services evaluation. Boston. Kluwer Academic
Publishers, 2000.

28
OPEN SOURCE Y SOFTWARE LIBRE

Ante esta situación solo era cuestión de tiempo que el software libre desapareciera
y se implantara el software comercial o Closed Source (código fuente cerrado), que
supone para el usuario adquirir únicamente el derecho a la utilización de las
aplicaciones.

Es este contexto el que en 1984 inspiró a Richard Stallman, miembro del staff del
laboratorio de inteligencia artificial del Instituto de Tecnología de Massachusetts (MIT), a
renunciar a su puesto y dar inicio al proyecto GNU, acrónimo del inglés GNU is not Unix,
con el propósito de crear una comunidad para compartir software de forma libre. Libre en
cuanto a la posibilidad de ver su código fuente, modificarlo y poder distribuirlo con o sin
coste, pero siguiendo la distribución esos mismos principios. Para conseguir ese objetivo, la
primera tarea que se propuso fue desarrollar un sistema operativo completo tipo Unix4 que
siguiera esos criterios de libertad.

En 1985 los componentes del proyecto GNU crearon la Fundación para el Software
Libre, free software Fundation (FSF), organización sin ánimo de lucro creada para
el fomento del software libre que pasa a ocuparse de tareas organizativas y de
distribución de este tipo de software tanto procedente del proyecto GNU como
ajeno. Esta asociación establece la definición de free software, software libre,
indicando que un software para tener esta calificación debe cumplir con cuatro
condiciones, denominadas las cuatro libertades:

1. Libertad para ejecutar el programa con cualquier propósito.


2. Libertad de acceso al código fuente, permitiendo la modificación del
programa según las necesidades del usuario.
3. Libertad para redistribuir copias, tanto gratis como por un canon.
4. Libertad para distribuir versiones modificadas del programa.

2.2.3. TERCERA ETAPA, EXPANSIÓN


La principal dificultad del proyecto GNU para el desarrollo de su sistema operativo
completo era disponer de un núcleo o kernel libre, no comercial. Esto se soluciona
cuando en 1991 Linus Trovalds desarrolló un núcleo libre compatible con Unix que
denominó Linux. Al combinar el sistema GNU con Linux se obtuvo un sistema
operativo libre completo, GNU/LINUX.

4
La intención de hacer el nuevo sistema compatible con Unix fue debida a que “...ese era
el sistema operativo más utilizado y por tanto el ser compatible con dicho sistema
facilitaría el trasvase de usuarios de uno a otro.....”. Stallman, 1999.

29
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En 1993 Ian Murdock da lugar al proyecto Debian como una asociación de


personas, cerca de un millar de desarrolladores voluntarios dispersos por todo el
mundo, que trabajan a través de la Red y hacen causa común para el desarrollo y
distribución de software de forma abierta en la línea de Linux y GNU, dando lugar
al sistema operativo que han denominado Debian GNU/Linux5.

Un hecho crucial para toda la corriente es la creación por parte de esta asociación
del denominado “Contrato social de Debian con la comunidad de software libre”.
El primer borrador de este documento fue elaborado por Bruce Parens en 1997 y en
él se recogen las llamadas directrices de software libre de Debian, formadas por
diez puntos en los que se recoge la filosofía a seguir por el proyecto Debian y que
servirán de base a la futura definición de open source. Esta definición se produce
en febrero de 1998 cuando dentro de la comunidad de software libre un grupo,
formado entre otros por Raymond, E; Parens, B; Peterson, C, crea la open source
Initiative (OSI) que elabora y promueve el uso de la nomenclatura open source. La
OSI, tomando como base las directrices del software libre de Debian y eliminando
las referencias específicas a dicha asociación, establece la definición de open
source que se rige por los siguientes puntos que a continuación se muestran de
forma resumida:

1. Libre redistribución.
2. Acceso al código fuente.
3. Trabajos derivados.
4. Integridad del código fuente del autor.
5. No discriminación contra personas y grupos.
6. No discriminación contra campos de trabajo.
7. Distribución de licencia.
8. La licencia no debe ser específica a un producto.
9. La licencia no debe restringir otro tipo de software.
10. La licencia debe ser tecnológicamente neutral.

Como conclusión a este epígrafe se recoge en la Tabla 2.2 un resumen de los


acontecimientos más importantes dentro del movimiento software libre y open
source.
5
Si bien en la mayoría de ocasiones la utilización de este sistema operativo suele
designarse solo como Linux, la expresión correcta sería GNU/Linux. Linux por si solo es
un núcleo y no un sistema operativo completo.

30
OPEN SOURCE Y SOFTWARE LIBRE

1984 Richard Stallman crea el proyecto GNU.


1985 Los componentes del proyecto GNU crean la FSF (free software
Foundation).
1991 Linux Trovalds desarrolla el Kernel Linux.
1991 Primer sistema operativo libre Linux, combinación de
GNU/LINUX.
1993 Ian Murdock crea el proyecto Debian.
1997 Debian establece el “Contrato social Debian con la comunidad
del Software libre”.
1998 Un grupo de la comunidad Software Libre crea la OSI (open
source Initiative).
1998 Bruce Parents miembro de OSI establece la definición de open
source.
Tabla 2.2 Acontecimientos más importantes dentro del movimiento software libre y open
source

2.3. LA CORRIENTE OPEN SOURCE Y


SOFTWARE LIBRE FILOSOFÍA Y
CARACTERISTICAS
Antes de seguir avanzando en el significado de la denominada corriente open
source es necesario, tanto desde el punto de vista académico o científico como del
educativo, hacer una distinción entre dos vocablos que en la escasa literatura
existente aparecen confusos, unas veces utilizados como sinónimos y otras como
términos distintos para hacer referencia a una misma realidad.

Los términos free software, que en castellano puede traducirse por “software libre”,
donde libre no se refiere al precio sino a la libertad de uso y disponibilidad de una
aplicación y de su código fuente, y open source que tiene por expresión homónima
“código fuente abierto”, son dos formas distintas utilizadas para designar no solo
un tipo particular de software y licencia sino un modo de pensar, una filosofía
distinta en lo referido a producción, distribución y venta de software.

31
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Si bien es cierto que estos términos no son exactamente idénticos ya que cada uno
de ellos tiene su origen en una corriente distinta de un mismo movimiento
(Stallman, 19996), no es menos cierto que son más las coincidencias que los unen
que las diferencias, siendo las propias tendencias las que intentan hacer prevalecer
los matices de su concepto sobre el otro.

GNU y open source dos corrientes de un mismo movimiento

Son numerosos los artículos que circulan por la Red hablando de enfrentamiento
entre las dos corrientes, pero en honor a la verdad y acudiendo a la información que
las propias organizaciones FSF y OSI ofrecen, dicho enfrentamiento no existe, más
bien todo lo contrario, colaboran y participan en distintos proyectos y eventos,
aunque siempre dejando claro que no son organizaciones idénticas.

Sin entrar en profundidades filosóficas, las dos corrientes tienen en común un


aspecto fundamental, la obligación de que su software permita acceso al código
fuente, es decir, que sus aplicaciones sean de código abierto. Su punto clave de
distensión se encuentra en la posición diferente que mantienen respecto de la
distribución del código fuente y de los programas que de él pueden derivarse,
puesto que la FSF establece como condición obligatoria para considerar un
software como libre que dicha aplicación, su código fuente y las aplicaciones que
de él se deriven permanezcan siempre libres, utilizando para ello unas licencias de
software especiales que se estudiarán en el epígrafe siguiente. Por el contrario, la
OSI no establece restricciones y permite que un software con código abierto sea
modificado y posteriormente cerrado. De hecho, a tenor de lo anterior, todo
software libre admitido por la FSF estaría admitido por la OSI como software open
source, sin embargo, no todo el software open source de la OSI es considerado
libre por la FSF.

No se entrará a juzgar cuál de los dos vocablos es el más idóneo para designar en
sentido amplio a todo el movimiento. Pero por ser necesario en aras de la claridad
utilizar uno de los dos, se usará el término open source puesto que, como se ha

6
Stallman, R; Raymond, E. S; Bruce. P; O'Reilly.T et al.: open sources: Voices from the
open source Revolution. Edited by Chris DiBona, Sam Ockman, Mark Stone. (1999).

32
OPEN SOURCE Y SOFTWARE LIBRE

visto, engloba tanto al software open source como al software libre de la FSF y su
uso es más extendido y reconocido en los foros internacionales. Como ejemplo de
la utilización y reconocimiento del termino open source se pueden citar los
siguientes acontecimientos recientes:

— La Unión Europea ha puesto en funcionamiento el 15 de diciembre del año


2003 el open source Observatory dedicado al estudio del fenómeno open
source en el ámbito de la Unión Europea.

— Bajo el título “open source World Conference” se ha celebrado en Málaga


los días 18, 19 y 20 de febrero del año 2004 un congreso7 internacional
para el análisis de la situación mundial del software considerado open
source.

Open source no es solo una definición de un tipo de software sino que representa
todo un movimiento, con una filosofía y formas de trabajar distintas que implican
unas repercusiones tecnológicas, sociales y económicas que requieren de un
análisis detallado que se realizará a continuación.

Open source busca dar la libertad total a los usuarios en la utilización del software,
lo que implica la necesidad de poner a total disposición de estos el código fuente
que en la mayoría de las ocasiones además de ser accesible puede ser copiado,
modificado y redistribuido sin restricciones. Esta filosofía cargada de libertad y
apertura no puede crecer en los tradicionales entornos cerrados y requiere la
búsqueda y definición de nuevos espacios abiertos y colaborativos, que dan lugar a
las denominadas comunidades. Una comunidad es una agrupación de personas que
con independencia de su perfil económico, social, cultural y geográfico presentan
un interés común y de forma voluntaria se incorporan a un grupo, inicialmente
pequeño, que crece en torno a un mismo interés hasta crear una comunidad
organizada. Este fenómeno social de agrupación voluntaria de personas,
generalmente de forma virtual, en torno al desarrollo de software open source
constituye el motor de todo el movimiento. Motor social que se ha visto favorecido
en su desarrollo por la aparición y uso intensivo de Internet, que actúa como
espacio físico en el que estas comunidades se instalan y comunican y como
catalizador del movimiento open source. Es por ello que se reconoce la existencia
de una estrecha vinculación entre Internet y el open source, pues sin una red libre
del tipo de Internet sería imposible el desarrollo de esta tendencia, y sin esta no se
habrían desarrollado numerosos elementos que contribuyen al mantenimiento y
crecimiento de la Red.

7
Congreso que pese al título “open source” contó con la presencia de prestigiosos
representantes de ambas corrientes, free software y open source.

33
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El movimiento open source tiene importantes consecuencias económicas,


relacionadas con las sociales, que repercuten favorablemente en los usuarios. En
primer lugar, altera la forma tradicional de producción de software, puesto que no
hay una organización empresarial con finalidad lucrativa propietaria del software
que se desarrolle, ni se paga una contraprestación económica a los desarrolladores.
El modelo de producción del movimiento open source se basa en la comunidad,
formada por desarrolladores y usuarios cuya finalidad principal es generar y
disponer de un software de calidad, ocupando el lucro una posición marginal, lo
que permite que el precio del software generado sea bajo o nulo.

Un segundo punto a considerar es que el open source supone una anomalía en el


funcionamiento del mercado, debido a que las comunidades, salvo excepciones, no
pueden ser compradas o absorbidas como si de una empresa se tratase; incluso en
el caso de que una comunidad fuera eliminada, según el tipo de licencia que esta
hubiera incorporado en sus programas, estos y los posteriores desarrollos que se
hicieran sobre los mismos seguirían siendo igual de libres.

Por último, open source ha supuesto una apertura del mercado, generando
competencia y reduciendo los efectos negativos de las situaciones próximas al
monopolio, obligando a las empresas a ser más competitivas, lo que se traduce en
ofertar mejores productos a menores precios.

La tendencia monopolística que viene presentando el sector tecnológico de


desarrollo de software en el que unas pocas compañías controlan los productos
existentes en el mercado ha generado un retroceso en la ingeniería del software
debido a:

— El desarrollo de software no se basa en optimizar este, sino en los


adelantos y mayores requerimientos de hardware.

— La aparición de nuevas versiones y mejoras de software se rigen por


criterios económicos y no tecnológicos, y generalmente se producen de
forma dilatada en el tiempo para sacar el mayor rendimiento económico a
cada versión.

La forma de trabajo de open source, con un amplio número de desarrolladores y


usuarios revisando y testando los productos continuamente, favorece que los
avances y mejoras sean rápidas y regidas por criterios de calidad tecnológica.

Los desarrolladores-usuarios pueden colaborar en distintas comunidades y estas


aliarse entre sí para determinados proyectos, que generan colaboraciones y
sinergias desinteresadas económicamente, difíciles de encontrar en el entorno

34
OPEN SOURCE Y SOFTWARE LIBRE

empresarial, y que repercuten en diversidad de enfoques ante un mismo problema


tecnológico. Por último, una cuestión fundamental en el open source es que la
aparición de nuevos productos deriva de los intereses de los usuarios-
desarrolladores, que son quienes dirigen la comunidad.

2.4. LICENCIAS
La comunidad open source y software libre se basan en la búsqueda de la libertad
duradera y permanente del software, pero en una libertad siempre conforme al
derecho y la jurisprudencia y nunca sustentada en la violación de las normas
legales. Es precisamente la normativa jurídica la que permite y ampara que el
software se mantenga libre frente a intentos de apropiación por terceros. Esta
libertad se consigue dotando al software de los correspondientes derechos de autor
y licencias. La licencia, en un lenguaje coloquial, puede definirse como la forma en
la que el autor de una obra, en este caso software, permite el uso y distribución de
su creación por terceras personas de la manera que él considera más oportuna,
siendo por tanto responsabilidad del autor incluir la licencia que especifique de qué
forma puede ser utilizado un programa.

La cuestión de las licencias es uno de los temas más complejos de cuantos rodean
al open source, y ello es debido tanto a la dificultad propia del ámbito jurídico que
supone redactar una licencia sin ambigüedades ni contradicciones, que no entre en
conflicto con la ley y sobre todo que sea sostenible ante los tribunales en caso de
litigio; como a la gran variedad de licencias existentes.

Es práctica habitual y recomendada8 entre los desarrolladores de software libre a la


hora de crear una licencia para el software desarrollado, tomar como base la
licencia libre GPL (General Public License), que posteriormente se analizará, y a
partir de ella si no se está de acuerdo en algún punto modificarlo hasta lograr una
licencia a medida. Buena muestra de lo anterior es la Tabla 2.3, que recoge algunas
de las licencias más habituales.
Para simplificar, el análisis y tratamiento de las licencias de software pueden
clasificar estas según su pertenencia a uno de estos tres grupos:
— Licencias propietarias.
— Licencias libres.
— Licencias semilibres.

8
Esta recomendación se debe a la mencionada complejidad que entraña el desarrollar una
licencia conforme al derecho.

35
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Academic Free License

Apache Software License

Apple Public Source License

Artistic license

Attribution Assurance Licenses

BSD license

Common Public License

GNU General Public License (GPL)

GNU Library or "Lesser" General Public License (LGPL)

IBM Public License

Intel open source License

Jabber open source License

MIT license

Tabla 2.3 Licencias principales open source y Software Libre

2.4.1. LICENCIAS PROPIETARIAS


Son todas aquellas licencias que acompañan al software que no cumple los requisitos
para ser considerado libre o de código abierto por la FSF y la OSI, y se corresponde
con la mayoría del software comercial. Un ejemplo característico es la licencia de
Microsoft. Pese a que el análisis de estas licencias no es el objetivo central de este
apartado, se recogen a continuación una serie de rasgos distintivos de las licencias
propietarias a fin de que el lector pueda con posterioridad comparar con los otros
tipos de licencias. Así, son características genéricas de las licencias propietarias:

— La aceptación a priori de la licencia, es decir, sin dar la posibilidad a


utilización y evaluación del producto.

36
OPEN SOURCE Y SOFTWARE LIBRE

— Prohibición de realizar copias de la aplicación. Con ciertas reservas son


admitidas la realización de copias de los programas informáticos para uso
privado con fines de seguridad, las llamadas copias de seguridad9.
— Prohibición de realizar y distribuir modificaciones de la aplicación.
— Cada licencia permite utilizar el producto en un solo equipo informático.
Un ejemplo aclaratorio de esta cláusula consiste en que un usuario que
adquiere una licencia de una aplicación si tiene dos equipos informáticos
solo podrá utilizar esa licencia en uno de ellos.

2.4.2. LICENCIAS LIBRES


Las licencias libres son el medio legal que tiene la corriente open source y
software libre de garantizar que un software desarrollado como libre se mantenga
como tal en el tiempo.

La variedad de licencias libres, como se ha comentado, es muy amplia, si bien la


base de la gran mayoría de ellas está en la primera licencia libre que se creó: la
GPL10 (General Public License) desarrollada por la FSF (free software Foundation)
que recoge unas condiciones de distribución que impiden que el software libre se
transforme en software propietario mediante la denominada cláusula “Copyleft”.
El término copyleft11 tiene por objetivo preservar el carácter libre de un programa,
prohibiendo que del mismo se obtenga otro no libre o que se redistribuya con
restricciones adicionales. Su principal requerimiento es, en palabras de Stallman,
“cualquier cosa agregada o combinada con un programa bajo copyleft debe ser tal
que la versión combinada total sea también libre y bajo copyleft”.

Algunas de las licencias libres más utilizadas son:

— GPL, ya mencionada, y la GPL-2 segunda versión que respeta el núcleo


central de la licencia inicial, la cláusula Copyleft.

9
Así queda regulado en el artículo 25.3 de la Ley de Propiedad Intelectual RDL 1/1996 de
12 de abril.
10
La figura legal más próxima en España sería la llamada obra colectiva. regulada en los
artículos 8 y 97 de la Ley de Propiedad Intelectual, Real Decreto Legislativo 1/1996 de 12
de abril.
11
Copyleft no es lo contrario de Copyright pues la cláusula Copyleft la impone el autor del
programa original en uso de sus facultades de copyright.

37
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— FDL (Free Document License), licencia que recoge las mismas


condiciones que la GPL pero adaptada al tema de la documentación,
manuales y textos derivados del software libre.
— LGPL (Lesser General Public License), que consiste en una modificación
de la GPL con un carácter menos restrictivo al permitir la creación de
librerías abiertas que puedan incorporarse tanto a programas libres como
propietarios sin obligar a estos últimos a cambiar de licencia.

Las características genéricas de este tipo de licencias con respecto a las licencias de
software propietario son:

— Posibilidad de instalar el software en tantas máquinas como se quiera.


— Aceptación de la licencia a posteriori, utilizada una aplicación el usuario
decide si quiere redistribuirla, siguiendo la licencia inicial y, por tanto,
acatándola.
— Posibilidad de hacer tantas copias como se quiera.
— No restricción en la distribución, incluso mediante venta12.

No obstante, hay que destacar que es en el ámbito de las licencias donde mejor
queda reflejada la distinción entre las dos corrientes, open source y software libre,
puesto que la OSI admite licencias, como la BSD (Berkeley Systmen Distribution),
que añaden determinadas restricciones a los términos de distribución de originales
y de redistribución de programas derivados, al eliminar la obligatoriedad de
mantener el software como libre suprimiendo la cláusula Copyleft. La licencia BSD
tiene como principal característica permitir que un programa libre pueda ser
modificado obteniéndose de él un programa derivado que se cierra, deja de ser libre
su código fuente, cambiando la licencia.

2.4.3. LICENCIAS SEMILIBRES


Un caso especial que refleja lo que son las denominadas licencias semilibres ha
sido la licencia QPL referida al uso de las librerías gráficas QT, caracterizadas por
requerir licencia y pago si se van a utilizar para desarrollos comerciales y
ajustándose a la GPL en los demás casos. Por tanto, no es propietaria en cuanto a

12
Siguiendo los principios de libre mercado la oferta y la demanda mantendrán un coste
bajo o nulo, puesto que si los vendedores obtienen un margen de beneficios elevado
entrarán nuevos vendedores en el mercado y la competencia hará que los precios
disminuyan

38
OPEN SOURCE Y SOFTWARE LIBRE

que da libre acceso al código fuente, siendo posible modificar y distribuir el


programa, pero no es libre en los términos de la FSF al ser necesario pagar licencia
cuando se use en proyectos comerciales.

Para finalizar este apartado se identificarán las licencias a las que están sujetas las
aplicaciones open source que se van a utilizar y desarrollar en los capítulos
siguientes:

— PHP, que es uno de los lenguajes de programación más utilizados por la


comunidad open source adopta su propia licencia, la PHP License 3.0 que
puede ser consultada integramente en (www.php.net/license/3_0.txt) licencia
que tomando como base la licencia BSD presenta una gran libertad en su uso y
redistribución con las únicas limitaciones que pueden resumirse en:

• Indicar en las redistribuciones la nota de copyright y condiciones


de la licencia original.
• No utilizar en los programas derivados el nombre de PHP, ni como
nombre ni con fines publicitarios sin permiso de PHP Group.

— MySQL, considerada la base de datos por excelencia del open source, ha


generado recientemente un pequeño sobresalto entre la comunidad de
código abierto, pues de su licencia inicial, la licencia LGPL que permite
que sus librerías sean utilizadas por programas de código abierto y no
abierto, ha pasado en la versión MySQL 4 a la licencia GPL
(www.mysql.com/products/licensing.html), que obliga a que todo código
que quiera utilizar las librerias oficiales de MySQL deba ser GPL, lo que
suponía romper la compatibilidad con PHP regida por una licencia no GPL.
Finalmente MySQL AB, compañía propietaria de MySQL, ante las
repercusiones que podía tener esta medida ha publicado una excepción13 a
la licencia GPL de MySQL que permite incluir las librerías en otros
proyectos de código abierto que usen licencia distinta a GPL. Esto supone
que permitirá que las librerías de acceso MySQL sean incluidas en PHP 5
como sucedía hasta ahora en PHP 4.

13
La publicación se ha realizado el 12 de marzo del 2004 y puede ser consultada
íntegramente en la siguiente dirección www.mysql.com/products/foss-exception.html

39
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

2.5. SITUACIÓN ACTUAL DEL SOFTWARE


OPEN SOURCE
La historia universal está llena de ejemplos en distintas ramas y campos del saber,
desde los epicúreos en filosofía hasta los planteamientos del comunismo radical en
economía, de movimientos que por sus propios planteamientos utópicos fueron
desapareciendo progresivamente. Pero este no parece ser el caso de la corriente
open source si se analiza la evolución de los datos y cifras relativas al uso y
aplicación del software perteneciente a dicho movimiento y a las comunidades y
proyectos que surgen dentro del mismo.

En el ámbito general, del software open source se conoce principalmente su


sistema operativo más extendido, Linux (GNU/Linux), pero que no se conozcan
otro tipo de aplicaciones no quiere decir que no existan, sino que simplemente por
ser recientes en comparación con la mayoría de aplicaciones cerradas o
propietarias existentes no han adquirido todavía popularidad entre los usuarios.
Esto es lógico, pues no se puede pensar en un cambio radical de un tipo de
aplicaciones a otro sino en un cambio progresivo, fruto en primer lugar del
conocimiento de las alternativas existentes y en segundo lugar de la comparación
entre las mismas.

2.5.1. SOFTWARE OPEN SOURCE, APLICACIONES


PARA TODO
Los movimientos de open source y software libre tienen como finalidad última
evitar la dependencia del software cerrado y para ello buscan dar una cobertura
total a las necesidades de los usuarios mediante software libre. Esto supone
desarrollar todo tipo de software no solo de base o sistema14, sistemas
operativos, sino también de aplicación como procesadores de texto, hojas de
cálculo, compresores, aplicaciones multimedia y herramientas de desarrollo
web.

14
El software de infraestructura, también llamado de base o de sistema, es aquel conjunto
de programas que tienen como misión facilitar el uso del ordenador por parte de los
usuarios. Entre sus funciones están comunicar la computadora con sus periféricos,
asignándolos y administrándolos y actuar como intermediario entre el hardware y el
software de aplicación. Este tipo de software suele dividirse en sistema operativo y
programas de utilidades.

40
OPEN SOURCE Y SOFTWARE LIBRE

Software open source de sistema


En primer lugar hay que recordar que el software de sistema hace referencia
principalmente al sistema operativo y matizar que este está formado por dos partes,
un kernel o núcleo y a un conjunto de utilidades y programas básicos que unidos al
núcleo forman un entorno completo.

Existen distintos sistemas operativos open source a parte de Linux como FreeBSD
(www.freebsd.org), caracterizado por proporcionar servicios de red robustos con
una excelente gestión de memoria y un alto rendimiento en los accesos a disco y
librerías compartidas que reducen el tamaño de los programas, OpenBSD
(www.openbsd.org) sistema operativo que concentra sus esfuerzos en la seguridad
y la portabilidad, GNU/HURD (http://hurd.es.gnu.org), novedoso sistema basado
en un conjunto de servidores, que se ejecutan sobre un microkernel formando la
parte del sistema operativo que sustituye al núcleo tradicional. Pero como ya se ha
comentado en apartados anteriores el sistema operativo open source por excelencia
es el que generalmente se denomina como LINUX, basado en el núcleo o kernel
Linux más las librerías y utilidades GNU. En la actualidad son numerosas las
variantes de distribuciones, comerciales y no comerciales, de sistemas
operativos basados en Linux (GNU/Linux) pero con distintas utilidades y
complementos alcanzando un elevado grado de especialización. A continuación
se recogen las distribuciones más destacadas:

Comerciales

— RedHat (www.redhat.es), es la distribución Linux más extendida, está


orientada principalmente a empresas y acompaña sus distribuciones con
atención y soporte al usuario junto con una amplia documentación.
— Mandrake, (www.mandrakelinux.com), basada inicialmente en Redhat,
pero con una orientación al usuario medio. Es sencilla de instalar y consta
de asistentes y ayudas visualmente atractivas.
— United Linux (www.unitedlinux.com), distribución fruto de la colaboración
de cuatro empresas Conectiva S.A., SCO Group, SuSElinux AG y
Turbolinux, Inc. que tienen por objetivo el desarrollo de un sistema
operativo Linux estandarizado, que actúe como distribución base a partir de
la cual cada empresa añada y comercialice las utilidades y mejoras propias.

No comerciales

— Debian (www.debian.org), Debian GNU/Linux es junto con Redhat la


distribución de uso más extendido. Desde el punto de vista técnico sus

41
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

controles son muy rigurosos y es considerada la distribución Linux más


estable. Las aplicaciones tienen su propio formato “.deb” y un cómodo
instalador “apt”. La distribución completa consta de más de 8.000 paquetes
con utilidades y aplicaciones de todo tipo: programas matemáticos,
grabadores de CD, editores de imágenes, etc. Desde su origen es una
distribución creada y mantenida por los usuarios, su licencia es GPL y es
una distribución apoyada públicamente por la FSF y el proyecto GNU.
— LinEx (www.linex.org), distribución gratuita, incluido el soporte y atención
al usuario, desarrollada y promovida por la administración autonómica de
Extremadura. Su desarrollo se basa en la distribución GNU/Debian de la
que hereda sus ventajas, con una gran variedad de software que permite
cubrir todas las necesidades de un usuario medio con software libre, e
intenta eliminar algunos de sus inconvenientes, facilitando al máximo la
instalación15.
— Guadalinex (www.guadalinex.org), distribución gratuita desarrollada por
la administración autonómica de Andalucía fruto de la colaboración
establecida con la junta de Extremadura destinada a dar cumplimiento al
Decreto 72/2003, en el que la Junta de Andalucía opta por el software libre
como instrumento para el impulso de la Sociedad del Conocimiento en
Andalucía. Guadalinex se desarrolla a partir de Linex de forma que LinEx
y Guadalinex ofrecen sus funcionalidades con las mismas aplicaciones
mantenidas en un mismo repositorio y por un único equipo de control de
calidad, diferenciándose en los programas y contenidos que sean de interés
solo en una de las dos comunidades.
— Knoppix, distribución GNU/Linux alemana totalmente gratuita y basada en
Debian que presenta como ventaja el no necesitar instalación, puesto que
permite arrancar desde el CD que puede ser descargado desde Internet
(www.cylnux.org) y Slackware (www.eslack.org). Es una de las más
antiguas y conocidas distribuciones GNU/Linux gratuitas que destacan por
su facilidad de instalación y estabilidad.

Software open source de aplicación


El software de aplicación fue en un principio el gran olvidado de los
desarrolladores open source, centrados casi de forma exclusiva en la búsqueda de
sistemas operativos libres. En la actualidad, superado ese primer estadio de crear
una base libre, si bien las comunidades siguen trabajando en el desarrollo y mejora
de los sistemas operativos, es el ámbito del software de aplicación el que está
15
La distribución Linex ha sido reconocida dentro del apartado Linux, con el premio a la
mejor distribución de 2003 por la empresa Softonic

42
OPEN SOURCE Y SOFTWARE LIBRE

despertando un gran interés entre la comunidad open source que se ha lanzado a la


búsqueda de aplicaciones libres con la calidad necesaria para sustituir a las
comerciales.

La oferta de software open source de aplicación es amplia y abarca desde suites


ofimáticas y aplicaciones de gestión empresarial hasta gestores de correo y
aplicaciones multimedia. Establecer una enumeración de todas las aplicaciones
existentes sería complicado tanto por el número como por la poca calidad de
muchas de ellas que han comenzado a desarrollarse recientemente y requerirán un
tiempo de maduración; sin embargo, sí se podría indicar dentro de cada tipo
aplicaciones ya contrastadas que, por supuesto, siguen mejorándose. Así, dentro de
la ofimática destaca el paquete OpenOffice (www.openoffice.org), suite ofimática
gratis y compatible con distintos sistemas operativos y diferentes arquitecturas.
Está compuesto por hoja de cálculo, procesador de texto, editor de fórmulas, editor
de presentaciones, etc., por tanto tiene todas las funcionalidades de Microsoft
Office, con el que es totalmente compatible y además incorpora otras propias como
la posibilidad de exportar documentos de texto a otros formatos como Pdf, Flash,
XML, etc.

En el desarrollo de software de gestión empresarial los avances hechos públicos son


menores que en el resto de actividades, posiblemente por el recelo y desconfianza
que todavía muestra el ámbito empresarial hacia herramientas que son consideradas
de dominio público pero, que analizando la situación real con detenimiento, son
prácticamente igual de accesibles para la competencia que los productos licenciados
de pago, con la ventaja de un menor coste o incluso ser gratuitas. Hoy en día no tiene
sentido pensar que una empresa es la única que utiliza en exclusiva una aplicación,
salvo determinadas aplicaciones realizadas a medida, es más, en el mundo
empresarial la dificultad no está en el acceso a la tecnología o a un programa
concreto, sino en sacar el máximo rendimiento de su uso.

Algunas aplicaciones empresariales que podrían citarse son:

— FacturLinEx y ContaLinEx (www.gnulinex.net), herramientas de gestión


liberadas y de acceso gratuito desarrolladas y cedidas por el gobierno de
Extremadura.
— Fisterra (www.fisterra.org), herramienta ERP (Enterprise Resource Planning),
que nació como aplicación empresarial a medida, de pago y con código cerrado
y posteriormente se liberó su código bajo licencia GPL, ofreciéndose de forma
gratuita.

43
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— FacturaLUX (www.facturalux.org), que pretende ser un software ERP creado


con software de código abierto que permita la gestión integral de la empresa.

En cuanto a gestores de correo, como alternativas al omnipresente Microsoft


Outlook, se tienen varias opciones, las más reconocidas Evolution y Mozilla
Thunderbird, anteriormente conocido como Mozilla mail, que es el cliente de
correo del proyecto Mozilla. (www.mozilla.org).

Por último, en lo que se refiere a las aplicaciones multimedia, verdadera revolución del
software, que permiten entre otras cosas ver y escuchar audio y video, tratamiento de
imágenes, etc. también existen aplicaciones abiertas capaces de hacer sombra a los
productos de código cerrado. Como principales ejemplos, en la Tabla 2.4 se recoge
para cada software de código cerrado un posible homólogo open source.

Cerrado Abierto Dirección


MSN Messenger AMSN http://amsn.sourceforge.net/
MSN Netmeeting GnomeMeeting www.gnomemeeting.org
WinAmp XmmS www.xmms.org
Winzip Gzip, zip www.gnu.org/software/gzip/gzip.html
Windows Media Player Mplayer, Xine www.mplayerhg.hu
Photoshop Gimp www.gimp.org
Acrobat Reader Gpdf www.purl.org/net/gpdf
ACDSEE GThumb http://gthumb.sourceforge.net

Tabla 2.4 Aplicaciones open source

Los últimos proyectos open source que mayor interés han despertado entre la
comunidad son KDE y Gnome, orientados a dotar al usuario de un escritorio
intuitivo y amigable desarrollado con software totalmente libre:

— KDE, (The K Desktop Enviroment www.kde.org), es el entorno gráfico


desarrollado en C++ que ha constituido el escritorio tradicional en los sistemas
Unix. Este desarrollo ha pasado por dos etapas muy distintas. Una inicial, desde los
comienzos del proyecto, en octubre de 1996, hasta octubre de 2000 con licencia no
libre en sus librerías QT, lo que generó el rechazo por parte de la comunidad open
source, y la actual, a partir de octubre del 2000, con la versión KDE 2.0 en la que
todo el desarrollo es software open source bajo licencia GPL.
— Gnome, (Gnu Network Object Model Environment www.gnome.org), surge
como proyecto liderado por Miguel de Icaza y Federico Mena dentro de GNU

44
OPEN SOURCE Y SOFTWARE LIBRE

en respuesta al desarrollo no libre de KDE con el objetivo de dotar al software


GNU de un escritorio libre. El proyecto está muy evolucionado y en realidad
no es solo un escritorio puesto que integra distintas aplicaciones ofimáticas.

Recientemente la empresa Novell ha anunciado que dos de sus divisiones Ximian y


SuSE, trabajarán juntas para crear un escritorio Linux común, con las mejores
características de GNOME y KDE .

Herramientas de desarrollo Web


Es sin duda en el área del desarrollo web donde la corriente open source ha alcanzado un
protagonismo indiscutible con alternativas para todos los elementos que intervienen en
dicho desarrollo y aplicaciones que cubren todas las fases del desarrollo web:
— Servidores web.
— Bases de datos.
— Lenguajes de programación
— Herramientas de desarrollo o gestores de contenido.

De tal forma que cualquier desarrollo web puede llevarse a cabo por completo
mediante la utilización de herramientas open source.

Los servidores web son programas que instalados en equipos conectados a una red,
principalmente Internet, permiten que dichos equipos puedan recibir peticiones http
de otros ordenadores y satisfacerlas sirviendo páginas web.

Algunos de los servidores web open source más conocidos son: Apache, AOL
Server, Roxen y Thttpd, de los cuales el servidor Apache es el que tiene mayor
presencia en Internet, tal como puede apreciarse en la Tabla 2.5.

Servidores Número Porcentaje


Apache 38.028.642 69,73%
Microsoft-IIS 11.923.178 21,86%
Netscape-Enterprise 1.743.421 3,20%
Zeus 739.006 1,36%
Rapidsite 369.532 0,68%
Tigershark 246.962 0,45%
Thttpd 221.446 0,41%
OTROS 1.266.961 2,32%
TOTAL 54.539.148 100%

Tabla 2.5 Servidores activos en Internet en más de 5.000 sitios (noviembre 2004).
Elaboración propia a partir de datos ofrecidos por la consultora de Información Netcraft

45
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El servidor Apache, desarrollado por más de cien desarrolladores voluntarios


dentro del proyecto Apache, gestionado por la Fundación Apache, The Apache
Software Foundation (www.apache.org), es el servidor web más utilizado en el
mundo y esto es debido a sus características: robustez, rapidez, ser multiplataforma
con versiones para Linux, Win32, MacOs, Unix, modularizable, dispone de
módulos para ejecutar PHP, Perl, etc.

En cuanto a las aplicaciones gestoras de bases de datos, son numerosos los


ejemplos que siguen la corriente open source: MySQL, Postgrade, Sap DB,
Interbase Borland,... de las cuales, merece especial mención MySQL, que presenta
como características destacadas su carácter multiplataforma, una buena integración
con PHP, licencia GPL que garantiza su libertad, gran velocidad y estabilidad.

En una encuesta sobre desarrollo de bases de datos realizada por Evans Data
Corporation en enero del 2004, se puso de manifiesto que SQL Server y Access
continúan dominando el desarrollo de bases de datos, pero las bases de datos open
source están ganando terreno. El uso de SQL Server y Access había crecido casi un
6%, mientras que el uso de MySQL se había incrementado más del 30% en los seis
meses anteriores a la realización de la encuesta.

Los lenguajes de programación son las herramientas básicas utilizadas por los
desarrolladores para crear aplicaciones web. Dentro del desarrollo web la
comunidad open source parece mostrar sus predilección por el lenguaje PHP.
Aunque no se va a profundizar en este apartado en este lenguaje, por ser objeto de
estudio de los próximos capítulos, sí se puede adelantar que se trata de un lenguaje
interpretado especialmente diseñado para embeber su código en el HTML de las
páginas web y especial facilidad para interactuar con bases de datos.

Los sistemas gestores de contenido, más conocidos como CMS (Content


Management Systems) son aplicaciones desarrolladas para facilitar la creación
y gestión de portales en Internet. Estas herramientas, que serán estudiadas con
más detalle en el Capítulo 18, han alcanzado una gran difusión debido a su
simplicidad de uso y potencia de desarrollo; basan su funcionamiento en tres
elementos fundamentales: una base de datos, por ejemplo MySQL, un servidor
web como Apache y un lenguaje de programación que permita la interacción
con la base de datos como por ejemplo PHP. Ejemplos de gestores de contenido
son PHPNuke, Postnuke, Drupal,... En el Capítulo 18 se darán referencias a
estos productos y otro tipo de herramientas de desarrollo web basadas en PHP y
MySQL.

46
OPEN SOURCE Y SOFTWARE LIBRE

2.5.2. COMUNIDADES OPEN SOURCE


Las comunidades, como agrupación voluntaria de personas con intereses
comunes representan y son una muestra del espíritu de colaboración y libertad
de la corriente open source y en ellas generalmente usuarios y desarrolladores
llegan a ser la misma cosa. Las comunidades y sus miembros son el verdadero
alma del open source, las comunidades actúan como centro de trabajo y los
miembros de la comunidad, técnicos o no, son la fuerza productiva del software
abierto, unos de forma directa si tienen los conocimientos y medios técnicos
participando directamente en el desarrollo de las aplicaciones, y otros testando
y experimentando con los programas, comunicando cualquier incidencia o
sugiriendo vías de mejora. Las comunidades, como centros de trabajo, ofrecen
el entorno necesario para el trabajo en grupo orientado al desarrollo y mejora de
software open source, facilitando para ello una serie de servicios. Entre los
elementos o servicios comunes que presentan estas comunidades se pueden
citar:

— CVS (Concurrent Versions System) sistema de control de versiones, son


aplicaciones que utilizando una arquitectura cliente-servidor, facilitan la
gestión y trabajo simultáneo sobre el código mediante repositorios o bases
de datos que mantienen un histórico de los códigos fuente, almacenando
solo las diferencias entre versiones.
— Listas de discusión y foros como elementos de comunicación.
— Seguimiento de errores.
— Copias de seguridad.

En su origen las comunidades nacían del espíritu de colaboración de usuarios y


desarrolladores independientes en la búsqueda de software libre y de calidad. Eran
comunidades creadas y mantenidas por los usuarios. Con el tiempo el número de
comunidades open source se ha incrementado notablemente, en gran medida
debido al apoyo y soporte económico recibido de grandes empresas como IBM a la
comunidad Eclipse y Compaq a Sourceforge, por ejemplo.

Las comunidades organizan su trabajo en proyectos, cada proyecto se corresponde


generalmente con el desarrollo y mejora de una aplicación concreta, tarea realizada
por los usuarios de la comunidad que de forma libre deciden participar en uno o
varios proyectos.

Intentar enumerar las comunidades sería además de imposible, pues continuamente


aparecen nuevas iniciativas, injusto, pues se corre el riesgo de no mencionar a

47
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

todas. No obstante, tomando como criterios la tradición y años de trabajo, los


proyectos desarrollados y en vías de desarrollo y los usuarios (véase Tabla 2.6)
destacan especialmente dos comunidades:

— Sourceforge (http://sourceforge.net/)
— Savannah (http://savannah.gnu.org/)

Comunidad Proyectos Usuarios


registrados
SourceForge 90.625 952.696
Savannah 2.176 31.392

Tabla 2.6 Proyectos activos y usuarios registrados de dos de las comunidades open
source más importantes a fecha de noviembre de 2004. Fuente: Web de las propias
comunidades

2.5.3. USUARIOS DE SOFTWARE OPEN SOURCE


Todas las organizaciones, tanto públicas como privadas, se rigen en su gestión por
la búsqueda de la eficacia y eficiencia, unas para satisfacción de los ciudadanos y
otras de sus accionistas y stakeholders. En este sentido, el software open source no
ha pasado desapercibido para dichas organizaciones por sus beneficios tanto
técnicos como económicos. En el siguiente epígrafe se muestran distintas
referencias de utilización del software open source en distintas administraciones
públicas y privadas.

Open source y la Administración Pública

Las iniciativas gubernamentales a favor del software open source se han producido
en todas las partes del mundo, desde Asia, donde el gobierno de una de las mayores
potencias tecnológicas del mundo, la República Popular China, ha establecido
disposiciones legales a favor del uso de software open source para los servidores
públicos, o Taiwán dónde las previsiones son ahorrar 300 millones de dólares en
pago de licencias a Microsoft, gracias a un programa de desarrollo y adopción de
software open source en toda la administración estatal. Hasta el gobierno de
Estados Unidos, que si bien no ha legislado a favor del software open source sí lo

48
OPEN SOURCE Y SOFTWARE LIBRE

utiliza, ejemplo claro es el sitio web de la Casa Blanca16 soportado con sistema
operativo Linux y servidor web Apache. Y latinoamérica, con países como Perú y
Chile en los que se han sucedido las propuestas de leyes que obliguen al uso
exclusivo de software open source en la administración pública.

En Europa las iniciativas no se han quedado atrás a la hora de apostar por el open
source, ejemplos claros son la administración alemana que en junio del 2002
anunció la migración de sus sistemas a Linux, o Noruega país que decidió no
renovar las licencias de Microsoft e invertir en favor del software libre.

En el caso español, si bien no se han producido hasta el momento iniciativas a nivel


estatal17, sí pueden encontrarse ejemplos en distintos gobiernos autonómicos y
municipales. Destaca especialmente el caso de la Junta de Extremadura, entidad
pionera de la introducción de software libre en la administración pública española,
que rescindió sus licencias de sistema operativo pertenecientes a Microsoft y ha
desarrollado un sistema operativo propio, GNU/LINEX (www.linex.org), lo que ha
servido de ejemplo a otras comunidades como la andaluza, que ha desarrollado el
sistema Guadalinux (www.guadalinex.org), o la Generalitat Valenciana, que ha
comunicado su intención de migrar todas las aplicaciones utilizadas por sus
organismos hacia el software libre.

Open source y la empresa privada


En cuanto a las empresas privadas, caracterizadas tradicionalmente por el principio
de maximizar los beneficios para los accionistas, que se puede traducir en apostar
solo por aquellas inversiones capaces de generar beneficios futuros, la penetración
del open source es muy superior a la de las administraciones públicas. La
implantación del software open source en las organizaciones empresariales se ha
concentrado de forma inicial en grandes empresas y multinacionales, que hay que
recordar son siempre las pioneras en innovación y desarrollo y paulatinamente se
van incorporando las pequeñas y medianas empresas que, como en otras
circunstancias similares de innovación, suelen ir un paso por detrás de las grandes
compañías. El despegue e implantación del open source en las pymes se producirá
en un futuro no muy lejano.

16
Información tomada de Netcraft, empresa britanica de servicios de Internet reconocida
internacionalmente por sus estudios sobre la Red.
17
La única iniciativa con carácter estatal ha sido una Proposición de Ley para promocionar
el uso del software libre en la Administración del estado en general y en las
administraciones autonómicas en particular, presentada por el Grupo Mixto y debatida en el
Congreso de los Diputados el 24-09-2002, sesión plenaria número 181, donde fue
rechazada.

49
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Como ejemplos de multinacionales y grandes empresas de distintos sectores


económicos que han confiado e invertido en el software open source se recogen las
siguientes:

Sector tecnológico e informático:

— Oracle, ha realizado la migración de sus aplicaciones de negocio de Unix a


un cluster de máquinas Intel bajo Linux.
— IBM, desde el año 2001 ha realizado inversiones superiores a 1.000
millones de dólares en Linux y utiliza Apache en su aplicación de
comercio electrónico WebSphere, además de mantener una colaboración
muy activa con la comunidad open source Eclipse como estrategia y
apuesta de futuro.
— Hewlett-Packard/Compaq y Sun Microsystems, mantienen y dan soporte a
distintas comunidades open source como opensource.compaq.com, en el
caso de la primera, y sunsource.net, en el caso de la segunda.

Sector ventas y distribución:

— Toyota Motor Sales Usa, eligió Linux como sistema operativo de su red de
1.200 servidores.
— Amazon, basa sus sistemas en la utilización de servidores Apache sobre
Linux.

Media y comunicación:

— Walt Disney Feature Animation, utiliza Linux en sus proyectos.


— El País, basa sus sistemas en Apache, PHP4 y Linux.
— El prestigioso grupo editor Forbes presenta como base de sus plataformas
Linux y Apache y contribuye activamente con el open source Software
Institute (www.oss-institute.org)

Financiero:

— Morgan Stanley, prestigiosa firma financiera, utiliza como sistema


operativo Linux.
— El Banco Herrero, se sirve de Linux sobre un servidor Apache.
— El Banco Sabadell pasó del sistema operativo Solaris 8 sobre
Netscape/Enterprise 4.1 a Linux corriendo sobre un servidor Apache

50
OPEN SOURCE Y SOFTWARE LIBRE

2.6. VENTAJAS, INCONVENIENTES Y


PERSPECTIVAS DE FUTURO
A lo largo de este capítulo se han dejado entre ver algunas de las ventajas del
software open source, poco se ha hablado de los inconvenientes que puede tener y
del futuro que puede esperar al software desarrollado bajo los principios del código
abierto.

2.6.1. VENTAJAS
Se enumeran a continuación algunas de las ventajas que proporciona el software
open source, destacando que, si bien las económicas18 son las más visibles, hay
otras ventajas importantes:

— Ahorro de costes, las distribuciones de software open source son


generalmente gratuitas o a un coste muy bajo, teniendo en cuenta que con
sus licencias dan al usuario libertad para hacer con la aplicación las
modificaciones o distribuciones que consideren oportunas sin ningún coste
añadido.
— El código de los programas es abierto y por tanto no depende de una sola
empresa desarrolladora ni de su política y permite total flexibilidad para
adaptar el programa a las necesidades de los usuarios.
— Mayor calidad y seguridad en los programas. Esto es debido tanto a que el
código sea libre como a la metodología de trabajo de las comunidades, que
permite que un elevado número de programadores pueda revisar y trabajar
simultáneamente sobre un mismo código, detectando errores que de otra
manera serían difíciles de detectar.
— Reactiva la competencia en un mercado con tendencias monopolísticas.
— Rapidez de desarrollo, la evolución19 y lanzamiento de versiones
mejoradas en el software open source es muy superior al software cerrado.

18
Beneficios que no solo se deben cuantificar como diferencia entre, el pago actual por las
licencias de software y el que se pagaría, en caso de ser necesario, al utilizar software open
source, pues hay otras cuestiones como ahorro en costes de actualizaciones, estabilidad del
sistema que repercute en la productividad, etc.
19
Atendiendo al estudio de IBM que se puede obtener integro en:
http://www-1.ibm.com/linux/LinuxInSight.pdf, Linux es el sistema operativo que más
rápido ha evolucionado en la historia de la ingeniería de software.

51
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— Escucha activa a los usuarios y retroalimentación entre la producción del


software, desarrolladores, y los usuarios mediante una relación directa y de
colaboración.

2.6.2. INCONVENIENTES
Por supuesto no todo son ventajas, la utilización de este tipo de software puede
tener sus inconvenientes:

— Dificultad en cambiar o dejar de utilizar determinadas aplicaciones de


software cerrado que se han convertido en un estándar.
— La utilización de software open source no es la mejor opción para
determinadas empresas que basen su negocio en algoritmos secretos o
patentados.
— La utilización de aplicaciones open source generalmente requiere, tanto
para el usuario doméstico como para el personal de empresas, un proceso
de adaptación y formación, no porque las herramientas open source sean
más complicadas sino simplemente debido a que los usuarios nunca han
trabajado con ellas.
— Existencia de proyectos de desarrollo y comunidades en algunos casos sin
estructuras jerárquicas ni organizativas claras que dan al usuario sensación
de desorganización.
— Dentro del movimiento hay algunas comunidades con una tendencia
excesiva a la búsqueda del elitismo que aleja al usuario domestico no
técnico.

2.6.3. PERSPECTIVAS DE FUTURO


A modo de conclusión de este capítulo dedicado al estudio del movimiento open
source y software libre y todo lo que con ellos está relacionado se desea apuntar
tres ideas finales.

Hablar de open source es más que hablar de software gratis o de disponer de un


código fuente. Supone una nueva forma de producir, desarrollar y distribuir
software en la que el usuario, las comunidades e Internet adquieren un papel
protagonista.

52
OPEN SOURCE Y SOFTWARE LIBRE

El continuo incremento de usuarios públicos y privados, de comunidades de


desarrollo y de mejoras técnicas afianzan que la corriente open source no es una
moda pasajera dentro del desarrollo del software. Más aún, predicen y hacen
aventurar que su verdadero esplendor está por llegar, siendo indicativo de esto
mismo la creación del “Observatorio del software de fuente abierta” por parte de
la Unión Europea para estudiar este fenómeno en los actuales y futuros estados
miembros y la elaboración desde la UNESCO de un programa de actuaciones en
apoyo del software libre.

Por último, las voces más optimistas predicen en artículos y comentarios la rápida
desaparición de las compañías de software cerrado. Desde aquí, manifestar que
aunque la situación actual parece indicar que se producirá un importante cambio en
el ámbito del software, estas compañías no tienen porqué desaparecer, aunque sí
posiblemente reorientar su núcleo de actividad de la producción de software hacia
la prestación de servicios de valor añadido. No obstante, en ningún caso se puede
pensar que este cambio ocurra de un día para otro sino que, como en todo periodo
de transformación, será fruto de un proceso continuo que comienza ahora a
caminar con paso firme.

53
CREACIÓN DE PÁGINAS
WEB MEDIANTE EL
LENGUAJE HTML

3.1. INTRODUCCIÓN
En el primer capítulo, en el que se ha sido analizado el funcionamiento del servicio
web, se explicó que Internet utiliza para la transferencia de información entre clientes y
servidores el protocolo HTTP (HiperText Transfer Protocol), protocolo de
transferencia de hipertexto. Este protocolo establece los requisitos que se deben
cumplir para la transferencia de la información, y exige que la información a transferir
sea definida mediante un sistema estándar, comprensible para cualquier equipo. Con la
intención de satisfacer esta necesidad se desarrolló un lenguaje de definición de
hipertextos, el conocido actualmente como HTML. En este capítulo se analizará dicho
lenguaje y su sintaxis desde un punto de vista práctico, mediante pequeños ejemplos.

El objetivo que persigue este capítulo introductorio es situar al lector en las


condiciones mínimas necesarias para poder desarrollar un sitio web y dotarle
posteriormente de diversas funcionalidades mediante el uso de PHP y MySQL. Por
supuesto, no se pretende hacer una presentación exhaustiva del lenguaje, simplemente

55
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

se mostrará el proceso de construcción de un sencillo sitio web, tomando como


referencia lo que podría ser el objetivo de una empresa ficticia, a la que se denominará
Cinem@s. Esta empresa ficticia pertenece al sector del entretenimiento y dispone de un
multicine, el objetivo final que persigue es ofrecer a sus clientes un cómodo servicio de
información y reserva de localidades a través de Internet. El primer paso para ello será
la creación de unas sencillas páginas web de presentación, en torno a las cuales se
desarrollará posteriormente la aplicación web deseada.

La Figura 3.1 muestra la página web de inicio de Cinem@s, el proceso de creación


de está página será explicado a lo largo del capítulo, y contendrá enlaces a otras
páginas que se desarrollarán en la segunda parte del libro para implementar el
sistema de consulta y compra de localidades.

Figura 3.1 Página de inicio de Cinem@s

56
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

3.1.1. DEFINICIÓN DE HTML

Las definiciones existentes de HTML son múltiples y más o menos complejas. Una
definición sencilla y de marcado carácter práctico es la que se propone a
continuación:

HTML es un lenguaje de descripción de hipertexto compuesto por una serie


de comandos, marcas, o etiquetas, también denominadas “Tags” que
permiten definir la estructura lógica de un documento web y establecer los
atributos del mismo (color del texto, contenidos multimedia, hipervínculos,
etc...).
En resumen, es un lenguaje que permite crear páginas web y para ello utiliza unos
comandos o etiquetas que indican o marcan qué se debe mostrar y de qué forma.

Los comandos siempre van incluidos entre los signos < > e insertados en el propio
texto que compone el contenido de la página. Especifican su estructura (las
distintas partes de la página) y formato. Además, permiten la inserción de
contenidos especiales como imágenes, videos, sonidos, etc.

Ejemplo 3.1:
Un primer ejemplo sencillo de creación de una página web, puede ser realizado
utilizando un simple editor de texto, por ejemplo el bloc de notas de Windows.

Si se escribe el código:

<H1> Primer ejemplo de página web </H1>


realizado con <B> HTML y el bloc de notas.</B>

y se guarda el documento con un nombre con extensión .htm o .html, ya se


habrá creado una primera página web. Dicho documento abierto desde el
navegador genera una página como la que se puede ver en la Figura 3.2.

Toda página web debe ser guardada en un documento de texto con la


NOTA extensión .htm o .html..

Si se analiza detalladamente el código HTML que ha producido esta página puede


verse cómo los diferentes comandos van señalando los diferentes elementos de la

57
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

página. Por ejemplo, los comandos <H1> y </H1> señalan el inicio y el fin,
respectivamente, del texto que se mostrará con formato de título: “Primer ejemplo
de página web”. De la misma manera, los comandos <B> y </B> encierran el
texto que se mostrará en negrita.

Figura 3.2 Primera página web

Toda página web desarrollada con HTML oculta un documento de texto sin
formato, texto ASCII, que incorpora todas las instrucciones o etiquetas del lenguaje
HTML necesarias para conseguir que la página tenga la apariencia que se visualiza
en el navegador. Este documento de texto que aparece oculto al usuario final, es lo
que se denomina código fuente de la página. Las herramientas de navegación web
permiten la consulta de ese código fuente; por ejemplo, Internet Explorer dispone
de la opción Código fuente del menú Ver.

3.2. HISTORIA DE HTML


El nacimiento y desarrollo del lenguaje HTML no fue algo casual y espontáneo.
Desde el comienzo de la utilización de las primeras redes de ordenadores por parte
de las grandes empresas y organismos científicos y militares surge la preocupación
por desarrollar un sistema que permita la edición estructurada de documentos, de
forma que se evite la disparidad de formatos y a la vez se facilite el intercambio de
los mismos.

58
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

El antecedente más remoto de HTML se encuentra en el lenguaje de marcado


generalizado, GML, desarrollado por Charles Goldfarb, Ed Mosher y Ray Lorie
dentro de IBM, en los primeros años de la década de los setenta con el objetivo de
dotar de un formato común a los documentos de la empresa con independencia de
su tipo. Este lenguaje fue posteriormente mejorado por sus creadores dando lugar
a la primera tecnología de información estandarizada y estructurada: el lenguaje
de marcado generalizado estándar, SGML, que en 1986 es aceptado por la
Organización Internacional de Estandarización (ISO), como un estándar. A pesar
de esto, no se consiguió evitar una elevada complejidad para el usuario final, que
unido a un alto coste impidió que dicho lenguaje se convirtiera en un estándar
aceptado, aunque sí sentó las bases de lo que sería posteriormente HTML.

El salto cualitativo se produce en 1989 cuando Tim Berners-Lee y Anders


Berglund, investigadores del Laboratorio Europeo de Física de Partículas (CERN),
crearon un lenguaje basado en etiquetas para editar documentos con el fin de
compartirlos entre diferentes equipos de investigación que trabajaban para el
CERN. Esta aplicación simplificada del SGML se llamó HTML, lenguaje de
marcas de hipertexto, y se convirtió por su simplicidad en el primer formato de
información estándar de Internet, dando lugar a la aparición del servicio más
popular de la red: el servicio web. El lenguaje HTML ha ido evolucionando
mediante distintas versiones, desde la HTML 2.0 de 1994, hasta la actual,
adaptando el lenguaje en cada momento a las necesidades y características de los
usuarios de Internet, pasando, desde la transferencia de documentos de texto plano,
a la incorporación de posibilidades multimedia (imágenes, vídeo, Flash, applets de
Java), de dinamismo (HTML Dinámico), de presentación (CSS) y de operatividad
(CGI, ASP, JSP, PHP,...) que no estaban presentes en un principio. Cambios y
modificaciones no siempre realizados de forma coordinada, como ejemplo claro la
implementación de distintas etiquetas y extensiones del lenguaje en función del
navegador, lo que provoca que en ocasiones una misma página no se visualice de
igual forma en todos los navegadores.

Con la intención de solucionar estos problemas se creó en 1996 el consorcio W3C


(www.w3.org), formado por más de 350 organizaciones, entre las que se
encuentran las principales empresas del sector: Microsoft, Netscape,... y distintos
organismos públicos internacionales como el MIT, INRIA,... con el propósito de
promover el crecimiento de la Web, desarrollando especificaciones y software de
referencia disponibles para todos los usuarios sin coste alguno. La tarea principal
del W3C es la de recomendar a las empresas y desarrolladores interesados en la
Web una serie de pautas sobre cómo deben implementarse los diferentes lenguajes
(HTML, CSS, XML, etc.) y tecnologías.

59
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

3.3. SOFTWARE NECESARIO PARA


TRABAJAR CON HTML
Trabajar con un lenguaje siempre conlleva la necesidad de utilizar herramientas
informáticas, generalmente de edición, compilación y otras utilidades. En el caso
del lenguaje HTML esto se simplifica notablemente siendo estrictamente necesario
solo dos tipos de aplicaciones: navegadores y editores.

3.3.1. NAVEGADORES
Son programas instalados en el equipo del usuario que se encargan de ejecutar las
órdenes contenidas en el código HTML. Cuando un usuario desea visitar una
página web, su equipo debe conectarse con un servidor remoto y efectuar una
petición al servidor web. Como respuesta a esta petición se inicia, a través de la red
y basándose en el protocolo HTTP, la transferencia del código fuente que define la
página. Una vez que ese código llega al equipo del usuario, el navegador que este
tenga instalado interpreta “línea a línea” el código recibido y genera la página tal y
como se verá finalmente. Por tanto, los navegadores web o browsers son las
aplicaciones encargadas de realizar las peticiones de páginas web y otros recursos
al servidor y de presentar luego los resultados de la petición al usuario. Si además
la página HTML contiene imágenes, vídeos, documentos PDF u otro tipo de
ficheros diferentes, el navegador es el encargado de intentar presentar en pantalla
de forma correcta dichos contenidos y, si no puede hacerlo, de arrancar la
aplicación necesaria para la visualización de los mismos.

Los navegadores más conocidos son Internet Explorer y Netscape Comunicator,


pero existen otros navegadores menos conocidos como Neoplanet, Opera, Hot
Java, Mozilla, etc. Este último cada vez adquiere mayor importancia, y como se
indicó en el Capítulo 2, es el navegador estandarte de la corriente open source.

3.3.2. EDITORES
La labor de creación de una página web está a mitad de camino entre la
programación y el diseño gráfico o maquetación. Aunque se utiliza un lenguaje
(HTML), este está lejos de ser un lenguaje de programación como C, C++, Java,
etc. Por otro lado, crear la página no se reduce únicamente a buscar una
combinación de colores y colocación de diferentes elementos multimedia con una
apariencia visual atractiva.

60
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Hasta el momento se ha visto que para trabajar en HTML simplemente se necesita


un procesador de textos, por ejemplo el bloc de notas, con el que se crea la página
escribiendo directamente código HTML, y un navegador que interprete dicho
código.
Pero trabajar de esta manera requiere dominar completamente el lenguaje, de
ahí que para facilitar la labor de creación de páginas web se hayan
desarrollado unos programas, editores de HTML, que pueden ser clasificados
en dos grandes grupos:

— Editores WYSIWYG (What You See Is What You Get): con este tipo de editores el
usuario no trabaja directamente sobre el código, sino sobre un documento que
muestra la apariencia de la página tal como llegaría al usuario final (lo que tu ves
es lo que tu obtienes). Se trata de editores ideales para personas que comienzan a
utilizar el lenguaje HTML y quieren llegar a crear una página sin necesidad de
dominar el lenguaje, ya que estos editores se encargan de generar
automáticamente ese código de forma oculta para el usuario. Por supuesto, el
usuario tiene la posibilidad de consultar el código generado y, en algunos casos,
dependiendo del editor, también modificarlo.

— Editores no WYSIWYG: en este tipo de editores, el usuario en todo momento


puede ver y editar el código fuente. Por supuesto, estos editores disponen de
opciones que permiten generar automáticamente la estructura de los diferentes
elementos de la página y ayudan a la utilización de los comandos sin necesidad
de que el usuario los conozca con todo detalle.

Cualquier persona que quisiera crear su página web sin ningún tipo de
complicaciones, podría utilizar el procesador de texto Microsoft Word. Tras incluir
todo el contenido, con el formato deseado, se elegiría la opción de Guardar como
página web..., y el propio Word generaría una página web con el código fuente
correspondiente. Otro tipo de editores específicamente creados para generar páginas
web, como por ejemplo FrontPage, también permiten al usuario crear sus páginas de
esta forma tan simple. En ambos casos se estaría trabajando con un entorno de
edición perteneciente a la primera categoría de editores (WYSIWYG). A pesar de su
simplicidad de uso, estos editores también tienen sus inconvenientes; el principal es
la falta de control por parte del usuario del código generado, llegándose a generar en
ocasiones un código excesivamente complejo y no optimizado.

Dentro de la segunda categoría de editores se podrían citar los siguientes:

— HomeSite (www.allaire.com)
— 1stPage2000 (www.evrsoft.com)

61
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— arachnophilia (www.arachnoid.com/arachnophilia)
— AceHTML (http://freeware.acehtml.com)

La mayoría de los editores que se utilizan a un nivel profesional incorporan las dos
funcionalidades o modos de edición. Normalmente, los desarrolladores prefieren
trabajar directamente sobre el código y utilizar el otro modo para comprobar
únicamente la apariencia final de la página.

3.4. ESTRUCTURA DE UNA PÁGINA WEB


La estructura básica de todo documento HTML, aún no siendo obligatoria, debería
ajustarse al siguiente esquema:

<HTML> Indica el inicio de la página


<HEAD> Comienzo de la cabecera
<TITLE> Comienzo del título
Aquí irá el titulo de la página
</TITLE> Fin del título
</HEAD> Fin de la cabecera
<BODY> Comienzo del cuerpo
Aquí irá el contenido de la página: texto, tablas, imágenes,...
junto con los comandos HTML
</BODY> Fin del cuerpo
</HTML> Indica el fin de la página

3.4.1. COMPLEMENTOS A LA ESTRUCTURA BÁSICA:


METATAGS
Generalmente, cuando un internauta visualiza el código fuente de una página web
esta presenta una estructura más compleja que la indicada anteriormente como
estructura básica. Esto es debido principalmente a dos elementos: por un lado, el
código HTML que forma una página puede llevar embebido en distintas partes de
la estructura código de otros lenguajes, como por ejemplo JavaScript, con la
intención de dotar a la página de efectos o funcionalidades imposibles de lograr
con la utilización exclusiva de HTML. Por otro, es posible también encontrar unas
etiquetas especiales llamadas metatags o metaetiquetas, que por su importancia se
estudian a continuación.

62
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Las metatags, se pueden agrupar según su funcionalidad en dos bloques. El primero,


formado por metatags orientadas a definir una página web de acuerdo con los
estándares del lenguaje HTML, consiguiendo con ello que no solo los navegadores,
sino también las aplicaciones que estos puedan necesitar para visualizar la página,
sepan de forma clara cómo tienen que tratarla, consiguiendo así la máxima
compatibilidad y accesibilidad. Y, el segundo, formado por metatags orientadas a
conseguir la promoción de la página o sitio web.

Etiquetas de compatibilidad
Dos son las principales etiquetas que contribuyen a dotar al sitio de un correcto
aspecto formal y que, aún no siendo obligatorias, es al menos necesario conocer
para poder interpretar su significado.

La primera es la etiqueta META HTT-EQUIV="Content-Type", cuya


finalidad es solucionar el problema derivado de la disparidad de caracteres e
idiomas en los que se puede elaborar una página web. Problema, que de forma
resumida, se debe a la elaboración de una página en un determinado idioma y la
posterior posibilidad de que dicha página sea solicitada por un navegador desde
cualquier punto del mundo y con un idioma distinto, lo que con frecuencia impide
que dicho navegador pueda interpretar correctamente todos los caracteres que
componen la web. Un ejemplo claro es el carácter “ñ”. Surge así la necesidad de
dotar de un estándar a todos los documentos HTML, que permita indicar al
navegador qué conjunto de caracteres debe utilizar para presentar las páginas. Este
patrón viene dado por la metaetiqueta:

<META HTTP-EQUIV= "Content-Type"


CONTENT= "text/html;charset= caracteres a usar">

donde el atributo charset fijará el conjunto de caracteres de la página. El


navegador al recibir la página obtiene en la cabecera esta metaetiqueta y solicita al
sistema operativo que cargue los caracteres necesarios para poder presentar la
página tal y como se creó.

Para las páginas elaboradas en castellano se deberá usar el conjunto de caracteres


ISO 8859-1, también denominado Latin1, que incluye las letras acentuadas y la
letra ñ, tanto en mayúsculas como en minúsculas. La metaetiqueta a incluir será
entonces:

<META HTTP-EQUIV= "Content-Type"


CONTENT="text/html;charset= ISO-8859-1">

Por último, indicar que esta etiqueta debe situarse entre el <HEAD> y <TITLE>.

63
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La segunda metaetiqueta a destacar es DOCTYPE, y permite cumplir con las


recomendaciones del W3C en las que se indica la necesidad de que se declare el
tipo de documento y en la versión de HTML utilizada, facilitando de esta forma la
compatibilidad y accesibilidad a los navegadores. El texto de la declaración debe
colocarse al principio del documento, en la sección de precabecera, antes de la
etiqueta <HTML>, de forma que sea lo primero que recibe el navegador cliente al
solicitar una página web.

En HTML, atendiendo a las recomendaciones del consorcio W3C20, es posible


establecer tres tipos diferentes de documentos:

— Strict: el documento debe estar elaborado de una forma estricta conforme a las
reglas del estándar HTML aprobadas por la W3C para cada versión de HTML.
La etiqueta para establecer este tipo de documento es la siguiente:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

El inconveniente de este tipo de definición es que los navegadores antiguos


pueden no admitirla y que su rigidez no permite errores de código en la
elaboración de la página web.

— Transitional: es la declaración utilizada con mayor frecuencia, con ella además


de incluir los elementos y atributos del HTML estricto se incorporan otros
elementos no aceptados por el consorcio W3C y se dispone de más flexibilidad
a la hora de escribir el código. La declaración de este tipo de documento se
consigue mediante la siguiente etiqueta:

<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.O1
Transitional//EN">

— Frameset: es la declaración de documento a utilizar cuando la página utiliza


marcos o frames. La declaración se establece del siguiente modo:

<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">

20
El consorcio W3C pone a disposición de los desarrolladores un servicio gratuito que
permite verificar y confirmar que el documento está elaborado siguiendo las directrices
establecidas. El servicio está disponible en The W3C MarkUp Validation Service:
http://validator.w3.org/

64
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Etiquetas de promoción
Aún a riesgo de simplificar en exceso, se puede decir que el objetivo último de una
página web es ser visitada, y para lograrlo debe ser conocida, algo extremadamente
complicado de conseguir debido a la ingente cantidad21 de sitios web en la red. Los
usuarios de Internet en su búsqueda de información utilizan buscadores y
directorios, es habitual que consulten solo las páginas que ocupan las primeras
posiciones. Es por tanto un hecho que estos buscadores y directorios son la
principal fuente de visitas de una web, y que la posición que una página ocupa
dentro de ellos es clave para conseguir visitas. A tenor de lo comentado, los
desarrolladores se han esforzado primero en conocer el funcionamiento de los
buscadores22 y robots y, posteriormente, desarrollar un medio de facilitar el
indexado de sus páginas en las bases de datos de dichos buscadores. Surgen así una
serie de metatags entre las que destacan las siguientes:

META NAME="keywords", ofrece a los buscadores palabras clave (keywords)


del contenido de la página. Su sintaxis completa es:

<META NAME="keywords" CONTENT="palabra1, palabra2,


palabra3,
palabra4, palabra 5, palabra6, palabra
7">

META NAME="description", permite establecer una descripción general y


concisa de la página, como norma general se recomienda utilizar las palabras que
aparecen en las metatags keywords y no utilizar más de 255 caracteres. La sintaxis
es:

<META NAME="description" CONTENT=" Texto que forma la


descripción del sitio web .....">

21
El buscador Google, considerado en la actualidad el más completo de la red, tiene
indexadas un total de 3.300 millones de páginas web.
22
De forma resumida se puede considerar que, en función de la forma de operar, existen
tres tipos de buscadores o robots: los que venden el posicionamiento, los que utilizan robots
que leen las páginas webs, dando un peso fundamental a las metatags, e indexan las páginas
en función de las veces que aparece un término y Google, que utiliza el sistema
denominado “pagerank” en el que no importan tanto las metatags de una web y sí el
número de páginas de contenido similar que se dirigen o enlazan con ella.

65
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

3.5. CARACTERÍSTICAS GENERALES DEL


LENGUAJE Y SINTAXIS DE SUS COMANDOS
Antes de analizar los principales comandos de HTML es necesario conocer algunas
de sus características:

— Los navegadores ignoran los cambios de línea dentro del código HTML, así
como la existencia de más de un espacio en blanco entre palabras.
— Todo comando que carezca de sentido es ignorado por el navegador sin generar
ningún mensaje de error.
— Hay distintos tipos de navegadores e incluso un mismo navegador tiene
distintas versiones, esto hace que no todos funcionen igual, por lo que la
visualización de una misma página puede variar de un navegador a otro si no
se respetan los estándares del lenguaje.
— Los comandos o etiquetas van encerrados entre los signos < > y suelen tener
una orden de inicio y otra de fin con la misma forma que la de inicio pero
precedida de /. Ejemplo, para señalar que un texto se debe visualizar en
negrita se utiliza el comando <B> para señalar el inicio del texto y el comando
</B> para el final.
— Para escribir los comandos en HTML es indiferente el uso de mayúsculas o
minúsculas, pues producen el mismo efecto. Si bien, es bastante común utilizar
mayúsculas para hacer más identificables los comandos dentro del código
fuente.
— Los comandos o etiquetas pueden anidarse, combinarse, obteniendo como
resultado la suma de los efectos de cada uno de ellos. Por ejemplo, si se desea
que un texto aparezca en negrita y subrayado se podría realizar el siguiente
anidamiento de comandos:

<B><U> El texto deseado </U></B>


— Los comandos pueden requerir parámetros, elementos que especifican o
concretan la orden indicada por el comando. Los parámetros se introducen a
continuación del inicio del comando. Por ejemplo, la etiqueta <HR> genera una
línea horizontal que permite separar partes de una página; este comando puede
llevar los parámetros ALIGN, que indicará la posición de la línea (centrada,
izquierda, derecha), SIZE, que indica el grosor de la línea en píxeles, y
WIDTH, que marca la longitud de la línea.

66
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

— Si los comandos requieren parámetros, estos pueden indicarse en cualquier


orden, el valor del parámetro es asignado con el signo de igualdad y en caso de
existir más de uno, los parámetros se separan por espacios en blanco. Por
ejemplo, los dos comandos siguientes serían equivalentes:
<HR SIZE=20 WIDTH=40 ALIGN=center>
<HR ALIGN=center WIDTH=40 SIZE=20>
Los valores de los parámetros deben ser dados entrecomillados, salvo en el
caso de que estos valores no incluyan espacios en blanco o caracteres
especiales.

3.5.1. CARACTERES ESPECIALES


Existe una serie de caracteres que originalmente no podían ser incluidos
directamente en el documento HTML; si bien, la evolución del lenguaje ha
permitido el desarrollo de especificaciones concretas para cada idioma, recuérdese
una de las funciones de las metatags. No obstante, una forma de conseguir que
dichos caracteres especiales sean reconocidos por cualquier navegador, con
independencia del idioma que tenga predefinido, es introducirlos mediante una
codificación especial en HTML. La Tabla 3.1 muestra alguno de estos caracteres
especiales.

Carácter Cód. HTML Carácter Cód. HTML


< &lt; > &gt;
& &amp; " &quot;
¿ &iquest; i &iexcl;
Á &Aacute; á &aacute;
É &Eacute; é &eacute;
Í &Iacute; í &iacute;
Ó &Oacute; ó &oacute;
Ú &Uacute; ú &uacute;
Ä &Auml; ä &auml;
Ñ &Ntilde; ñ &ntilde;

Tabla 3.1 Caracteres especiales en HTML

67
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

3.6. COMANDOS BÁSICOS

Los comandos o tags existentes en el lenguaje HTML son múltiples. Para facilitar
su compresión se van a presentar agrupados según su finalidad (para qué sirven o
qué permiten hacer).

3.6.1. COMANDOS DE CABECERAS PARA


DEFINICIÓN DE TÍTULOS Y SECCIONES:
HTML dispone de seis cabeceras o tipos de letra predefinidos de distinto tamaño,
que se utilizan para marcar los títulos en las páginas. Mediante estos comandos se
puede estructurar el documento en secciones y diferentes niveles de subsecciones.
Las cabeceras se activan con el comando <Hn> y se desactivan con </Hn> donde Qes un
número de 1 a 6. Las cabeceras provocan automáticamente un salto de línea aunque no se
indique explícitamente. En concreto, los 6 comandos de cabecera se muestran en la Tabla
3.2.

Los comandos de cabecera admiten el parámetro ALIGN, que especifica la forma


de alineación de la cabecera con respecto al resto del documento, y cuyo valor
puede ser LEFT, RIGHT, o CENTER .

Código HTML Visualización


<H1>Cabecera tipo 1</H1> con un tamaño de letra de 24 puntos
<H2>Cabecera tipo 2</H2> con un tamaño de letra de 18 puntos
<H3>Cabecera tipo 3</H3> con un tamaño de letra de 14 puntos
<H4>Cabecera tipo 4</H4> con un tamaño de letra de 12 puntos
<H5>Cabecera tipo 5</H5> con un tamaño de letra de 10 puntos
<H6>Cabecera tipo 6</H6> con un tamaño de letra de 8 puntos
Tabla 3.2 Comandos de cabecera

3.6.2. COMANDOS DE CAMBIO DE ESTILO DE TEXTO

Para indicar atributos del texto (negrita, subrayado, etc...) se dispone de varias
directivas que a continuación se muestran. Hay que puntualizar que algunas de ellas
no son reconocidas por determinados navegadores, por lo que el resultado final
dependerá del navegador con que se visualice la página. Un ejemplo de esto es el
comando <BLINK>, específico del navegador Netscape y que no produce efecto en

68
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

otros navegadores. Los comandos más habituales para cambiar el estilo del texto son
los que se muestran en la Tabla 3.3.

Código HTML Visualización


<B>..................</B> Texto en negrita
<I>........... ......</I> Texto en itálica
<U>..................</U> Texto subrayado
<SUP> .............</SUP> Texto como superíndice
<SUB>..............</SUB> Texto como subíndice
<S>..................</S> Texto tachado
<BLINK> ..........</BLINK> Texto parpadeante

Tabla 3.3 Comandos de cambio de estilo del texto

Para variar el tamaño, color y tipo de letra de un texto también es muy útil el
comando <FONT> </FONT>. Algunos de los parámetros de este comando son:
— SIZE = +n/-n permite asignar al texto un tamaño n veces superior (+)
o inferior (-) respecto al tamaño normal de la fuente.
— COLOR = "código del color". Más adelante se analizará la codificación de
los colores en HTML.
— FACE = "nombre del tipo de fuente". Si el tipo de letra indicado no existe
en el ordenador que visualiza el texto, aparecerá escrito en la fuente
predeterminada del navegador.

Ejemplo 3.2:
Si se desea que el texto sea mostrado utilizando un tipo de letra de tamaño 2 veces
superior al normal, en color rojo y con fuente arial, el comando sería:

<FONT SIZE=+2 COLOR="#FF0000" FACE="arial"> Texto </FONT>

3.6.3. BLOQUES DE TEXTO Y PÁRRAFOS

El bloque de texto básico de un documento es el párrafo. Los párrafos del


documento pueden ser delimitados con los comandos:

69
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<P> .................... </P>

El comando <P> admite el parámetro ALIGN, cuyo valor puede ser LEFT, RIGHT
o CENTER y especifica la forma de alineamiento del párrafo.

Como se ha comentado anteriormente, los cambios de línea en el código fuente


HTML son ignorados por el navegador. Para forzar un salto de línea, basta colocar
el comando <BR>.

Existe un caso en el que los cambios de línea y espacios en blanco extra dentro del
código fuente sí tienen efecto sobre la visualización de la página, este caso
corresponde a los denominados bloques de texto preformateado. La forma de
definir estos bloques de texto en HTML es:

<PRE>................</PRE>

Ejemplo 3.3:
Supóngase que se desea incluir en la página una estadística de las proyecciones y
espectadores de Cinem@s durante el último año. Se podría generar una sencilla
estructura tabular mediante un bloque de texto preformateado:

<PRE>
Trimestre Trimestre Trimestre Trimestre
1 2 3 4
----------------------------------------------------------
Proyecciones 456 502 399 487
Expectadores 3.446 6.782 2.947 5.821
----------------------------------------------------------
</PRE>

Cuando el navegador interprete este código, se visualizará ese bloque de texto tal como
aparece en él, respetando el espaciado entre palabras y los cambios de línea. Puede
comprobarse cómo, de no usar los comandos <PRE> y </PRE>, los datos se
mostrarían separados entre sí por un único espacio en blanco y los cambios de línea se
producirían en los lugares que determine la anchura de la ventana del navegador.

Otro de los tipos de bloques de texto disponibles está constituido por los bloques
con sangrías (texto sangrado), la definición de uno de estos bloques se realiza con
los comandos:

<BLOCKQUOTE>................</BLOCKQUOTE>

70
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

3.6.4. COMANDOS PARA LA GENERACIÓN DE


LISTAS
La presentación de información en forma de listas se puede realizar básicamente de
dos formas:

— Listas numeradas, representan los elementos de la lista numerando cada


uno de ellos de forma consecutiva según el lugar que ocupan en la misma.
— Listas sin numerar, representan los elementos de la lista con una marca o
viñeta que antecede a cada uno de ellos.

Para la construcción de listas numeradas se utilizan los comandos <OL> y


</OL>, que señalan el inicio y el fin, respectivamente, de la lista. Cada elemento
o ítem de lista se señala con el comando <LI>. El propio intérprete de HTML se
encargará de asignar la numeración a cada ítem.

El comando <OL> tiene algunos parámetros opcionales, entre ellos:


— START: especifica el número de orden del primer elemento de la lista, por
defecto empezará en 1.
— TYPE: Indica el tipo de numeración a emplear, el valor para este parámetro
puede ser:

1 números (valor por defecto).


i números romanos en minúscula.
I números romanos en mayúscula.
a letras en minúscula.
A letras en mayúscula.

Ejemplo 3.4:
Supóngase que se desea mostrar en una página las 10 películas más taquilleras de
todos los tiempos en España. El código HTML que genera esta página podría ser el
siguiente:

<H2>
LAS PELÍCULAS MAS TAQUILLERAS DE TODOS LOS TIEMPOS EN
ESPAÑA
</H2>
<OL>

71
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<LI>Titanic (1997)</LI>
<LI>El señor de los anillos, El retorno del
rey (2003)</LI>
<LI>El señor de los Anillos, La comunidad del
anillo (2001)</LI>
<LI>El señor de los anillos, Las dos Torres (2002)</LI>
<LI>Harry Potter y la piedra filosofal (2001)</LI>
<LI>Los otros (2001)</LI>
<LI>El sexto sentido (1999)</LI>
<LI>Shrek 2 (2004)</LI>
<LI>Harry Potter y la cámara secreta (2002)</LI>
<LI>La guerra de las galaxias, Episodio I,
La amenaza fantasma (1999)</LI>
</OL>

Los comandos de finalización de cada ítem de la tabla (</LI>) son opcionales.

La visualización de la página en el navegador se muestra en la Figura 3.3.

Figura 3.3 Lista de las películas más taquilleras

72
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

En el caso de las listas sin numerar, su construcción es similar, salvo en el uso de


comandos diferentes para señalar el inicio y el fin de la lista. Estos comandos son
<UL> y </UL>; cada elemento de la lista irá precedido del comando <LI>.

El comando <UL> puede llevar el parámetro opcional TYPE, que indica el tipo de
símbolo utilizado para marcar los elementos de la lista. Los valores posibles son:

— circle Círculos huecos


— disc Círculos rellenos
— square Cuadrados rellenos

Ejemplo 3.5:
La Figura 3.4 corresponde a una página web del sitio de Cinem@s en la que se
muestra información sobre las salas de proyección disponibles. Esta página
contiene en su parte inferior una lista sin numerar cuyo código HTML es:

Todas nuestras salas están equipadas con:


<UL TYPE="disc">
<LI>Aire acondicionado</LI>
<LI>Pantallas de grandes dimensiones</LI>
<LI>Sistema de sonido Dolby Digital Soundround</LI>
<LI>Cómodas butacas equipadas con portarefrescos</LI>
<LI>Cómodos accesos y espacios entre butacas</LI>
</UL>

73
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 3.4 Página de presentación de las características de las salas de Cinem@s

Por último, indicar que los diferentes tipos de listas se pueden anidar es decir,
incluir una lista dentro de otra, incluso siendo listas de diferentes tipos.

Ejemplo 3.6:
La página que se puede ver en la Figura 3.5 incorpora una serie de listas anidadas,
la lista de nivel superior es una lista numerada, mientras que las de los niveles
inferiores son listas sin numerar. El código fuente de esa página es:

<H2>
Nuestros menús especiales
</H2>
Para disfrutar del mejor cine le ofrecemos nuestros packs
especiales:

74
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

<OL TYPE=A>
<LI> Menú <I>Junior</I> </LI>

<UL TYPE=square>
<LI>Palomitas pequeña</LI>
<LI>Bebida a elegir:</LI>

<UL TYPE="circle">
<LI>Agua mineral</LI>
<LI>Refresco pequeño</LI>
</UL>
</UL>

<LI> Menú especial <I>Cinem@s</I> </LI>

<UL TYPE=square>
<LI>Palomitas grande</LI>
<LI>Snack</LI>
<LI>Bebida a elegir:</LI>

<UL TYPE="circle">
<LI>Agua mineral</LI>
<LI>Refresco grande</LI>
</UL>
</UL>
</OL>

Aunque no es estrictamente necesario, y no tiene ningún efecto sobre la


visualización de la página, sí que es recomendable tratar de escribir el
NOTA
código fuente de una manera que mejore su legibilidad y depuración. En
el ejemplo anterior, las diferentes listas anidadas han sido incluidas en
el código con diferentes niveles de sangrado precisamente para eso.

75
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 3.5 Estructura de listas anidadas

3.6.5. CREACIÓN DE TABLAS

Otra de las estructuras básicas de HTML para mostrar y organizar datos son las
tablas. Estas estructuras van a resultar especialmente útiles cuando se desee
recuperar datos de una base de datos y visualizarlos en una página web; es por ello
que, en función de los objetivos de este libro, resulta importante conocer en detalle
los diferentes comandos HTML que permiten generar estas estructuras.

Las tablas se generan siempre con la siguiente estructura:

— Toda tabla queda delimitada por los comandos <TABLE> y </TABLE>.


— Cada fila de la tabla queda delimitada por los comandos <TR> y </TR>.
— Se pueden definir dos tipos de celdas:
o Celdas de cabecera o titulares: señaladas con los comandos <TH>
y </TH>.

76
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

o Celdas de contenido: señaladas con los comandos <TD> y </TD>.

Los diferentes comandos de creación de tablas disponen de una serie de


argumentos opcionales que permiten, entre otras cosas, establecer bordes para las
celdas, tipos de alineación, fusión de celdas, dimensiones,... A continuación se
recogen algunos de estos parámetros.

Parámetros opcionales del comando <TABLE>:

— BORDER: indica que debe dibujarse un borde a la tabla. Si se da un valor a este


parámetro, ese valor indica el grosor en píxeles del borde. Si no se indica este
parámetro la tabla aparecerá sin borde.
— CELLPADDING: permite indicar el espacio que se debe dejar entre el borde de
cada celda y su contenido. El valor por defecto es 1.
— CELLSPACING: fija la anchura, en píxeles, de las líneas de división internas
de la tabla. El valor por defecto es 2.
— WIDTH: controla la anchura de la tabla. Se puede indicar un valor en píxeles o
un porcentaje respecto al ancho total de la página.
— ALIGN: permite situar la tabla respecto al texto que tiene a su alrededor. Los
valores que puede tomar este parámetro son CENTER, LEFT y RIGHT.

Parámetros adicionales de los comandos <TD> y <TH>:

— ALIGN: indica el tipo de alineación del contenido de las celdas. Los valores
pueden ser LEFT, RIGHT y CENTER. Este parámetro también puede aplicarse
sobre el comando <TR> y tendrá efecto sobre todas las celdas de esa fila.
— VALIGN: indica el tipo de alineación vertical del contenido de las celdas. Los
valores pueden ser TOP, BOTTOM, MIDDLE (valor por defecto).
— BGCOLOR: indica un color de fondo para la celda. También puede ser aplicado
sobre toda una fila o la tabla completa.
— COLSPAN: indica el número de columnas que ocupa la celda. El valor por
defecto es 1.
— ROWSPAN: indica el número de filas que ocupa la celda. Por defecto es 1.
— NOWRAP: obliga al navegador a no partir las líneas de la celda. El ancho de la
celda estará fijado por la longitud del texto que contendrá.
— WIDTH: indica el ancho de la celda. Se puede indicar un ancho en píxeles o un
porcentaje respecto al ancho total de la tabla.

77
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 3.7:
Cinem@s tiene establecido un sistema por el cuál todos sus clientes acumulan
puntos cada vez que adquieren una entrada. Los puntos acumulados pueden ser
canjeados por entradas gratis y otros regalos. Dentro del sitio web, Cinem@s
quiere incluir una tabla como la que se ve en la Figura 3.6 para indicar la
correspondencia entre puntos y premios.

Figura 3.6 Tabla de premios

El código HTML que genera esta página es:

<H1 ALIGN="center">
Nuestros premios
</H1>
<TABLE BORDER ALIGN=center>
<TR BGCOLOR=#99CCFF>
<TH> Puntos </TH> <TH> Premio </TD>
</TR>
<TR>
<TH> 20 </TH> <TD> Entrada gratis </TD>
</TR>
<TR>
<TH> 25 </TH> <TD> Gorra <I>Cinem@s</I> </TD>
</TR>

78
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

<TR>
<TH> 30 </TH> <TD> Camiseta <I>Cinem@s</I> </TD>
</TR>
<TR>
<TH> 35 </TH> <TD> Película en DVD o VHS </TD>
</TR>
<TR>
<TH> 40 </TH> <TD> Reproductor de CDs portátil </TD>
</TR>
</TABLE>

3.6.6. INSERCIÓN DE IMÁGENES

Las imágenes son un elemento esencial para diseñar páginas elegantes. Sin
embargo, un excesivo número de imágenes en una página puede hacer que esta
pierda su estética, a la vez que supone hacer más lento el proceso de visualización
(las imágenes son las partes de las páginas que más espacio en bytes ocupan, por lo
que su transferencia requiere más tiempo que la del texto). Los visualizadores
pueden admitir distintos formatos de imágenes, los más extendidos son GIF y JPG.
Cada uno de ellos tiene sus ventajas; por ejemplo, las imágenes JPG ocupan menos
espacio, con la consiguiente reducción de tiempo en la transferencia, pero también
tienen peor calidad que el formato GIF.

El comando utilizado para la inserción de imágenes es <IMG> cuya sintaxis


mínima exige indicar en su parámetro SRC el fichero gráfico que contiene la
imagen:

<IMG SRC = "fichero gráfico con la imagen">

En el caso de que el fichero gráfico se encuentre almacenado en un directorio


diferente al de la propia página web, será preciso indicar junto con el nombre del
fichero la ruta relativa necesaria para localizarlo.
El comando <IMG> tiene una serie de parámetros opcionales, los más importantes son los
que se citan a continuación:

— ALIGN: especifica el modo en el que la imagen se alinea con el texto que la


rodea. Los valores que puede tomar este parámetro son: TOP, BOTTOM,
MIDDLE, LEFT, RIGHT.
— ALT: especifica un texto alternativo que se utilizará para sustituir a la imagen
en el caso de que el visualizador utilizado no pueda mostrar imágenes o esta
no pueda ser localizada o cargada.

79
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— HEIGHT y WIDTH: indican al navegador la altura y la anchura en píxeles de la


imagen. Si estas dimensiones no corresponden con las reales la imagen será
escalada.
— BORDER: indica la anchura del borde que rodeará a la imagen en la página.
— HSPACE y VSPACE: fijan márgenes horizontales y verticales a dejar entre la
imagen y el texto que la rodea.

Una opción interesante es insertar una imagen como fondo de la página. La forma
de hacerlo es utilizando el parámetro BACKGROUND al mismo tiempo que se
declara el inicio del cuerpo del documento:

<BODY BACKGROUND="Fondo.gif">

En este caso la imagen se repetirá tantas veces como sea necesario para cubrir todo
el área visible de la página.

Ejemplo 3.8:
La página de inicio de Cinem@s que se vio en la Figura 3.1 incorpora varias
imágenes. La página está dividida en dos áreas diferentes, correspondientes a lo
que en HTML se denomina marcos o frames, en la de la parte superior se incluyen
tres imágenes que han sido insertadas dentro de una tabla para poder posicionarlas
en la página de una manera sencilla. El código siguiente muestra la construcción de
esa tabla y la inserción de las tres imágenes:

<TABLE WIDTH="100%" BORDER=1>


<TR BORDERCOLOR="#FFFFFF" BGCOLOR="#0066CC">
<TH WIDTH=110>
<IMG SRC="images/CARRETEPELI1.gif"
WIDTH=77 HEIGHT=60></TH>
<TH WIDTH ="*">
<IMG SRC="images/logo.gif" WIDTH=143 HEIGHT=73>
</TH>
<TH WIDTH =110>
<IMG SRC="images/CARRETEPELI1.gif"
WIDTH=77 HEIGHT=60></TH>
</TR>
</TABLE>

80
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

3.6.7. TRATAMIENTO DEL COLOR


En el último ejemplo se utilizó el parámetro BGCOLOR para definir un color de
fondo para determinadas celdas la tabla. El valor de ese parámetro es una cadena
de caracteres con la codificación hexadecimal de un color. En esta sección se
explica el significado de este tipo de codificaciones.

Todo color en HTML viene definido por su formato RGB (Red-Green-Blue), identificado
mediante un código numérico de seis dígitos hexadecimales precedidos del signo "#".
Según este formato, todo color es una combinación de los tres colores básicos: rojo (R),
verde (G) y azul (B); cada uno de ellos puede expresarse desde la ausencia de color (valor
0) a saturación de color (255). La expresión de los valores debe hacerse en forma
hexadecimal, el valor mínimo (0) se expresa como 00, y el máximo (255) como FF. De
esta forma el código de un color estará formado por 6 dígitos hexadecimales:

— Los dos primeros dígitos indican la componente del color primario rojo.
— Los dos dígitos intermedios indican la componente del color primario verde.
— Los dos últimos dígitos indican la componente azul.

La Tabla 3.4 muestra los códigos hexadecimales de algunos de los colores habituales.
Para alguno de esos colores HTML acepta la utilización de identificadores
alfanuméricos, por ejemplo, el color azul puede ser identificado como blue o el color
rojo como red.

Color Código Color Código


Blanco #FFFFFF Negro #000000
Azul #0000FF Verde #00FF00
Ciano #00FFFF Verde mar #238E6B
Azul cielo #3299CC Verde oscuro #2F4F2F
Violeta #4F2F4F Verde lima #32CC32
Gris #C0C0C0 Salmón #6F4242
Turquesa #7093DB Marrón #A52A2A
Rosa #BC8F8F Naranja #CC3232
Oro #CC7F32 Rojo #FF0000
Magenta #FF00FF Amarillo #FFFF00
Tabla 3.4 Codificación RGB de colores habituales

Los editores de HTML suelen disponer de una paleta de colores para facilitar la
utilización de los mismos sin tener que realizar conversiones a formato
hexadecimal.

81
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En el momento de declarar el cuerpo del documento HTML mediante el comando


<BODY>, se pueden utilizar una serie de parámetros para indicar el color de
distintos elementos que intervienen en la página como el fondo, el texto y los
enlaces:

— BGCOLOR : permite dar un color al fondo de la página.


— TEXT : permite indicar el color del texto.
— LINK : permite designar el color de los enlaces aún no visitados.
— VLINK : permite designar el color de los enlaces ya visitados.

Ejemplo 3.9:
Si se desea que el fondo de la página sea de color azul oscuro, el texto amarillo
(combinación de rojo y verde a partes iguales), el texto asociado a los enlaces no
visitados en color verde y el de los visitados en rojo, la definición del cuerpo del
documento debería hacerse de la siguiente manera:

<BODY BGCOLOR="#OOOOCC" TEXT="#FFFFOO"


LINK="#OODDOO" VLINK="#FFOOOO">

3.6.8. ENLACES O HIPERVÍNCULOS


Los enlaces permiten la navegación a través de la información de una página a
puntos concretos de la misma página, a otras páginas diferentes de un mismo sitio
web o a cualquier página en Internet.

Todo enlace consta de dos elementos esenciales: un elemento de enlace y un


destino. El elemento de enlace puede ser texto, una imagen o ambas cosas, y la
activación se produce mediante un "click" del ratón sobre él. El elemento de enlace
debe ser señalado encerrándolo entre los comandos <A> y </A>.

En cuanto al destino del enlace, este puede ser otro documento HTML, cualquier
punto intermedio dentro del documento HTML en curso o de otro documento
HTML, e incluso cualquier otro documento de otro tipo (binarios, imágenes,...). El
destino del enlace se define mediante el parámetro HREF del comando <A>.

Ejemplo 3.10:
La página de inicio de Cinem@s (Figura 3.1) tiene un conjunto de enlaces que dan
acceso a las restantes páginas del sitio. Estos enlaces se encuentran situados en una
tabla que consta de tres filas y tres columnas, estando la columna central reservada

82
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

para una imagen. El código que define esa estructura tabular con los enlaces
correspondientes es el que se incluye a continuación:

<TABLE CELLSPACING=2 CELLPADDING=5 WIDTH=100%>


<TR ALIGN="center" BGCOLOR="#0066CC">
<TD WIDTH=25%>
<A HREF="proyecciones.php">
<FONT SIZE=4 COLOR="#FFFFFF">
Nuestra cartelera</FONT>
</A>
</TD>
<TD WIDTH=50% ROWSPAN=4>
<IMG SRC="images/cineportada.jpg"
WIDTH="295" HEIGHT="303">
</TD>
<TD WIDTH=25%>
<A HREF="salas.htm">
<FONT SIZE=4 COLOR="#FFFFFF">
Nuestras salas</FONT>
</A>
</TD>
</TR>
<TR ALIGN=center BGCOLOR="#0066CC">
<TD>
<A HREF="clientes.htm">
<FONT SIZE=4 COLOR="#FFFFFF">
Área de clientes</FONT>
</A>
</TD>
<TD>
<A HREF="entradas.htm">
<FONT SIZE=4 COLOR="#FFFFFF">
Compra de entradas</FONT>
</A>
</TD>
</TR>
<TR ALIGN=center BGCOLOR="#0066CC">
<TD>
<A HREF="estrenos.htm">
<FONT SIZE=4 COLOR="#FFFFFF">
Próximos estrenos</FONT>
</A>
</TD>
<TD>
<A HREF="foros/index.php">
<FONT SIZE=4 color="#FFFFFF">
El foro Cinem@s</FONT>

83
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

</A>
</TD>
</TR>
</TABLE>

Como puede apreciarse, los diferentes enlaces apuntan hacia nuevas páginas
HTML o documentos PHP.

Un caso particular de enlaces son los denominados marcadores o anclas internos,


enlaces a puntos concretos de un documento HTML. Para crear un marcador se
debe, en primer lugar, señalar el punto de destino con el siguiente comando:

<A NAME=" nombre_marcador"> Texto opcional </A>

El nombre del marcador no puede contener ni espacios en blanco ni los caracteres


=, +, <, >, ¿, / y %. Además, estos nombres son sensibles al uso de mayúsculas y
minúsculas.

Una vez marcado el destino, se debe crear el enlace, para ello la sintaxis es:

— Si el lugar de destino y el enlace se encuentran en el mismo documento, el


valor del parámetro HREF debe ser el nombre dado al marcador precedido
del signo "#":

<A HREF="# nombre_marcador"> Elemento de enlace


</A>

— Cuando el lugar de destino se encuentra en un documento diferente al del


enlace, el parámetro HREF toma como valor el URL absoluto o relativo del
documento de destino, seguido del signo "#" y el nombre del marcador:

<A HREF="URLdestino#nombre_marcador">
Elemento de enlace
</A>

Finalmente, otro de los enlaces o hipervínculos más característicos es el que


permite enviar un correo electrónico a una determinada dirección. El comando a
utilizar vuelve a ser el comando <A> pero con un valor diferente para el parámetro
HREF:

<A HREF="MAILTO:admin@cinemas.es">Enviar mensaje</A>

84
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Como se pueda apreciar, el valor de HREF es en este caso la palabra MAILTO


seguida de dos puntos y la dirección de correo electrónico de destino.

3.7. MARCOS O FRAMES


Una de las opciones más interesantes para el diseño y presentación de sitos web
es la utilización de los denominados marcos o frames. Los marcos en HTML
permiten la creación de un documento web con varias partes independientes,
cada una de las cuales puede mostrar diferentes páginas web, lo que permite
dotar a un sitio de cierto dinamismo a la vez que mejorar su funcionalidad y
apariencia.

Uno de los usos más frecuentes de los marcos es el de reservar una zona de la
página para mostrar cierta información siempre visible o fija, por ejemplo un
logotipo de una empresa, un índice con enlaces a otras páginas, etc. De esta forma,
cuando se activa uno de esos enlaces se puede acceder a su contenido en otra parte
de la página manteniendo también visible la parte fija. Esto es precisamente lo que
se ha realizado en el diseño del sitio web de Cinem@s, cuya página de inicio
muestra la Figura 3.1 y que contiene dos marcos:

1. El marco superior muestra en todo momento el logotipo de la empresa con


dos imágenes flanqueándole a ambos lados.

2. El marco inferior, o principal, contiene la tabla con los enlaces a las


restantes páginas del sitio. Cada vez que un enlace se active se cargará en
esa parte de la ventana la correspondiente página, pero quedando fijo el
marco que contiene el logotipo.

3.7.1. CONSTRUCCIÓN DE PÁGINAS CON MARCOS


Los documentos HTML que contienen marcos de forma general suelen recibir el
nombre de páginas de marcos, y tienen una estructura diferente a la de los
documentos sin marcos. Un documento HTML tiene dos grandes secciones
definidas por las etiquetas <HEAD>, para indicar la cabecera del documento, y
<BODY> para introducir el cuerpo de la página. Sin embargo, esta estructura
cambia en los documentos con marcos. Para crear un documento con marcos se
debe crear una página web con una cabecera pero se sustituye el cuerpo por unas
directivas o etiquetas específicas <FRAMESET> y </FRAMESET> mediante las
que se define el conjunto de marcos del documento.

85
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Los parámetros que recibe el comando de definición de marcos (<FRAMESET>)


son:

— COLS: establece que la disposición de los marcos será en columnas,


dividiendo la pantalla verticalmente en columnas. Además, indica la
extensión de cada espacio generado. Este parámetro recibe como valor una
lista con las dimensiones de cada columna separadas por comas, cada una
de estas dimensiones puede darse de tres formas:
o Un número que represente la anchura en píxeles de la
columna.
o Un porcentaje que la columna ocupará sobre el total del
espacio libre.
o Un asterisco, indicando que la columna se extenderá por todo
el espacio libre de la ventana.
— ROWS: establece que la disposición de los marcos será en filas, dividiendo
la pantalla horizontalmente. Como en el caso anterior debe indicarse la
extensión de cada marco y para ello toma los mismos parámetros que el
atributo COLS.
— FRAMEBORDER: dota de borde a los marcos según tome los valores YES o NO.
— BORDER: señala el grosor, en píxeles, del borde.
— BORDERCOLOR: establece un color concreto para el borde.
— FRAMESPACING: indica la separación entre marcos tomando.

Es conveniente señalar que los marcos se crean de izquierda a derecha para las
columnas y de arriba a bajo para las filas. Además, los marcos se pueden anidar es
decir, introducir unos marcos dentro de otros o subdividir un marco en otros.

Hasta el momento se ha visto cómo dividir una página en varias áreas con la
directiva <FRAMESET>. Una vez realizada esa división es necesario definir los
contenidos que se mostrarán en cada marco, para ello se utiliza la etiqueta
<FRAME>, etiqueta que no tiene comando de cierre y que irá situada en cada uno
de los marcos que se definan entre las etiquetas <FRAMESET>. Los parámetros
que pueden acompañar a esta etiqueta permiten indicar el contenido y modificar la
apariencia del marco:

— SRC: indica el documento que se cargará o visualizará en el marco. El


valor que toma es el nombre del documento HTML o su ruta.

86
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

— NAME: asigna un nombre al marco, este nombre identificará posteriormente


al marco.
— FRAMEBORDER: permite que aparezca visible o no el borde del marco. Los
valores que puede tomar son YES o NO.
— MARGINHEIGHT: altura del margen a dejar respecto a los bordes del
marco.
— MARGINWIDTH: anchura del margen a dejar respecto a los bordes del
marco.
— SCROLLING: permite indicar si se desea mostrar una barra de
desplazamiento para el marco. Los valores que puede tomar son:
o YES: mostrar siempre barra de desplazamiento.
o No: sin barra de desplazamiento.
o AUTO: (valor por defecto) se mostrará la barra de
desplazamiento cuando sea necesario (el contenido de la
página no se puede visualizar completamente en el espacio
reservado a tal efecto).
— NORESIZE: si está presente indica que el usuario no podrá redimensionar
el marco, es decir, aumentar o reducir el tamaño.

Los marcos, si bien permiten enriquecer un sitio con mayor dinamismo y sensación
de interactividad, también pueden generar problemas derivados principalmente del
navegador que utilice el usuario, puesto que determinados navegadores o versiones
de estos no están preparados para permitir mostrar páginas construidas con marcos.
El diseñador del sitio web debe tener en cuenta este posible problema y anticiparse
a él generando un contenido alternativo que pueda ser visualizado por los usuarios
con navegadores que no admitan marcos. Para la creación de este contenido
alternativo se utilizan las etiquetas <NOFRAMES> y </NOFRAMES>. Estas
etiquetas permiten indicar a los navegadores que no soporten marcos que el
contenido que se debe mostrar es el contenido comprendido entre ellas.

3.7.2. ENLACES EN PÁGINAS CON MARCOS


Una cuestión importante cuando se trabaja con páginas con marcos es señalar
claramente el marco en el que se desea visualizar cada enlace. Por ejemplo, podría
ser interesante que el enlace se encuentre en un marco pero que al activarlo el
contenido del destino se visualice en otro; sin embargo, las opciones son múltiples:

87
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

además de visualizarlo en un marco concreto se podría ver en una ventana nueva


del navegador, en la misma ventana haciendo desaparecer la página de marcos,...

Para realizar esta tarea de asignación de un lugar concreto de visualización a cada


enlace, en la creación del vínculo se debe introducir el parámetro TARGET, siendo
su valor alguno de los siguientes:

— "Nombre_marco": señala el nombre del marco en el que debe cargarse


el destino.
— _blank: abre el documento vinculado en una nueva ventana del
navegador sin cerrar la anterior.
— _parent: muestra el contenido del enlace en el anterior marco definido.
Si no hay ningún marco definido se muestra a pantalla completa.
— _self: abre el documento en el mismo marco o ventana en el que se
encuentra el vinculo (opción por defecto).
— _top: muestra el contenido del enlace a pantalla completa eliminando la
ventana anterior.

Hay que hacer notar al lector que la decisión de asignar el lugar en el que se deben
mostrar los contenidos no es trivial, imagínese que en un sitio web tiene una página
que consta de diferentes enlaces a otros sitios web distintos; si se decide que al
seleccionar un enlace este se abra en la misma ventana del navegador, implicaría
que el usuario al seleccionarlo sale del sitio web.

Ejemplo 3.11:
A continuación se muestra el código fuente de la página principal de Cinem@s
(Figura 3.1), que como ya se ha comentado anteriormente está constituida por dos
marcos divididos horizontalmente.

<HTML>
<HEAD>
<TITLE>Cinem@s</TITLE>
</HEAD>
<FRAMESET ROWS="105,*">
<FRAME NAME="encabezado" SCROLLING="no" NORESIZE
SRC="encabezado.htm" FRAMEBORDER=0>
<FRAME NAME="principal" SRC="principal.htm"
FRAMEBORDER =0>
<NOFRAMES>
<BODY>

88
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

<P>Esta página usa marcos, pero su explorador


no los admite.</P>
</BODY>
</NOFRAMES>
</FRAMESET>
</HTML>

Como en todo documento HTML, la etiqueta de inicio es <HTML> seguida de la


cabecera del documento que contiene el título de la página. Finalizada la cabecera
del documento en una página normal se encuentra el cuerpo (<BODY>), pero como
ya se ha comentado, en las páginas de marcos lo que sigue a la cabecera del
documento es la definición de los marcos. En este caso:

<FRAMESET ROWS="105,*">

indica que la página se va a dividir horizontalmente en dos filas, una superior con
una altura de 105 píxeles y la inferior, que ocupará el resto de espacio libre.
Posteriormente se definen los dos marcos con el comando <FRAME>:

<FRAME NAME="encabezado" SCROLLING="no" NORESIZE


SRC="encabezado.htm" FRAMEBORDER=0>

Este primer comando define el marco superior, asignándole un nombre, indicando


que no tendrá barra de desplazamiento y que no se podrá redimensionar su tamaño.
Además, establece que en el marco se mostrará la página encabezado.htm y que no
aparecerá visible el borde del marco.

La segunda etiqueta <FRAME> establecerá la apariencia y contenido de la segunda


división de la ventana:

<FRAME NAME="principal" SRC="principal.htm"


FRAMEBORDER =0>

El segundo espacio generado por el marco se denomina principal y en él se


mostrará el documento principal.htm.

En la siguiente línea se define un contenido alternativo (<NOFRAMES>) para los


visitantes cuyo navegador no admita marcos. Nótese que este contenido alternativo
se sitúa entre las etiquetas <NOFRAMES> y </NOFRAMES>, antes de cerrar la
definición de la estructura de marcos.

89
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

3.8. FORMULARIOS
Los formularios son uno de los componentes esenciales en una página web, ya que
permiten la interacción con el usuario, consiguiendo así recoger información
particular sobre sus gustos, opiniones, datos personales,... Los visitantes rellenan
los campos del formulario y haciendo clic en un botón del propio formulario, se
envían los datos al servidor en el que reside el sitio web, para que sean procesados,
en su caso, por este. Especialmente útiles serán los formularios para actuar de
interfaz de usuario en los programas PHP.

Los formularios están compuestos por campos de diferentes tipos (cuadros de


texto, casillas de verificación, botones de opciones, menús desplegables,...) en los
que el usuario introduce los datos, y dispone de botones que ejecutan las acciones
de enviar o borrar los datos del formulario.

Para crear un formulario se utiliza el comando <FORM> y una serie de comandos


especiales para crear cada uno de sus campos. Este comando <FORM> admite dos
parámetros fundamentales:

— El parámetro ACTION indica quién será el encargado de recibir y, en su


caso procesar, los datos que se envían desde el formulario. Este parámetro
puede tomar como valor:
o El URL de un programa CGI alojado en el servidor y
encargado de procesar la información recibida mediante un
formulario.
o El URL de un archivo, por ejemplo en PHP, creado ad hoc
para procesar el formulario.
o Una dirección de correo electrónico a la que será enviada la
información de los campos del formulario.

— El parámetro METHOD indica cómo debe realizarse la transferencia de los


datos contenidos en el formulario. Los valores que puede tomar son:
o GET: envía los datos formando parte del URL.
o POST: transmite los datos separados del URL.

La diferencia entre estos dos métodos de envío será analizada en detalle en el


Capítulo 5, cuando se estudie la forma en la que PHP recibe y procesa los datos
procedentes de formularios.

90
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Una vez delimitado el formulario entre los comando <FORM> y </FORM>, deben
indicarse entre ellos los comandos necesarios para construir cada uno de sus
campos. Un formulario consta de campos de diferentes tipos y cada uno de esos
campos se define utilizando un comando <INPUT>, acompañado de un parámetro
TYPE que será el que indique el tipo de campo. Los valores que puede tomar este
parámetro TYPE son los que muestra la Tabla 3.5.

Otros parámetros del comando <INPUT> son:

— NAME: nombre que utilizará el programa encargado de procesar los datos


para referirse al campo.
— VALUE: utilizado para dar al campo valores por defecto.
— SIZE: establece el tamaño del campo (número de caracteres).
— MAXSIZE: indica el número máximo de caracteres que puede recibir el
campo.

Valor de TYPE Tipo de campo


text Campo de texto.
password Campo especial para introducir contraseñas.
radio Botón de radio.
checkbox Cajas de selección.
submit Botón de envío de la información.
reset Botón de borrado de la información.
button Botón de acción.
hidden Campo oculto.
Tabla 3.5 Tipos de campos de formulario

Además de los campos de texto definidos con el comando <INPUT>, se pueden crear
también otro tipo de campos: las áreas de texto. Se trata de campos de texto que ocupan
más de una línea. La definición de un área de texto responde al siguiente esquema:

<TEXTAREA NAME= "nombre_campo" ROWS=n COLS=m>


</TEXTAREA>

donde n es el número de filas y m el número de columnas del área de texto.

Otro recurso de los formularios son las listas desplegables, que definen campos con
valores predefinidos. Estas listas se crean igualmente con un comando especial: el

91
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

comando <SELECT>. Cada uno de los elementos de la lista se define con el comando
<OPTION>.

Ejemplo 3.12:
El siguiente código crea un menú desplegable con cuatro opciones, apareciendo la
primera seleccionada por defecto:

<SELECT NAME="nombre">
<OPTION SELECTED> Opción por defecto
<OPTION> Opción 2
<OPTION> Opción 3
<OPTION> Opción 4
</SELECT>

Si en el comando <SELECT> aparece el parámetro MULTIPLE la lista será de


selección múltiple, además la opción seleccionada por defecto tiene que indicarse
colocando el parámetro SELECTED en el correspondiente comando <OPTION>.

Para concluir este capítulo se incluyen a continuación ejemplos de formularios que


forman parte del sitio web de Cinem@s y que serán utilizados en los Capítulos 16 y
17 para efectuar diversas operaciones de acceso a bases de datos.

Ejemplo 3.13:
Cinem@s incluye en su sitio web una página en la que sus clientes pueden
registrarse y acceder a la consulta de sus datos. La página de este “Área de
clientes” es la que se muestra en la Figura 3.7. Dicha página incluye dos
formularios situados dentro de una tabla de dos columnas, el primero permite
introducir un número de usuario y contraseña, mientras que el segundo sirve para
enviar todos los datos necesarios para registrarse como cliente.

El código completo de la página del “Área de clientes” es:

<HTML>
<HEAD><TITLE>Área de clientes</TITLE></HEAD>
<BODY TEXT=blue>
<!-- Barra de navegación del sitio -->
<TABLE WIDTH="100%" BORDER BGCOLOR=#99CCFF>
<TR>
<TH WIDTH="16%">
<A HREF="principal.htm">Página principal</A></TH>
<TH WIDTH="17%">
<A HREF="proyecciones.php">Nuestra cartelera</A></TH>

92
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

<TH WIDTH="17%">
<A HREF="salas.htm">Nuestras salas</A></TH>
<TH WIDTH="17%">
<A HREF="entradas.htm">Compra de entradas</A></TH>
<TH WIDTH="17%">
<A HREF="estrenos.htm">Próximos estrenos</A></TH>
<TH WIDTH="16%">
<A HREF="foros/index.php">Foro Cinem@s</A></TH>
</TR>
</TABLE>

<H1 ALIGN="center">Área de clientes</H1>


<TABLE CELLSPACING=12>
<TR>
<TD WIDTH=35%>
En Cinem@s queremos premiar la fidelidad de nuestros
clientes. Por ello, te ofrecemos la posibilidad de
registrarte como cliente y por cada entrada que compres
online acumularás puntos canjeables por regalos o entradas
gratuitas.
<P> Si ya eres cliente registrado, entra en tu página:
<!-- Formulario de acceso al área personal -->
<FORM ACTION=accesocliente.php METHOD=POST>
Número de cliente:
<INPUT TYPE=text SIZE="5" NAME="numcliente"><BR>
Contraseña:
<INPUT TYPE=password SIZE="6" NAME="pass"><BR>
<INPUT TYPE=submit VALUE=Entrar>
</FORM>
</TD>
<TD WIDTH=65%>
<I>Si aún no te has registrado hazlo aquí y comienza a
disfrutar de enormes ventajas</I>
<!-- Formulario de inscripción de clientes -->
<FORM ACTION="nuevocliente.php" METHOD=POST>
<TABLE>
<TR>
<TD>Nombre (*):</TD>
<TD><INPUT TYPE=text SIZE="40" NAME="nombre"></TD>
</TR>
<TR>
<TD>Dirección:</TD>
<TD><INPUT TYPE=text SIZE="50" NAME="direccion"></TD>
</TR>
<TR>
<TD>NIF (*):</TD>
<TD><INPUT TYPE=text SIZE="9" NAME="nif"></TD>

93
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

</TR>
<TR>
<TD>Fecha de Nacimiento:</TD>
<TD>día <INPUT TYPE=text SIZE="2" NAME="dianac">
mes <INPUT TYPE=text SIZE="2" NAME="mesnac">
año <INPUT TYPE=text SIZE="4" NAME="annonac">
</TD>
</TR>
<TR>
<TD>Teléfono:</TD>
<TD><INPUT TYPE=text SIZE="20" NAME="telefono"></TD>
</TR>
<TR>
<TD>Email:</TD>
<TD><INPUT TYPE=text SIZE="30" NAME="email"></TD>
</TR>
</TABLE>
Contraseña (*):
<INPUT TYPE=password SIZE="6" NAME="pass1">
Repita su contraseña:
<INPUT TYPE=password SIZE="6" NAME="pass2">
<BR>
<FONT SIZE=-1> (*) campos obligatorios</FONT>
<BR>
<INPUT TYPE=submit VALUE=Enviar>
<INPUT TYPE=reset VALUE=Borrar>
</FORM>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

Ejemplo 3.14:
Para conocer la opinión de sus clientes y que estos compartan sus impresiones,
Cinem@s implementará un foro (véase Capítulo 17). Los mensajes serán enviados
al foro a través de una página con un formulario como el que puede verse en la
Figura 3.8, y cuyo código completo se incluye a continuación:

<H1>Nuevo mensaje para el foro</H1>


<FORM ACTION="nuevomensaje.php">
<TABLE>
<INPUT TYPE="hidden" NAME="respuestas" VALUE="0">
<INPUT TYPE="hidden" NAME="identificador" VALUE="">

94
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

<TR>
<TD>Autor:</TD>
<TD><INPUT TYPE="text" NAME="autor" SIZE=40></TD>
</TR>
<TR>
<TD>Título del mensaje:</TD>
<TD> <INPUT TYPE="text" NAME="titulo" SIZE=40 VALUE="">
</TD>
</TR>
<TD>Mensaje:</TD>
<TD><TEXTAREA NAME="mensaje" ROWS=6 COLS=30></TEXTAREA>
</TD>
</TR>
<TR><TD> <INPUT TYPE=submit VALUE="Enviar"> </TD></TR>
</TABLE>
</FORM>

Este último formulario tiene dos campos ocultos cuya utilidad se podrá ver cuando
se desarrolle completamente la página destino nuevomensaje.php en el Capítulo 17.

95
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 3.7 Área de clientes de Cinem@s

96
CREACIÓN DE PÁGINAS WEB MEDIANTE EL LENGUAJE HTML

Figura 3.8 Formulario para el envío de mensajes al foro

97
INTRODUCCIÓN A PHP

4.1. EL LENGUAJE PHP


PHP es un lenguaje interpretado del lado del servidor que se caracteriza por su
potencia, versatilidad, robustez y modularidad. Los programas escritos en PHP son
embebidos directamente en el código HTML y ejecutados por el servidor web a
través de un intérprete antes de transferir al cliente que lo ha solicitado un resultado
en forma de código HTML puro. Al ser un lenguaje que sigue la corriente open
source, tanto el intérprete como su código fuente son totalmente accesibles de
forma gratuita en la red. En concreto, la dirección oficial en la que puede
descargarse es:

http://www.php.net/

Por su flexibilidad, PHP resulta un lenguaje muy sencillo de aprender;


especialmente para programadores familiarizados con lenguajes como C, Perl o
Java, debido a las similitudes de sintaxis entre ellos.

Por supuesto, es un lenguaje multiplataforma; los programas funcionan igual sobre


diferentes plataformas, trabajando sobre la mayoría de servidores web y estando
preparado para interactuar con más de 20 tipos de bases de datos. No obstante, al

99
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ser un lenguaje inicialmente concebido para entornos Unix, es sobre este sistema
operativo sobre el que se pueden aprovechar mejor sus prestaciones.

En comparación con otro tipo de tecnologías similares, PHP resulta más rápido,
independiente de la plataforma y más sencillo de aprender y utilizar.

Todas estas características han hecho de este lenguaje uno de los que mayor
crecimiento ha experimentado en los últimos años, desde su aparición en 1994. Es
de destacar especialmente la facilidad para la conectividad con sistemas gestores de
bases de datos a través de un gran número de funciones especializadas. En este
libro en concreto se analizará la conectividad con el sistema gestor MySQL. Esa
facilidad de conexión ha hecho que PHP sea actualmente uno de los lenguajes más
utilizados para la generación de páginas dinámicas, no solo personales sino
también portales de empresas y organizaciones.

Inicialmente diseñado para realizar poco más que contadores y libros de visita de
páginas, en la actualidad PHP permite realizar una multitud de tareas útiles para el
desarrollo web. Por ejemplo, dispone, entre otras, de:

— Funciones de correo electrónico que pueden ser utilizadas para programar completos
sistemas de correo electrónico vía web.
— Funciones de administración y gestión de bases de datos específicas para la mayoría de
gestores comerciales y funciones para conexiones ODBC con bases de datos en
sistemas Microsoft.
— Funciones de gestión de directorios y ficheros, incluso para la transferencia mediante
FTP.
— Funciones de tratamiento de imágenes y librerías de funciones gráficas
— Funciones de generación y lectura de cookies.
— Funciones para la generación de documentos PDF.

A la innumerable cantidad de funciones predefinidas en PHP deben añadirse, por


supuesto todas aquellas funciones propias de cada programador, y que pueden ser
reutilizadas e intercambiadas a través de foros específicos con otros programadores.

4.2. ORÍGENES Y EVOLUCIÓN DEL LENGUAJE


En 1994 un programador de Groenladia, Rasmus Lerdorf, creó el lenguaje PHP con
el objetivo inicial de hacer un seguimiento de los visitantes de su página personal.
El sistema desarrollado originalmente por Lerdorf estaba formado por un conjunto

100
INTRODUCCIÓN A PHP

de scripts programados en Perl que posteriormente serían reimplementados en


lenguaje C con el objeto de obtener mayores funcionalidades. El significado
original del nombre PHP no era otro que Personal Home Page. Adicionalmente
Lerdorf desarrolló un sistema de procesamiento de formularios, sistema que fue
bautizado como FI (Form Interpreter), constituyendo ambos sistemas la primera
versión del actual lenguaje PHP: el PHP/FI. Lerdorf decidió hacer público el
código fuente de sus programas para que cualquiera pudiera utilizarlo; de esta
forma el sistema rápidamente comenzó a ser utilizado por otros usuarios de Internet
y entre todos comenzó a mejorarse el lenguaje, de manera que el actual PHP es
progresivamente construido por colaboradores desinteresados que implementan
nuevas funciones en nuevas versiones del lenguaje.

La versión PHP 1 aparece en la primavera de 1995 y el PHP 2 fue desarrollado


entre 1995 y 1997. En 1997 se estimaba que un 1% de los dominios de Internet
hacían uso del PHP 2.

A mediados de 1997 se produce un cambio importante en el lenguaje, se


reprogramó el analizador sintáctico, se incluyeron nuevas funcionalidades como el
soporte a nuevos protocolos de Internet y a la mayoría de los sistemas gestores de
bases de datos comerciales. Con estas nuevas funcionalidades nace el PHP 3,
además se decide rebautizar el lenguaje dando un nuevo significado a sus siglas:
preprocesador de hipertexto. El PHP 3 se caracterizaba por su gran extensibilidad
y por el diseño de una sintaxis mucho más potente y consistente, además del
soporte de sintaxis orientado a objeto. Se estima, que en su apogeo el PHP 3 llegó a
estar instalado sobre el 10% de los servidores web de Internet.

En el año 2000 surge la siguiente versión del lenguaje: el PHP 4, con una mayor
independencia del servidor web y con un mayor número de funciones disponibles.
Con esta versión se redefine el núcleo del programa, generando un nuevo motor que
mejora la ejecución de aplicaciones complejas, este nuevo motor es bautizado como
“motor Zend”, en honor a sus autores: Zeev Zuraski y Andi Gutmans, quienes al
mismo tiempo fundan la empresa Zend (http://www.zend.com) con el objetivo de
ofrecer productos complementarios y herramientas para el desarrollo en PHP.

La actual versión del lenguaje, PHP 5, fue lanzada oficialmente en septiembre de


2004. Hoy en día se estima que PHP es usado por cientos de miles de
programadores y que está presente en más del 20% de los servidores web en
Internet. Es el sexto lenguaje de programación más utilizado en el desarrollo de
software23, únicamente por detrás de C, Java, C++, Visual Basic y Perl.

23
Estimación de la TIOBE Programming Community en noviembre de 2004. Fuente:
http://www.tiobe.com/tpci.htm

101
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Como prueba del crecimiento experimentado en estos años, la Figura 4.1 muestra
una gráfica con la evolución de dominios y direcciones IP que hacen uso de PHP.
Como puede apreciarse, a inicio de 2005 más de 18 millones de dominios y 1,3
millones de direcciones IP en Internet hacían uso de esta tecnología.

Figura 4.1 Evolución de la presencia de PHP en Internet (Fuente:


http://www.php.net/usage.php )

4.3. PROGRAMACIÓN EN PHP: PRIMEROS


EJEMPLOS
Para empezar a programar en PHP se necesita disponer de una serie de elementos
básicos:

1. Al ser PHP un lenguaje de programación del lado del servidor, lo primero


que se requiere es un servidor web. PHP puede trabajar con la totalidad de
los servidores web más conocidos. Lo más habitual es encontrar PHP sobre
un servidor Apache, pero también es posible instalarlo sobre los servidores
de Microsoft: Microsoft Internet Information Server y Personal Web
Server. Otros servidores posibles serían: Netscape, iPlanet, Oreilly Website
Pro Server, Caudium, Xitami, OmniHTTPd,... En cuanto al sistema
operativo a utilizar también hay diferentes posibilidades: Linux, Unix,
Microsoft Windows, Mac OS X o RISC OS.

102
INTRODUCCIÓN A PHP

2. Sobre el servidor web es preciso instalar el intérprete de PHP. Este


intérprete puede obtenerse en la dirección http://www.php.net y está
disponible para varias versiones de sistemas operativos. En el proceso de
instalación debe configurarse además el servidor web y decidir si dicho
intérprete se ejecutará como módulo o como un CGI independiente.

3. Una vez instalados el servidor web y el intérprete de PHP, ya se está en


condiciones de crear las primeras páginas dinámicas con PHP. En principio
para la creación del código fuente no es necesario disponer de ningún editor
especial, cualquier editor de texto o de HTML podría ser utilizado. Sin
embargo, en Internet pueden encontrarse algunos editores gratuitos específicos
para el lenguaje PHP y que además permiten probar el funcionamiento de los
programas sin necesidad de salir del entorno de edición.

Una vez instalados sobre el equipo a utilizar todas las herramientas necesarias, es el
momento de crear el primer programa en PHP. Por supuesto, se tratará de un
programa muy simple y cuyo interés es meramente educativo.

Ejemplo 4.1:
En un nuevo documento escriba el siguiente código y grábelo en un fichero con la
extensión .php, por ejemplo con el nombre primer.php.

<HTML>
<HEAD>
<TITLE> Primer ejemplo </TITLE>
</HEAD>
<BODY>
<U>
<?PHP
echo "Este es mi primer
programa en PHP";
?>
</U>
</BODY>
</HTML>

Como puede apreciarse, el código tiene la estructura básica de cualquier


documento HTML, con las correspondientes etiquetas que van señalando la
cabecera del documento, el título, el cuerpo,... Pero también puede observarse
cómo dentro del código se encuentra un bloque, señalado con letra negrita, con una
sintaxis diferente. Este bloque es el que inserta dentro del documento un programa
o script en PHP. En este caso se trata de un programa que simplemente usa la
función echo para escribir un mensaje.

103
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El documento anterior debe ser guardado con la extensión .php y no con la


extensión .htm o .html habitual en los documentos HTML. De esta manera,
cuando un cliente solicite al servidor la página, este último sabrá que esa página
incorpora un programa PHP y que por tanto deberá ser pasado al intérprete de PHP
antes de remitir la página al cliente que la ha solicitado.

Para hacer pública esta primera página, el documento primer.php deberá ser
guardado en el directorio que el servidor web tenga establecido para alojar las
páginas. Para probar que la página funciona correctamente, sin necesidad de tener
una salida real a Internet, se podría abrir el navegador web en el propio equipo que
tiene instalado el servidor web y en la barra de direcciones escribir:

http://localhost/primer.php

Por supuesto, es necesario que el servidor web se encuentre en marcha. En este caso
se está usando el mismo ordenador como servidor y como cliente. El nombre
localhost que aparece en la dirección podría ser también sustituido por el nombre
que identifique al equipo.

En la ventana del navegador se podrá ver el resultado esperado (Figura 4.2).

Figura 4.2 Ejecución del primer programa en PHP

104
INTRODUCCIÓN A PHP

La página generada muestra el mensaje indicado en el programa pero subrayado.


Esto último es debido a que el script en el documento se encontraba entre las
etiquetas <U> y </U> que indican el estilo subrayado en HTML.
Si desde el navegador se solicita a este que muestre el código fuente de la página
web que ha recibido, se podría comprobar que dicho código es:

<HTML>
<HEAD>
<TITLE> Primer ejemplo </TITLE>
</HEAD>
<BODY>
<U>
Este es mi primer
programa en PHP</U>
</BODY>
</HTML>

En este código recibido en el cliente no hay ningún elemento que no sea HTML
puro. Esto es debido a que el servidor web, antes de transferir la página al cliente,
se la envió al intérprete de PHP y este ejecutó el programa que estaba integrado en
el documento. Al ejecutar la llamada a la función echo del programa, se escribió
el correspondiente mensaje directamente sobre el código transferido al cliente. Con
este sencillo ejemplo puede verse claramente la forma de trabajo de una tecnología
del lado del servidor como es PHP.

Para probar este ejemplo, se ha utilizado un mismo ordenador en un doble papel:


como servidor web y como cliente que realiza una petición al servidor. Es
conveniente destacar que para poder hacer esto es necesario que la petición de la
página sea realizada desde la dirección del navegador usando el protocolo http,
tal como se ha hecho anteriormente, y no abriendo directamente el documento
como archivo local.

La extensión .php es la más habitual en los documentos que contienen


scripts PHP, sin embargo es posible también encontrar documentos con
otras extensiones como .php3 para documentos que incluyan
NOTA programas en PHP 3, .php4 para los programas en PHP 4, o incluso
la extensión .phtml, actualmente en desuso.

En Ejemplo 4.1 se ha utilizado la función echo para escribir un mensaje en la


página web. Realmente echo es una sentencia del lenguaje más que una función,
obsérvese la no necesidad de utilizar los paréntesis para pasar el argumento. En

105
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

PHP existe otra función que se puede utilizar para ese mismo cometido: la función
print(). En cualquiera de los dos casos, al producirse la escritura sobre el
código HTML que será pasado al cliente, es posible utilizar esas funciones para
generar código HTML dentro de un script PHP. Por ejemplo, el siguiente programa
genera una tabla HTML con el título y director de una película que se encuentran
almacenados en sendas variables ($t y $d).

Ejemplo 4.2:
<?PHP
$t = "Todo sobre mi madre";
$d = "Pedro Almodóvar";
print("<TABLE BORDER>");
print("<TR> <TH>Título</TH> <TH>Director</TH> </TR>");
print("<TR> <TD> ");
print($t);
print("</TD> <TD> ");
print($d);
print("</TD> </TR> </TABLE>");
?>

El programa anterior generaría el código HTML necesario para que el cliente que
accede a la página pueda ver una tabla como la siguiente:

Título Director
Todo sobre mi madre Pedro Almodóvar

En este programa se ha utilizado la función print() en lugar de echo() para


escribir las cadenas, además se hace uso de dos variables inicializadas en el propio
programa. Cuando más adelante se presenten las diferentes formas de dar cadenas
de caracteres en PHP y su relación con las variables, se verá una forma de
optimizar el código anterior reduciendo el número de sentencias de escritura.

Una de las funciones predefinidas en PHP es la función phpinfo()que genera


diversas tablas con gran cantidad de información sobre la configuración de PHP en
el servidor, como por ejemplo, versión del lenguaje, ubicación del fichero de
inicialización, opciones de compilación, sistema operativo del servidor,...

106
INTRODUCCIÓN A PHP

Ejemplo 4.3:
A continuación se muestra un documento HTML que incorpora un script que hace
una llamada a la función phpinfo():

<HTML>
<HEAD><TITLE> Información PHP</TITLE></HEAD>
<BODY>
Opciones de configuración de PHP:
<?PHP
phpinfo();
?>
</BODY>
</HTML>

Ejemplo 4.4:
Finalmente, se incluye a continuación un nuevo sencillo ejemplo de programa en
PHP que es capaz de detectar la hora actual del servidor y mostrar esa información
con un formato preestablecido por el programador. En este caso se utiliza un nueva
función predefinida del lenguaje: la función date(), que permite generar una
cadena de caracteres con una fecha u hora dada y de acuerdo a una cadena de
formato. En el capítulo destinado a funciones predefinidas de PHP, se estudiarán
esta y otras funciones de tratamiento de fechas y horas.

<HTML>
<HEAD>
<TITLE> Cuarto ejemplo </TITLE>
</HEAD>
<BODY>
Bienvenido a esta página, la fecha y hora actual es:<BR>
<B>
<?PHP
print(date("d \de M \de Y, H:i:s"));
?>
</B>
</BODY>
</HTML>

La página que el usuario podría visualizar con su navegador tendría un contenido


como el siguiente:

Bienvenido a esta página, la fecha y hora actual es:


27 de Nov de 2004, 22:43:59

107
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

4.4. FORMAS DE INCRUSTAR EL CÓDIGO PHP


EN LOS DOCUMENTOS HTML
Como ha quedado de manifiesto en el primer ejemplo visto en la sección anterior,
el código de los programas PHP se incrusta directamente entre el código HTML.
Cuando el documento es pasado al intérprete de PHP, este debe saber diferenciar lo
que realmente es código PHP de lo que son etiquetas de HTML. La forma de
conseguirlo es utilizar etiquetas o comandos especiales que señalen el inicio y fin
de cada script PHP; todo lo que quede fuera de esas etiquetas será ignorado por el
intérprete de PHP.

Existen cuatro formas diferentes de diferenciar el código PHP, dos de ellas están
siempre disponibles y las dos restantes dependen de la configuración particular del
servidor.

Las dos formas siempre disponibles de delimitar el código PHP son:

<?PHP
.........................
.........................
.........................
?>

<SCRIPT LANGUAGE="php">
.........................
.........................
.........................
</SCRIPT>

De estas dos formas, la primera es la sintaxis específica del lenguaje PHP, mientras
que la segunda es la sintaxis general que se utiliza para insertar scripts
programados en diferentes lenguajes.

Las otras dos formas de incrustar el código PHP son:

<?
.........................
.........................
.........................
?>
o

108
INTRODUCCIÓN A PHP

<%
.........................
.........................
.........................
%>

La primera de estas sintaxis es la que se denomina de "etiquetas de formato corto"


y requiere que el servidor tenga configurado su fichero php.ini para aceptarlas.
Finalmente, la última sintaxis es la que resulta compatible con ASP, pero tampoco
es aceptada por todos los servidores.

De las cuatro formas de incrustar el código PHP, la más recomendable es la


primera (<?PHP .... ?>), por varias razones: por ser la específica de PHP, por
estar disponible en cualquier servidor, y por ser además la única que permite
incrustar código PHP también en XML y en XHTML. A lo largo de este libro se
utilizará siempre esta sintaxis para insertar los scripts PHP.

Una de las características destacadas de PHP es que los scripts pueden ser
divididos en bloques, y añadir entre los bloques código HTML puro. Esto resulta
especialmente útil cuando dentro de un programa se necesita escribir un texto que
requeriría en otro caso el uso de una serie de funciones echo.

Ejemplo 4.5:
Dado el script siguiente:

<?php
if ($x<0) {
echo "<B> Valor negativo </B>";
echo "<BR> Vuelva a intentarlo";
} else {
echo "<B> Valor positivo </B>";
echo "<BR> Correcto";
}
?>

se podría conseguir el mismo resultado fraccionándolo en bloques y colocando


código HTML entre ellos:

<?php
if ($x<0) {
?>
<B> Valor negativo </B>
<BR> Vuelva a intentarlo
<?php

109
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

} else {
?>
<B> Valor positivo </B>
<BR> Correcto
<?php
}
?>

Ejemplo 4.6:
El ejemplo anterior no tiene mucho interés, pero siguiendo ese mismo esquema se
podría definir, por ejemplo, una página que mostrara diferentes contenidos
dependiendo del navegador que esté usando el cliente.

<?php
if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE")) {
?>
................................
................................
código HTML si el navegador del
cliente es Internet Explorer
................................
................................
<?php
} else {
?>
................................
................................
código HTML para otros navegadores
................................
................................
<?php
}
?>

En este ejemplo se utiliza por un lado la variable global de PHP $_SERVER para
saber el navegador que ha utilizado el cliente para hacer la petición, y la función
strstr() para tratar de localizar la cadena de caracteres "MSIE" en la
identificación del navegador.

Como puede verse en estos ejemplos, la flexibilidad y fluidez lógica del script
permanece intacta a pesar de su ruptura en varios bloques.

110
INTRODUCCIÓN A PHP

4.5. ESCRITURA DEL CÓDIGO FUENTE PHP

4.5.1. ASPECTOS SOBRE LA SINTAXIS DEL


LENGUAJE
La sintaxis del lenguaje PHP es muy similar a la de otros lenguajes conocidos
como C o Perl, algunos aspectos iniciales sobre la sintaxis que deben ser
considerados a la hora de abordar la escritura del código fuente de los programas
son:

— El uso de mayúsculas y minúsculas es indiferente. A diferencia de otros


lenguajes similares, PHP permite que las diferentes sentencias estén escritas
con cualquier combinación de letras mayúsculas o minúsculas. Por ejemplo, en
las estructuras condicionales sería totalmente equivalente utilizar la palabra
reservada if o IF. Una excepción importante a esta regla se produce en los
nombres de las variables; como se verá más adelante, no es lo mismo nombrar
una variable con letras mayúsculas que hacerlo con minúsculas.

— Se pueden colocar todos los espacios en blanco y cambios de línea que se


deseen con objeto de hacer más legible el código fuente. Esos espacios
adicionales no tienen efecto alguno en la ejecución del programa, el intérprete
de PHP los ignora.

— Las diferentes instrucciones deben terminar con ";". Sin embargo PHP admite
cierta flexibilidad a este respecto, ya que el terminador punto y coma no sería
necesario en la última sentencia del script antes de terminador ?>, ni en los
casos en los que al final de la instrucción se cierre un bloque de código con una
llave, por ejemplo en las estructuras condicionales o bucles.

— Las instrucciones se pueden partir en tantas líneas como se desee a efectos, de


nuevo, de mejorar la legibilidad. Esta división de las instrucciones no afecta a
su ejecución.

— En una misma línea se pueden colocar, si así se desea, varias instrucciones


diferentes separadas por ";". Esto puede ser útil en el caso, por ejemplo, de
tener que hacer varias sentencias de asignación diferentes.

111
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

4.5.2. INSERCIÓN DE COMENTARIOS EN EL CÓDIGO


La inserción de comentarios dentro del código fuente no tiene ningún efecto sobre
la ejecución de los programas pero ayuda a hacerlos más legibles. Sobre todo en
proyectos de gran envergadura, la documentación de los programas mediante
comentarios es esencial para facilitar su mantenimiento, y muy especialmente
cuando son varios los programadores que trabajan en un mismo proyecto. Debe
destacarse igualmente que PHP crece gracias al esfuerzo de todos los
programadores que distribuyen libremente sus desarrollos, por lo que el código
distribuido debe estar especialmente bien documentado.

En PHP hay varias formas de incluir comentarios en el código. En primer lugar


están los que usan el estilo de C o C++:

// Comentario estilo C. Hasta fin de línea.

/* Comentario estilo C.
Puede extenderse durante varias líneas.
*/

Cuando PHP se encuentra la pareja de caracteres // considera como comentario


todo lo que le sigue hasta alcanzar el fin de línea o el fin del script, lo que antes
ocurra. Con este estilo, si se quiere que el comentario abarque varias líneas, cada
una de ellas debería ser precedida del correspondiente inicio de comentario //.
Para evitar la innecesaria repetición, se puede utilizar el segundo estilo de
comentarios. Con él, el comentario puede extenderse por varias líneas hasta
encontrar la señal de fin */. Con este segundo estilo hay que prestar especial
atención para evitar anidamientos de comentarios.

El tercer estilo de comentarios es propio del lenguaje Perl, y consiste en utilizar el


signo #, considerándose en este caso como comentario todo lo que le sigue hasta el
fin de línea:

# Comentario estilo Perl. Hasta fin de línea.

112
INTRODUCCIÓN A PHP

4.6. ELEMENTOS BÁSICOS DEL LENGUAJE

4.6.1. TIPOS DE DATOS


Como todo lenguaje de programación, PHP puede trabajar con una serie de tipos de
datos básicos. En concreto los tipos de datos admitidos son:

— Números enteros: los enteros pueden ser dados tanto en base decimal como en
base octal o hexadecimal (un 0 inicial indica que el valor está representado en
octal, un 0x indica que es hexadecimal).
o Ejemplos de números en base 10: 45 -142 783
o Ejemplo de número en octal: 0123 (equivale a 83)
o Ejemplos de números en hexadecimal: 0x12 (equivale a 18)
0x21B (equivale a 539)

— Números en coma flotante: los números en coma flotante se pueden dar en dos
formatos: como parte entera y parte decimal, usando el punto como separador,
o en notación científica:
o Ejemplos: 14.67 -76.0023 1.4e3 -78.5e-4

— Cadenas de caracteres: las cadenas de caracteres pueden ser dadas en dos


formatos: usando comillas dobles o usando comillas simples. El uso de una u
otra forma de delimitación afecta a la forma en la que se tratan las posibles
variables que pueda haber dentro de la propia cadena. Más adelante se
analizará este aspecto.
o Ejemplos: "Casablanca"'Cantando bajo la lluvia'

— Arrays o matrices: los arrays constituyen colecciones de datos que se


referencian bajo un nombre común. Como se verá en el capítulo dedicado a
estas estructuras de datos, PHP admite la posibilidad de construir dos tipos de
arrays: arrays asociativos e indexados.

— Objetos: finalmente PHP admite también la posibilidad de crear objetos y


realizar acciones con ellos. Mediante el uso de objetos se pueden entender
como una misma entidad los datos y las acciones que se realizan con ellos. Esta
es la base de la programación orientada a objetos. Al igual que ocurre con los
arrays, los objetos serán tratados con detalle en un capítulo posterior.

113
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

4.6.2. VARIABLES
Una vez analizados los tipos de datos básicos soportados por PHP, lo siguiente que
se necesita es disponer de "contenedores" que permitan guardar los datos y realizar
operaciones con ellos. Estos contenedores son las variables. Algunas de la
peculiaridades de las variables en PHP son:

— No es necesario declarar explícitamente las variables, sino que basta con


utilizarlas cuando se necesite.
— En principio las variables no tienen un tipo predefinido, puede asignarse
cualquier tipo de valor.
— La asignación de valores a las variables se realiza utilizando el signo "=".
— Los nombres de las variables en PHP siempre comienzan por el signo "$".
— Se pueden utilizar nombres de variables de cualquier longitud, formados por
letras, dígitos y signos de subrayado, pero nunca comenzando por un dígito.
Entre las letras que pueden utilizarse se encuentran los caracteres cuyo código
ASCII se encuentren entre 127 y 255, por lo que se pueden utilizar letras
acentuadas o "ñ" en los nombres de las variables.
— En los nombres de las variables SÍ se distingue el uso de mayúsculas y
minúsculas, de manera que $titulo y $TITULO serían variables diferentes.
— Una misma variable se puede reutilizar asignándole a lo largo del tiempo datos
incluso de distinto tipo.

Serían ejemplos de nombres de variable válidos:

$titulo $fecha_nacimiento $año $precio2

En cambio no serían válidos los siguientes:

$dir-pelicula $4fila genero $dto%

Ejemplo 4.7:
A continuación se incluye un sencillo script que utiliza dos variables para generar
un mensaje:

<?php
$titulo = "Buscando a Nemo";
$sala = 2;

114
INTRODUCCIÓN A PHP

echo "En la Sala $sala se proyectará la película $titulo";


?>

En este caso, a la primera variable se le asigna una cadena de caracteres y a la


segunda un número entero. Las dos variables se utilizan dentro de la cadena a
imprimir; cuando dicha cadena está delimitada por comillas dobles como en este
caso, las variables que se encuentran en su interior serán sustituidas por sus
valores.

Además de las variables propias que el programador pueda utilizar, en PHP existen
un gran número de variables predefinidas a las que se tendrá acceso dentro de los
scripts.

Ejemplo 4.8:
Como se ha comentado, es posible reasignar valores a una misma variable aún
cuando sean de distinto tipo:

<?php
$x = "Importe: ";
echo $x;
$x = 5;
echo $x . " (precio normal) ";
$x = $x * 0.85;
echo $x . " (precio reducido) ";
?>

El resultado del programa sería:

Importe: 5 (precio normal) 4.25 (precio reducido)

Como puede observarse, en este programa se ha utilizado una única variable $x a


la que inicialmente se le asignó una cadena de caracteres, después se le asignó un
número entero y, finalmente, el resultado de una expresión que devuelve un
número en coma flotante.

En este caso se ha utilizado el operador punto para realizar concatenaciones entre


cadenas de caracteres y variables. Esto es una alternativa a la inclusión de las
variables directamente dentro de las cadenas.

En el momento en el que se usa por primera vez una variable y se le asigna un


valor, automáticamente PHP asigna un tipo a dicha variable. Si el valor asignado
cambia de tipo, implícitamente se produce una conversión de tipos en la variable.

115
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Además de esta conversión implícita, el programador puede forzar a la conversión


explícita usando la función settype() o la operación de conversión o cast.

Ejemplo 4.9:
En la siguiente secuencia de instrucciones se producen tres conversiones de tipo
implícitas y una explícita.

$a = "10 euros";
$b = 2.25;
$c = $a - $b; // conversión implícita a tipo float
$d = (integer)$c; // conversión explícita a tipo integer
$e = $d / 2; // conversión implícita a tipo float
echo $e; // conversión implícita a tipo cadena
// finalmente, se escribe el valor 3.5

La primera conversión se produce al realizar una operación numérica como es la


diferencia sobre dos variables de tipos diferentes, la primera una cadena de
caracteres y la segunda un número en coma flotante (float). En esta conversión
la cadena será convertida a su valor numérico equivalente, siendo en este caso 10.
Por tanto el valor de la variable $c sería 7.75. Este valor luego es convertido a
entero, para lo cual se produce un truncamiento de la parte decimal, por tanto, la
variable $d pasa a ser una variable entera con valor 7. Al hacer la división se
produce de nuevo una conversión implícita del resultado a tipo float. Finalmente al
utilizar una variable numérica en una operación de escritura, esta debe ser
convertida a cadena de caracteres.

La conversión de tipo explícita se puede realizar mediante el operador de cast:

(tipo) expresión

o mediante la función settype():

$tlf = (string) 942323305;


$x = (integer) 5.97;
$y = 12.5;
settype($y,"integer");
settype($y,"float");

Otro de los aspectos importantes a tener en cuenta a la hora de trabajar con


variables es el denominado ámbito de las variables. El ámbito determina desde qué
lugares esa variable es visible y, por tanto, puede ser utilizada.

116
INTRODUCCIÓN A PHP

Las variables por defecto tienen un ámbito global que abarcaría el documento
completo en el que son definidas, a no ser que sean definidas dentro de una
función, en cuyo caso solo pueden ser utilizadas dentro de la propia función
(ámbito local).

Esto significa que una variable definida en un script del documento fuera de
cualquier función, puede ser utilizada en cualquier otro lugar de ese script o incluso
en otros posibles scripts que se encuentren en el mismo documento.

Ejemplo 4.10:

<?PHP
...........
$fila = 12;
$num = 6;
...........
?> En este caso el documento incluye dos
scripts, en el primero se definen dos
...........
variables que, al ser globales, pueden ser
<?PHP utilizadas posteriormente en un segundo
........... script.
$asiento =
"F$fila.$num";
...........
?>

Una variable global puede ser utilizada dentro de cualquier función, pero para
hacer referencia a ella debe declararse dentro de la función con la palabra global
delante de su nombre.

Ejemplo 4.11:
$precio = 4.5;

function calcular_importe($num_entradas) {
global $precio;
$i = $precio * $num_entradas;
return $i;
}

117
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En este caso la variable $precio está definida fuera de la función y es utilizada


dentro de la función calcular_importe(). Por otro lado, la variable $i está
definida dentro de la función y no puede ser utilizada fuera de ella.

Más adelante, cuando se explique con detalle la forma de construir funciones, se


volverá a analizar la diferencia entre las variables locales y globales.

Otra peculiaridad del lenguaje PHP en relación al trabajo con variables es la


posibilidad de tener nombres de variables que sean a su vez variables, es decir, que
los nombres puedan establecerse y usarse dinámicamente. Estas variables se
identifican por ir precedidas de dos signos dólar.

Ejemplo 4.12:

$nombrevariable = 'x';
......................
......................
$$nombrevariable = 150; // asignación equivalente a
$x=150

Dado que en PHP las variables no tienen un tipo declarado explícitamente y que
este puede cambiar a lo largo de la ejecución de los programas, se necesita
disponer de alguna forma de saber el tipo de dato que guarda la variable en cada
instante. Para ello PHP incorpora una serie de funciones:

gettype(): devuelve el tipo de la variable.


is_array(): determina si la variable contiene un array.
is_float(): determina si la variable contiene un número en coma flotante.
is_int(): determina si la variable contiene un número entero.
is_object(): determina si la variable hace referencia a un objeto.
is_string(): determina si la variable contiene una cadena de caracteres.

Otra función especialmente interesante es la función isset() que permite


averiguar si una variable ha sido definida. Esta función es especialmente útil
cuando se quiere comprobar si se han recibido los valores correspondientes a todos
los campos de un formulario.

Por otro lado, la función unset() permite eliminar una variable, no solo borra el
contenido de la variable sino que también libera el espacio de memoria reservado
para ella. Cualquier intento posterior de acceso a esa variable generaría un error.

118
INTRODUCCIÓN A PHP

En ocasiones puede interesar también saber si una variable existe pero tiene un
valor nulo o vacío, la función que permite efectuar esta comprobación es
empty().

4.6.3. CONSTANTES
Una constante es un valor que permanece inalterable a lo largo de la ejecución del
script y a la que se le asigna un identificador. Solo pueden definirse constantes con
valores escalares (números o cadenas de caracteres). Por ejemplo, no podría
definirse una constante cuyo valor fuese un array.

La definición de las constantes se realiza con la función define(), y una vez


definidas su valor no puede cambiarse. En cuanto a los identificadores de las
constantes, estos siguen las mismas reglas que los identificadores de las variables
salvo que no comienzan con el signo $. Aunque no es una regla de obligado
cumplimiento, por convenio se suelen utilizar identificadores con letras mayúsculas
para las constantes.

Otra diferencia con las variables está en la ausencia de cualquier restricción de


ámbito en las constantes. Una constante definida en un documento será accesible
desde cualquier punto de cualquier script que esté en el mismo documento.

Ejemplo 4.13:
A continuación se muestra un sencillo ejemplo de definición y uso de constantes:

define("NOMBRE_EMPRESA", "Cinem@s");
define("EDAD_JUBILACION", 65);
define("TIPO_IVA", 0.16);

echo NOMBRE_EMPRESA;

if($edad > EDAD_JUBILACIÓN) {


$base = 3;
} else {
$base = 4.5;
}
$importe = $base*(1 + TIPO_IVA);
echo $total;

El uso de constantes puede resultar especialmente adecuado para definir


determinados parámetros del programa que no se espera que cambien.

119
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El propio PHP incorpora un amplio conjunto de constantes predefinidas; entre ellas


por ejemplo se encuentran TRUE y FALSE que hacen referencia a los valores
booleanos verdadero y falso, respectivamente.

4.6.4. CADENAS DE CARACTERES Y VARIABLES


Como ya se comentó, las cadenas de caracteres constituyen uno de los tipos de
datos básicos del lenguaje PHP. En su definición se pueden utilizar como
delimitadores tanto las comillas simples como las dobles, lo que no es posible es
combinar ambos tipos de delimitadores, por ejemplo abriendo la cadena con
comillas dobles y cerrándola con comillas simples.

Serían cadenas válidas:

"Bailando con lobos" 'El último samurai'

en cambio, no serían válidas:

"Monstruos S.A. "Mulán' "El "último" emperador"

la primera de ellas, por no haber sido cerrada, la segunda, por utilizar diferentes
delimitadores a cada lado, y la tercera, por el hecho de aparecer como un carácter
de la propia cadena las comillas.

En relación a este último error, debe señalarse que, al igual que ocurre en el
lenguaje C, la inclusión de determinados caracteres en las cadenas exige la
utilización de las denominadas secuencias de escape. Entre estos caracteres
especiales están las comillas, el signo dólar, la barra invertida y los caracteres de
tabulación y retorno de carro. La Tabla 4.1 muestra algunas de estas secuencias de
escape.

Secuencia de escape Significado


\n Nueva línea
\r Retorno de carro
\t Tabulador
\\ Barra invertida
\' Comillas simples
\" Comillas dobles
\xNum Carácter cuyo código ASCII en hexadecimal es Num
\Num Carácter cuyo código ASCII en octal es Num
Tabla 4.1 Secuencias de escape

120
INTRODUCCIÓN A PHP

Ejemplo 4.14:
La instrucción PHP:

echo "Página creada por:\n \"CINEM@S\" \t \xA9 2004";

generaría en la página web el mensaje:

Página creada por: "CINEM@S" © 2004

En la cadena anterior se utilizan dos secuencias de escape que no tienen reflejo en la


página que sería visualizada por el navegador del cliente, pero sí en el código fuente
HTML: el carácter de nueva línea y el tabulador se incluirían en el código fuente
HTML, pero, como todos los espacios extra, serían ignorados por el navegador.

Las otras secuencias de escape que han sido utilizadas en el ejemplo son las que
permiten incluir comillas en la propia cadena y que generan el signo copyright
(correspondiente al carácter de código ASCII 169 o A9 en hexadecimal).
La diferencia entre el uso de comillas dobles o simples como delimitadores de las
cadenas de caracteres está en la forma en la que se tratan los posibles
identificadores de variables que aparezcan dentro de la cadena:

— Con las comillas dobles, las variables dentro de la cadena se expanden, es


decir, se sustituyen por su valor.
— Con las comillas simples las variables no se expanden y por tanto en la propia
cadena aparecerán sus identificadores como cualquier otro carácter de la
misma. Además de eso, en este caso las únicas secuencias de escape
reconocidas son \\ y \'.

Ejemplo 4.15:
Si se tienen definidas las siguientes variables:

$titulo = "Todo sobre mi madre";


$director = "Pedro Almodóvar";
$año = 1999;

la sentencia:

print "Sesión especial: \"$titulo\" de $director ($año)";

escribiría el siguiente mensaje:

Sesión especial: "Todo sobre mi madre" de Pedro Almodóvar (1999)

121
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Obsérvese cómo al utilizar las comillas dobles, los nombres de variables que
aparecen dentro de la cadena son sustituidos por sus valores. Esta característica de
PHP es especialmente útil y evita tener que recurrir a engorrosas operaciones de
concatenación de cadenas con variables, tal como ocurre en otros lenguajes.

En cambio, la sentencia:

print 'Sesión especial: \"$titulo\" de $director ($año)';

escribiría el siguiente mensaje:

Sesión especial: \"$titulo\" de $director ($año)

En este caso se observa cómo las secuencias de escape no son reconocidas y se


escriben los nombres de las variables dentro de la cadena y no sus valores.

Existe otra forma de expandir variables dentro de cadenas que PHP hereda del
lenguaje Perl y que fue incorporada en la versión PHP 4. Se trata de la sintaxis de
documento incrustado: se basa en señalar el inicio de la cadena con la secuencia
<<< seguida de un identificador y cerrar la cadena con el identificador elegido.
Entre el inicio y el fin, la cadena puede ocupar incluso varias líneas y en ella todas
las variables que aparezcan se expandirán.

Ejemplo 4.16:
El siguiente código

$titulo = "La gran evasión";


$nacionalidad = "norteamericana";
$director = "John Sturges";
$año = 1963;
$actores = " Charles Bronson, David McCallum,
Donald Pleasence, Gordon Jackson,
James Coburn, James Donald, James Garner,
Richard Attenborough, Steve McQueen";
$dia = "12/5/2004";
$hora = "18:30";
$nsala = 2;
$c = <<<FICHA
<B>$titulo</B>: película de nacionalidad $nacionalidad
dirigida por $director en el año $año y protagonizada
por $actores.
<BR>
La película será proyectada el <U>día $dia a las $hora</U>
en la Sala $nsala.

122
INTRODUCCIÓN A PHP

FICHA;
echo $c;

genera un mensaje como el que sigue:

La gran evasión: película de nacionalidad norteamericana dirigida por John


Sturges en el año 1963 y protagonizada por Charles Bronson, David McCallum,
Donald Pleasence, Gordon Jackson, James Coburn, James Donald, James
Garner, Richard Attenborough, Steve McQueen.
La película será proyectada el día 12/5/2004 a las 18:30 en la Sala 2.

Las cadenas de caracteres son un caso especial de un tipo de datos que se verá más
adelante: los arrays. Por tanto, como en todo array, se puede acceder a cualquiera
de los caracteres que componen la cadena sin más que utilizar un índice numérico.
Los índices deben ser siempre dados entre corchetes y además debe tenerse en
cuenta que el primer carácter de la cadena es el correspondiente al índice 0.

Por ejemplo, dada la cadena: $genero="Comedia", se podría acceder a su


primer carácter usando la sintaxis $genero[0], al segundo mediante
$genero[1], y así sucesivamente.

Al hablar de las conversiones de tipo en las variables, se comentó cómo en


determinadas ocasiones PHP realiza conversiones implícitas. Por ejemplo, cuando
una cadena de caracteres interviene en una expresión aritmética, esta es convertida
a su valor numérico. Para la determinación de ese valor numérico debe tenerse en
cuenta que PHP intenta convertir la cadena en número hasta que se encuentra un
carácter que no tiene sentido numérico, a continuación pueden verse ejemplos de
tales conversiones:

$x = 12 + "23"; // $x tendrá el valor 35


$x = 1 + "0.5"; // $x tendrá el valor 1.5
$x = 4000 + "-1.5e+3"; // $x tendrá el valor 2500
$x = 4 + "5 dias"; // $x tendrá el valor 9
$x = "2 horas" + "10 min"; // $x tendrá el valor 12
$x = 2.5 – "1.2Kg"; // $x tendrá el valor 1.3
$x = 4 + "Tarde"; // $x tendrá el valor 4
$x = 2 * "5 Eur"; // $x tendrá el valor 10
$x = 2 * "Eur 5"; // $x tendrá el valor 0

Por supuesto, PHP dispone de un gran número de funciones predefinidas para


realizar operaciones habituales con cadenas de caracteres: localización de
caracteres, conversiones entre mayúsculas y minúsculas, determinación de la
longitud de las cadenas,... Estas funciones serán presentadas con detalle en el
capítulo destinado a análisis de funciones predefinidas (Capítulo 9).

123
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

4.6.5. OPERADORES

Una vez analizados los tipos de datos básicos del lenguaje y la definición de las
variables y constantes, el siguiente aspecto a revisar lo constituyen el conjunto de
operadores que se pueden utilizar para generar expresiones complejas.

Los operadores se podrían clasificar en diferentes categorías:

— Operadores aritméticos.
— Operadores de asignación.
— Operadores de bit.
— Operadores de comparación.
— Operadores lógicos.
— Otros operadores (concatenación, supresión de error, ejecución,...).

Operadores aritméticos
Los operadores aritméticos básicos son los habituales de cualquier lenguaje de
programación:
$x + $y Suma de dos números
$x - $y Diferencia de dos números
$x * $y Producto de dos números
$x / $y División de dos números
$x % $y Resto de la división entera
Tabla 4.2 Operadores aritméticos

Además de los operadores anteriores se dispone de los operadores de incremento y


decremento que existen también en lenguajes como C o C++.

++$x Incrementa una unidad el valor de $x


$x++ Incrementa una unidad el valor de $x,
pero después de evaluar el resto de la
expresión
--$x Decrementa una unidad el valor de $x
$x-- Decrementa una unidad el valor de $x,
pero después de evaluar el resto de la
expresión
Tabla 4.3 Operadores de incremento y decremento

124
INTRODUCCIÓN A PHP

En su uso más sencillo, los operadores de incremento están pensados para actuar de
contadores; así por ejemplo, las sentencias siguientes serían totalmente
equivalentes:

$x++; ++$x; $x = $x + 1;

Sin embargo, el uso de estos operadores es especialmente útil cuando se incluyen


formando parte de expresiones u otras sentencias más complejas, permitiendo
optimizar el código fuente. Además en este caso el uso de los operadores delante o
detrás de las variables determina el valor final de la expresión.

Ejemplo 4.17:
Para entender la diferencia entre la utilización de los operadores de incremento o
decremento antes o después de la variable, conviene analizar algunos sencillos
ejemplos:

En este caso la variable $n tomará el valor 5 mientras


$n = 5; que $m tendrá el valor 6, ya que el operador de
$m = ++$n; incremento delante de $n hace que el incremento se
realice antes de efectuar la asignación a $m..

Los valores finales de las variables serán 4, 8 y 3 para


$z = 4; $z, $v y $w, respectivamente. En este caso, en la
$v = 2*$z--; segunda sentencia se utiliza el operador de decremento
$w = $z; después de la variable, por lo que el decremento se
produce después de realizar la asignación.

$a = 10; Tras ejecutar estas tres sentencias la variable $a


$b = 2*--$a; tendría el valor 10, la variable $b valdría 17 y $c
$c = ++$a-$b--; valdría –8.

Operadores de asignación
En diversos ejemplos previos ya se ha utilizado el operador de asignación para dar
valores a variables, este operador se representa mediante el signo "=". Su sentido es
el evidente: la variable de la izquierda del operador tomará el valor resultado de la
expresión que se encuentre a la derecha.

$variable = valor ó expresión

125
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Cuando en PHP se realiza una asignación, la sentencia devuelve como valor el


propio valor asignado; esto permite por ejemplo utilizar asignaciones dentro de
otras sentencias de asignación:

$z = ($x = 4) + ($y = 5);

En la sentencia anterior se realizan 3 asignaciones diferentes, por un lado se asigna


el valor 4 a la variable $x y el valor 5 a $y, pero además, teniendo en cuenta que
estas asignaciones devuelven el propio valor asignado, se aprovecha a asignar a $z
el valor resultante de la suma de 4 y 5.

Esta misma particularidad del lenguaje PHP hace que sea posible encadenar varias
asignaciones en una misma sentencia, por ejemplo, las tres asignaciones siguientes:

$a = 1;
$b = 1;
$c = 1;

podrían condensarse en una sola sentencia de la siguiente manera:

$a = $b = $c = 1;

Además del operador básico de asignación (=), PHP permite la utilización de la


asignación combinada con otro tipo de operadores. La sintaxis de esta asignación
combinada es:

$v op= valor; que equivale a $v = $v op valor;

A continuación pueden verse algunos ejemplos de utilización de estas asignaciones


junto con su asignación equivalente:

Asignación combinada Asignación equivalente


$x += 5; $x = $x + 5;
$y *= 2; $y = $y * 2;
$z %= 3; $z = $z % 3;
$c .= "fin"; $c = $c . "fin";
Tabla 4.4 Ejemplos de asignaciones combinadas

126
INTRODUCCIÓN A PHP

Operadores de bit
Los operadores de bit trabajan directamente sobre la representación binaria de los
números enteros, realizando operaciones sobre los diferentes bits de los operandos.
La Tabla 4.5 detalla cuáles son estos operadores y su funcionamiento.

$x & $y Se ponen en 1 los bits que en $x y en $y están


en 1 (Y)
$x | $y Se ponen en 1 los bits que en $x o en $y están
en 1 (O)
$x ^ $y Se ponen en 1 los bits que en $x o en $y están
en 1 pero no en ambos (O exclusivo)
~$x En la representación binaria de $x cambia los
1 por 0 y viceversa (negación)
$x << $n Los bits de $x se desplazan $n posiciones a la
izquierda
$x >> $n Los bits de $x se desplazan $n posiciones a la
derecha
Tabla 4.5 Operadores de bit

Para comprender mejor el funcionamiento de estos operadores se presenta a


continuación un sencillo ejemplo.

Ejemplo 4.18:
Supóngase que se tienen dos variables $x e $y con valores de 214 y 178
respectivamente. Asumiendo una representación binaria con 8 bits, estos dos
valores estarían codificados con las siguientes cadenas de dígitos binarios:

$x = 214 1 1 0 1 0 1 1 0
$y = 178 1 0 1 1 0 0 1 0

Con estos datos, los resultados de algunas de las operaciones de bit anteriores
serían:

$x & $y 1 0 0 1 0 0 1 0 Resultado: 146


$x | $y 1 1 1 1 0 1 1 0 Resultado: 246
$x ^ $y 0 1 1 0 0 1 0 0 Resultado: 100
$x >> 2 0 0 1 1 0 1 0 1 Resultado: 53

127
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Operadores de comparación
En cualquier lenguaje de programación una de las estructuras más comunes son las
condicionales. En ellas se ejecutan una serie de sentencias en función del valor de
una expresión de tipo lógico (verdadero/falso) que con frecuencia proviene de la
realización de una comparación de valores. Los operadores de comparación son los
que realizan estas comparaciones, devolviendo un valor verdadero si la
comparación es positiva o falso en otro caso.

$x == $y Compara si $x e $y tienen el mismo valor


(operador de igualdad)
$x === $y Compara si $x e $y son iguales y además son
del mimo tipo (operador de identidad)
$x != $y Comprueba si $x e $y tienen distinto valor
(negación de igualdad)
$x !== $y Comprueba si $x e $y tienen distinto valor y/o
tipo (negación de identidad)
$x < $y Comprueba si el valor de $x es menor que el
valor de $y
$x > $y Comprueba si el valor de $x es mayor que el
valor de $y
$x <= $y Comprueba si el valor de $x es menor o igual
que el valor de $y
$x >= $y Comprueba si el valor de $x es mayor o igual
que el valor de $y

Tabla 4.6 Operadores de comparación

Quizás convenga realizar algunas observaciones relativas a los operadores de


igualdad y de identidad. En primer lugar, no debe confundirse el operador de
igualdad (==) con el operador de asignación (=). Suele ser bastante frecuente en
programadores principiantes dicha confusión, lo que puede conducir a situaciones
aparentemente tan extrañas como lo que ocurre en el siguiente programa.

Ejemplo 4.19:

$x = 10;
$y = 35;
if ($x = $y)
echo "Los dos valores son iguales";
else
echo "Los dos valores son diferentes";

128
INTRODUCCIÓN A PHP

Sorprendentemente, este programa escribiría el mensaje "Los dos valores son


iguales". En ese programa se ha utilizado la estructura condicional if...else,
que será analizada con calma en el próximo capítulo, para escribir un mensaje u
otro en función del resultado de la expresión $x = $y.

Pero, ¿qué es lo que ha pasado para que el programa indique que las dos variables
tienen el mismo valor cuando claramente eso no es cierto? El problema se ha
debido a que se ha utilizado el operador de asignación en lugar del operador de
igualdad. La asignación $x = $y asigna a la variable $x el valor de la variable
$y y devuelve como valor el valor asignado, en este caso 35. En PHP cualquier
expresión que de como resultado un valor numérico diferente de cero o una cadena
de caracteres no vacía es considerada, a efectos de su participación en expresiones
lógicas, como valor "verdadero". Esta es la razón por la que el programa anterior
escribe el mensaje "Los dos valores son iguales". Para que el programa realmente
escriba ese mensaje cuando los dos valores de las variables sean iguales, se debería
haber utilizado el operador de comparación en lugar del de asignación:

if ($x == $y)
echo "Los dos valores son iguales";
else
echo "Los dos valores son diferentes";

El operador de igualdad es un operador del que disponen todos los lenguajes de


programación; en cambio, el operador de identidad no es un operador muy
frecuente en otros lenguajes, de hecho, en el propio PHP no existía hasta su
aparición en el PHP 4. Se trata de un operador que compara la igualdad de los
valores pero también de los tipos de las respectivas variables. La mejor forma de
entender la diferencia entre el operador de igualdad y el de identidad es a través de
un sencillo ejemplo, las dos variables siguientes

$a = 120;
$b = "120";

tienen tipos diferentes, una corresponde a una variable numérica y la otra a una
cadena de caracteres. Sin embargo, tras la correspondiente conversión, se puede
entender que las dos variables tienen el valor numérico 120. Teniendo en cuenta
esto, la comparación $a == $b produciría un valor "verdadero", mientras que la
comparación $a === $b produciría un valor "falso".

129
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Operadores lógicos
Los operadores lógicos de PHP son los clásicos de cualquier lenguaje de
programación, permiten generar expresiones lógicas complejas conjugando
diferentes subexpresiones.

$x and $y Devuelve un valor cierto cuando tanto $x


$x && $y como $y tienen el valor cierto (operación Y)
$x or $y Devuelve un valor cierto cuando $x o $y
$x || $y tienen el valor cierto (operación O)
$x xor $y Devuelve un valor cierto cuando $x o $y
tienen un valor cierto pero no ambos a la vez
(operación O exclusivo)
!$x Devuelve un valor cierto cuando $x tiene un
valor falso (operación de negación)
Tabla 4.7 Operadores lógicos

Como puede observarse, para los operadores Y y O existen dos sintaxis válidas, el
funcionamiento de las dos es el mismo, la única diferencia estriba en tener
diferentes prioridades a la hora de ser evaluados en expresiones. Tras finalizar este
repaso a los operadores de PHP, la Tabla 4.8 mostrará las diferentes prioridades de
estos.

Otros operadores
Operador condicional:

A continuación se presentan algunos otros operadores que no pertenecen a las


categorías anteriores. En primer lugar destaca la existencia de un operador ternario
(que opera sobre tres argumentos): se trata del operador condicional, cuya sintaxis
es la siguiente:

(condicion) ? (expresion1) : (expresion2)

El funcionamiento es el siguiente: se evalúa la condición y en el caso de ser cierta


se devuelve el valor de la expresión1, si la condición es falsa se devuelve el valor
de la expresión2.

130
INTRODUCCIÓN A PHP

Ejemplo 4.20:
Con la siguiente sentencia se asignaría un valor 1 a una variable $par si el valor
de otra variable $n es un número par, y se asignaría el valor 0 en otro caso. Para
determinar si un número es par se utiliza el operador módulo, que calcula el resto
de la división entera (un número es par si el resto de la división entera entre 2 es 0):

$par = ($n % 2 == 0) ? 1 : 0;

Teniendo en cuenta que en PHP cualquier expresión numérica se considera como


"cierto" si tiene un valor diferente de 0, la sentencia anterior también podría
escribirse de la siguiente manera:

$par = !($n % 2) ? 1 : 0;

Operador de concatenación:

El operador de concatenación permite concatenar cadenas de caracteres. Aplicado


sobre dos cadenas, este operador devuelve como resultado una nueva cadena. La
sintaxis es:

cadena1 . cadena2

Ejemplo 4.21:
Ejemplo de uso de este operador sería:

$titulo = "El último Samurai";


$protagonista = "Tom Cruise";
$anuncio = $titulo . ", con " . $protagonista;

En este caso la variable $anuncio tendría finalmente como valor la cadena "El
último Samurai, con Tom Cruise".

El operador de concatenación también puede ser utilizado combinado con el


operador de asignación:

$actores = "Tom Cruise";


$actores .= ", Timothy Spall";

El resultado final de estas sentencias sería que la variable $actores contendría la


cadena "Tom Cruise, Timothy Spall".

131
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Operador de supresión de error

El signo "@" se utiliza en PHP para identificar al operador denominado de


supresión de error. Este operador hace que el intérprete de PHP no genere mensajes
de error aún cuando detecte situaciones que claramente son erróneas, como por
ejemplo errores de tipo aritmético.

Ejemplo 4.22:
La sentencia

$x = 12/0;

produce un error de tipo aritmético (división por cero) que generaría en la página
un mensaje como

Warning: Division by zero in fichero.php on line n

Estos mensajes en las páginas pueden ser eliminados bien mediante determinados
parámetros de configuración del servidor web o mediante el uso del operador de
supresión de error en la sentencia causante del mismo.

De esta manera, la sentencia

$x = @(12/0);

no genera ningún tipo de mensaje de error. Por supuesto, en este caso la variable
$x no tendría ningún valor (variable vacía).

Operador de ejecución

El operador de ejecución (acento grave: `) se utiliza para indicar a PHP que la


expresión encerrada entre esos acentos graves debe ser tratada como una sentencia
a ejecutar directamente por el sistema operativo del servidor.

Ejemplo 4.23:
Si se quisiera generar una página web que muestre un listado con el contenido del
directorio del servidor en el que está alojada la propia página web, se podría
insertar en la página el script siguiente:

132
INTRODUCCIÓN A PHP

<?php
$x=`dir`;
echo "<pre> $x </pre>";
?>

La página generada, mostraría un listado con el siguiente aspecto:

El volumen de la unidad C no tiene etiqueta.


El número de serie del volumen es: 43F2-A53B

Directorio de C:\home

11/03/2004 18:23 .
11/03/2004 18:23 ..
21/11/2003 19:53 64 Comentarios.txt
21/11/2003 18:07 361 cookie.php
14/11/2003 10:23 315 index.php
21/02/2004 23:24 478 ordenar.php
21/11/2003 19:53 267 prueba.htm
11/03/2004 18:23 205 prueba.php
11/03/2004 18:23 0 ~out.htm
11/03/2004 18:23 205 ~scp.php
8 archivos 1.895 bytes
2 dirs 33.409.753.088 bytes libres

Operador de conversión de tipo (cast)

La conversión explícita del tipo de dato se realiza a través del operador cast:

(tipo) expresión

Ejemplos de uso de este operador serían:

$x = (int)12.67;
$p = (string)4.5;

Orden de prioridad de los operadores


Cuando en una expresión se combinan varios operadores, el orden en el que estos
se aplican es determinante para el resultado final de la expresión.

133
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 4.24:
En la expresión:

$x = 5/2+3*4;
intervienen cuatro operadores diferentes: uno de asignación y tres aritméticos
(división, suma y producto). ¿En qué orden se aplican esos operadores? La
respuesta viene dada por la prioridad que tenga cada uno en una tabla de
prioridades que todo lenguaje de programación maneja. En concreto, los
operadores de asignación son los que menor prioridad tienen, y por tanto este sería
el último en ser aplicado; en cuanto a los operadores aritméticos, los productos y
divisiones tienen mayor prioridad que las sumas y las restas. En definitiva, la
expresión anterior sería evaluada de la manera siguiente:

1. Se realiza la división 5/2, obteniéndose 2.5


2. Se realiza el producto 3*4, obteniéndose 12
3. Se realiza la suma de los dos resultados anteriores, obteniéndose 14.5
4. Se asigna a la variable $x el valor obtenido: 14.5

Si se quiere cambiar el orden de aplicación de los diferentes operadores deben


utilizarse paréntesis para agrupar expresiones. Las expresiones entre paréntesis
serán siempre las que primero se evaluarán, y en el caso de paréntesis anidados,
siempre se comenzará por los más internos.

Como puede verse en los siguientes ejemplos, en la expresión anterior el uso de


paréntesis en diferentes lugares cambiaría radicalmente el resultado final:

$x = 5/(2+3)*4; // $x tendría el valor 4


$x = 5/(2+3*4); // $x tendría el valor 0.35714
$x = 5/((2+3)*4); // $x tendría el valor 0.25

El orden de prioridad de los diferentes operadores es el que viene expresado en la


Tabla 4.8, siempre considerados de mayor a menor prioridad.

134
INTRODUCCIÓN A PHP

Orden de prioridad de operadores (de mayor a menor)


— Paréntesis (empezando por los más internos).
— Operadores de incremento (++), decremento (--), conversión de tipo
y supresión de error.
— Productos, divisiones y módulos (evaluados de izquierda a
derecha).
— Sumas y restas.
— Concatenación de cadenas.
— Operadores de desplazamiento de bits.
— Operadores relacionales (igualdad, desigualdad e identidad).
— Operadores lógicos (& ^ | && ||)
— Operador condicional.
— Operadores de asignación.
— Operadores lógicos (and, or, xor)
Tabla 4.8 Prioridades de los operadores

Obsérvese cómo en la tabla de prioridades los operadores lógicos Y y O se


encuentran en dos niveles diferentes, dependiendo de la sintaxis utilizada (&& o
and, || o or). En principio las dos sintaxis definen el mismo operador, pero la
prioridad es diferente, eso hace que, por ejemplo, las dos expresiones siguientes
produzcan resultados muy diferentes:

$x = 2<5 and 8<7;


$y = 2<5 && 8<7;

El operador lógico Y con la sintaxis and es el que menos prioridad tiene, menos
incluso que el operador de asignación, por eso en la primera sentencia la secuencia
de operaciones sería:

1. Se evalúan las dos condiciones: 2<5 y 8<7, produciendo una de ellas un


valor cierto y la otra falso.
2. A continuación se procede a realizar la asignación del resultado de 2<5 a
la variable $x, por tanto, $x pasará a tener el valor "cierto", que equivale
en un contexto numérico a 1.
3. Finalmente se aplica el operador and, que devolverá un valor falso pero
que no es asignado ya a ninguna variable.

Por tanto, el valor de la variable $x será 1.

En cambio, en la segunda sentencia se utiliza el operador Y con la sintaxis &&, que


tiene más prioridad que la asignación. La secuencia en este caso es:

135
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

1. Se evalúan las dos condiciones: 2<5 y 8<7, produciendo una de ellas un


valor cierto y la otra falso.
2. Se aplica sobre los dos resultados anteriores el operador &&, produciendo
en este caso un valor falso.
3. El valor obtenido se asigna a la variable $y.

En definitiva la variable $y tendría un valor falso, que es equivalente al valor


numérico 0 o a la cadena de caracteres vacía.

Si se deseaba que las dos sentencias tuvieran el mismo efecto, se tendrían que
haber utilizado los paréntesis en la primera para alterar el orden de evaluación.

$x = (2<5 and 8<7); es equivalente a $y = 2<5 && 8<7;

El ejemplo anterior pone de manifiesto que en caso de dudas es mejor


usar paréntesis para asegurarse que el orden de evaluación de las
expresiones es el deseado.
NOTA En una expresión el uso de paréntesis innecesarios no produce ningún
tipo de error pero sí que puede ayudar a clarificar su significado. En
definitiva, es preferible que "sobren" paréntesis a que se obtengan
resultados inesperados por su no utilización.

136
PHP Y LOS FORMULARIOS
DE HTML

5.1. FORMULARIOS DE HTML


Los formularios de HTML constituyen el primer mecanismo de interacción entre
las páginas web y el usuario. A través de sus diferentes campos, los formularios
solicitan al usuario información que podrá ser procesada directamente en la misma
página, enviada al servidor para su procesamiento o enviada a una dirección de
correo electrónico especificada. Para indicar la acción a realizar con esos datos se
utiliza el parámetro ACTION de la etiqueta FORM de definición del formulario. Por
ejemplo, si se quisiera que los datos introducidos por el usuario fueran enviados
automáticamente a una dirección de correo electrónico, la definición del formulario
en HTML se haría de la siguiente manera:

<FORM ACTION="mailto:admin@mimail.com" METHOD="post">


...............................
...............................
...............................
</FORM>

137
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Cada uno de los datos que el usuario introduzca en el formulario estará asociado al
correspondiente campo del mismo, es por ello necesario disponer de un sistema de
identificación de cada uno de esos campos. La identificación se logra asignando a
cada campo un nombre mediante el parámetro NAME de la etiqueta de definición de
campo.

Ejemplo 5.1:
Supóngase que Cinem@s tiene establecidas diferentes tarifas para las localidades
en función de la edad del cliente y de su condición o no de estudiante, y que desea
que los propios clientes puedan calcular exactamente el importe de sus entradas a
través de una sencilla página web. El primer paso resulta evidente: diseñar un
formulario que permita "interrogar" al usuario. El aspecto de ese formulario podría
ser el mostrado en la Figura 5.1.

Figura 5.1 Formulario para el cálculo de precios de entradas

El código HTML que genera este formulario es:

<FORM NAME="miformulario">
Edad: <INPUT TYPE="text" NAME="edad" SIZE="3">
Estudiante:
<INPUT TYPE="radio" NAME="estudiante" VALUE=1> Si
<INPUT TYPE="radio" NAME="estudiante" VALUE=0 CHECKED> No
<BR>
<INPUT TYPE="submit" VALUE="Calcular">
<INPUT TYPE="reset" VALUE="Borrar">
</FORM>

Como puede apreciarse, el formulario tiene asociado un nombre


(miformulario) al igual que cada uno de sus controles:

— El control para introducir la edad es un campo de texto de nombre edad.


— Para indicar si se es o no estudiante se incluye un grupo de dos botones de
radio. Para que ambos botones estén conmutados el nombre asignado a cada
uno debe coincidir (en este caso el nombre es estudiante), distinguiéndose
por el valor de la propiedad VALUE.

138
PHP Y LOS FORMULARIOS DE HTML

— Los dos últimos controles del formulario son el botón para enviar los datos
(submit) y el de reiniciar todos los valores de los campos (reset). A estos dos
controles no es necesario asignarles un nombre ya que no tienen como función
almacenar datos que luego se deban recuperar.

5.2. ENVÍO DE DATOS A PROGRAMAS PHP


Los datos que el usuario introduce en un formulario pueden ser enviados de una
forma sencilla a un programa PHP para su procesamiento. Precisamente esta
sencillez y facilidad de interacción con los formularios HTML es una de las
características más destacadas del lenguaje PHP.

En primer lugar es preciso indicar en el parámetro ACTION de la etiqueta FORM el


documento PHP al que deben ser enviados los datos.

Ejemplo 5.2:
Si se desea que los datos del formulario anterior sean enviados a un programa que
se encuentra en el archivo procesar.php, el formulario debería ser definido de la
siguiente manera:

<FORM NAME="miformulario" ACTION="procesar.php">


Edad: <INPUT TYPE="text" NAME="edad" SIZE="3">
Estudiante:
<INPUT TYPE="radio" NAME="estudiante" VALUE=1> Si
<INPUT TYPE="radio" NAME="estudiante" VALUE=0 CHECKED> No
<BR>
<INPUT TYPE="submit" VALUE="Calcular">
<INPUT TYPE="reset" VALUE="Borrar">
</FORM>

En este caso se está suponiendo que el archivo procesar.php se encuentra alojado


en el servidor en el mismo directorio que el documento HTML que define el
formulario; de no ser así se debería indicar el nombre de ese archivo junto con la
ruta absoluta o relativa para localizarlo.

Una vez indicado el archivo de destino, la pregunta siguiente sería: ¿cómo se


reciben esos datos en el programa PHP?, la respuesta a esta cuestión sorprende por
su simplicidad: el programa PHP recibirá variables con los valores que el usuario
introdujo en los campos del formulario; los nombres de esas variables
corresponderán además con los nombres de los correspondientes controles.

139
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Para poder acceder a las variables de formulario utilizando


directamente el nombre del correspondiente control, el intérprete de
PHP debe estar configurado para ello. En la próxima sección se
NOTA describirá exactamente cuál es esa configuración especial y qué otras
opciones hay para referirse a las variables del formulario.

En el caso del formulario anterior, las variables que se enviarán al documento


destino son: $edad y $estudiante. La primera de las variables contendrá la
cadena de caracteres que el usuario introduzca en el campo edad; la segunda de las
variables contendrá un valor 1 o 0 dependiendo del botón de radio que se encuentre
seleccionado. Los valores posibles para esta última variable coinciden con los
dados en el parámetro VALUE del control del formulario.

$edad
$estudiante Procesar.php

Ambas variables serán accesibles desde cualquier script que se incluya en el


archivo destino: procesar.php. A continuación puede verse cuál podría ser el
contenido de este archivo:

<html>
<head>
<title>Importe de la entrada</title>
</head>
<body>
<?php
if (($edad<12) or ($estudiante))
echo "El precio de la entrada es 3.5 euros";
else
echo "El precio de la entrada es 5 euros";
?>
</body>
</html>

Como puede observarse, el script PHP hace uso de las dos variables que provienen
del formulario para determinar el precio de la entrada. Si la edad del usuario es
menor que 12 o es un estudiante, la página mostrará un mensaje diciendo que el
importe es 3,5 á, en otro caso el importe será 5 á.

La variable $estudiante tendrá un valor numérico 1 si se ha elegido el primer


botón de radio y el valor 0 en el caso del segundo. Cuando los valores numéricos se

140
PHP Y LOS FORMULARIOS DE HTML

utilizan en expresiones lógicas, un valor diferente de cero se considera equiparable


al valor lógico verdadero.

5.3. MÉTODOS DE ACCESO A LAS VARIABLES


DEL FORMULARIO
Cómo ha podido apreciarse, el paso de datos desde los formularios HTML a los
programas PHP es sorprendentemente simple y sencillo, no hay más que hacer uso
de las denominadas variables de formulario. A esas variables se puede hacer
referencia de varias maneras, la más simple es la que se utilizó en el ejemplo
analizado en la sección anterior: el uso de un identificador de variable igual al
nombre del campo del formulario precedido del signo $ (esto es lo que se conoce
como "estilo corto"). Sin embargo, esta opción no siempre está disponible, para
que esto sea posible el archivo de inicialización del intérprete de PHP debe estar
configurado de una manera especial.

Este archivo de inicialización lleva por nombre php.ini y la configuración que se


exige es la activación del parámetro register_globals, en concreto, el
archivo php.ini debería tener la siguiente línea:

register_globals = On

En las primeras versiones del lenguaje PHP este parámetro se encontraba


activado por defecto, sin embargo, en las últimas versiones (desde la 4.2)
viene desactivado por defecto:

register_globals = Off

Por tanto, si el programador quiere hacer uso del estilo corto para hacer referencia
a las variables de formulario debe cambiar ese parámetro.

La razón de este cambio de estrategia en los desarrolladores de PHP al dejar de


considerarlo activado por defecto está en el hecho de que este estilo de acceso es
más proclive a cometer errores que puedan comprometer la seguridad en el código.
De hecho, en el propio archivo de configuración se advierte de este riesgo. Lo que
puede ocurrir al considerar las variables de formulario como globales es que el
programa pueda recibir variables del exterior y que las considere como si fuesen
variables provenientes de un formulario. En la próxima sección se verá cómo es
posible, por ejemplo, pasar variables a un programa directamente en el URL.

141
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

A pesar de estos riesgos, en este libro se utilizará habitualmente el estilo corto en


las variables de formulario por resultar mucho más práctico.

En el caso de que el estilo corto no esté habilitado, o simplemente no se desee


hacer uso de él, en PHP existen otras dos formas de acceder a las variables de los
formularios. La primera de ellas es el uso de un estilo intermedio en el que se
accede a las variables a través de un array asociativo con un índice igual al nombre
del campo del formulario. Esta opción apareció por primera vez en el PHP 4.1. En
concreto, todos los valores que el usuario introduzca en el formulario quedarán
almacenados en el array:

$_REQUEST[]

Adicionalmente también se almacenarán en los arrays:

$_POST[] ó $_GET[]

dependiendo del método utilizado para el envío de los datos del formulario.
Precisamente en la próxima sección se analizarán las diferencias entre ambos
métodos de envío (get y post).

Ejemplo 5.3:
En el caso del formulario de la Figura 5.1, desde el programa PHP se podría
acceder a los datos introducidos por el usuario en los campos edad y estudiante de
la manera siguiente:

$_REQUEST['edad'] ó $_GET['edad']
$_REQUEST['estudiante'] ó $_GET['estudiante']

En este caso, se puede utilizar el array $_GET[] porque el método GET es el


método de envío por defecto de los formularios de HTML. El código completo del
script que recibe los datos del formulario sería:

<?php
if (($_GET['edad']<12) or ($_GET['estudiante']))
echo "El precio de la entrada es 3.5 euros";
else
echo "El precio de la entrada es 5 euros";
?>

Finalmente, en PHP existe otra posibilidad para acceder a las variables del
formulario; se trata de una notación que garantiza el funcionamiento en todos los

142
PHP Y LOS FORMULARIOS DE HTML

servidores e independientemente de la configuración de PHP. En este caso se


vuelven a utilizar dos arrays asociativos:
$HTTP_POST_VARS[] ó $HTTP_GET_VARS[]

de nuevo dependiendo del método de envío de los datos.

Ejemplo 5.4:
A las variables del formulario del Ejemplo 5.1 se puede acceder también de la
siguiente manera:

$HTTP_POST_VARS['edad']
$HTTP_POST_VARS['estudiante']

En la actualidad, este estilo de acceso a las variables se considera obsoleto y es


muy probable que desaparezca, por lo que no se recomienda su uso.

5.4. MÉTODOS DE TRANSFERENCIA DE


DATOS EN FORMULARIOS
Los datos que el usuario introduzca en un formulario de una página web pueden ser
transferidos al servidor para su procesamiento con dos métodos diferentes:
— Método GET: los datos son enviados dentro del URL de localización del
destino.
— Método POST: los datos son enviados de manera "invisible" para el usuario,
haciendo uso del protocolo http y en un encabezado independiente.

El método de transferencia se especifica en la definición del formulario mediante el


parámetro METHOD, asignándole el valor "Get" o "Post" en función del
método elegido. En caso de ausencia de ese parámetro, se considera como método
por defecto el método GET.

En el caso de que los datos deban ser transferidos por correo electrónico, es
obligatorio el uso del método POST.

143
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

5.4.1. MÉTODO GET


Ejemplo 5.5:

Considérese el formulario definido anteriormente. A pesar de que el método de


transferencia es por defecto GET, aquí se indica explícitamente:

<FORM NAME="miformulario" ACTION="procesar.php"


METHOD="Get">
Edad: <INPUT TYPE="text" NAME="edad" SIZE="3">
Estudiante:
<INPUT TYPE="radio" NAME="estudiante" VALUE=1> Si
<INPUT TYPE="radio" NAME="estudiante" VALUE=0 CHECKED> No
<BR>
<INPUT TYPE="submit" VALUE="Calcular">
<INPUT TYPE="reset" VALUE="Borrar">
</FORM>

Si el usuario que accede a esa página rellena el formulario de la siguiente manera:

Figura 5.2 Envío de datos a través del formulario

debería ser transferido el valor 35 para la variable edad y el valor 0 para la


variable estudiante. Con el método GET lo que se hace es añadir esas
asignaciones a continuación del URL de destino (el indicado en el parámetro
ACTION) de la siguiente manera:

...URL...?variable=valor&variable=valor&variable=valor...

En concreto, con los datos anteriores, el URL que se formaría tendría el siguiente
aspecto:

http://miservidor/procesar.php?edad=35&estudiante=0

Este URL sería visible en la barra de dirección del navegador al visualizar la


página resultado (Figura 5.3).

Si el usuario rellena el formulario de la siguiente manera:

144
PHP Y LOS FORMULARIOS DE HTML

el URL que se generaría sería:

http://miservidor/procesar.php?edad=23&estudiante=1

Figura 5.3 Página generada a partir del envío con el método get

5.4.2. MÉTODO POST


Como ha podido apreciarse en los ejemplos anteriores, con el método GET
cualquier persona que vea la página resultado podrá conocer los valores que el
usuario introdujo en el formulario previo, ya que estos son visibles directamente
en la barra de direcciones. Cuando se desea ocultar esa información debe usarse
el otro método de transferencia: el método POST. Con este método los datos son
transferidos en una cabecera http independiente y no son visibles para el usuario.

Ejemplo 5.6:
Si el formulario se define de la siguiente manera:

<FORM NAME="miformulario" ACTION="procesar.php"


METHOD="Post">
Edad: <INPUT TYPE="text" NAME="edad" SIZE="3">
Estudiante:
<INPUT TYPE="radio" NAME="estudiante" VALUE=1> Si
<INPUT TYPE="radio" NAME="estudiante" VALUE=0 CHECKED> No
<BR>

145
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<INPUT TYPE="submit" VALUE="Calcular">


<INPUT TYPE="reset" VALUE="Borrar">
</FORM>

El script recibirá los datos y se ejecutará de la misma manera, pero en la barra de


dirección del navegador cuando se visualice la página generada no podrá verse
ninguna información sobre las variables transferidas (véase Figura 5.4).

Figura 5.4 Página generada a partir del envío con el método post

5.4.3. DIFERENCIAS ENTRE AMBOS MÉTODOS


El uso de uno u otro método de transferencia de datos implica diferentes ventajas e
inconvenientes que se deben tener presentes a la hora de optar por uno de ellos.

Con el método GET:

— La cantidad de información a transmitir está condicionada por la longitud


máxima de los URL que pueden ser procesados por el servidor y el cliente
web.
— Se permite añadir la URL con los datos a la lista de favoritos (bookmarks), de
manera que por ejemplo no sería necesario que el usuario vuelva a introducir
los datos en el formulario, ya que estos quedarían incluidos en el URL
almacenado.
— No se conserva la privacidad de los datos transferidos (aparecen en el URL y
por tanto en la barra de direcciones del navegador, quedan registrados en el
historial,...)

146
PHP Y LOS FORMULARIOS DE HTML

Con el método POST:

— No hay límite en la cantidad de información a transferir, ya que esta se


transfiere de manera independiente.
— No se puede agregar a la lista de favoritos la página destino, ya que para
generarla es necesario que las variables sean transferidas de nuevo
directamente del formulario.
— Los datos transferidos no son visibles en la URL y no quedan registrados en el
historial, conservando de este modo la privacidad.
A la vista de esta diferencias, queda claro por ejemplo que cuando la información
transferida sea confidencial (por ejemplo contraseñas), se debería utilizar el método
POST, además de poder establecer otro tipo de medidas (cifrado de datos,
conexiones seguras,...).

5.5. TRANSFERENCIA DE DATOS AL SCRIPT


DESDE EL URL
Cuando se comentó el riesgo que supone la utilización del estilo corto para
referenciar a las variables de los formularios, se indicó que el usuario podía
transferir directamente variables al script y que estas podrían ser confundidas con
variables que realmente provenían de un formulario. En esta sección se indica una
forma muy sencilla que tiene el usuario para transferir datos a los programas PHP.

Utilizando la misma idea en la que se basa el método GET, es posible transferir valores
para las variables del script directamente desde la barra de direcciones del navegador o
desde un enlace. Se trata, en definitiva, de incluir asignaciones de variables y valores al
final del URL con la misma sintaxis que utiliza el método GET:

http://servidor/script.php?variable1=valor1&variable2=valor2.
..

En el caso de que los valores de alguna de las variables transferidas incluyan


espacios en blanco, estos deben ser sustituidos por el signo '+'.

Ejemplo 5.7:
Si el usuario en la barra de dirección de su navegador escribe el URL:

http://miservidor/favorita.php?titulo=Piratas+del+Caribe

147
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

estaría indicando que se debe transferirse al script que se encuentra en el archivo


favorita.php una variable de tipo cadena de caracteres de nombre titulo y valor
"Piratas del Caribe". El script recibiría esa variable como cualquier otra variable
proveniente de un formulario.

El siguiente script recoge esa variable y muestra a partir de ella un mensaje:

<?php
echo "Su película favorita es \"$titulo\". ";
echo "Muchas gracias por su opinión";
?>

Evidentemente, no es habitual ni recomendable que se solicite al usuario la


introducción de datos de esta manera. En este caso, si el usuario no añade al URL
la variable titulo con su correspondiente valor, el script anterior generaría un
mensaje de error al encontrarse con una variable no definida. La forma de evitar
ese error es utilizar la función isset() que permite averiguar si una variable
concreta se encuentra definida o no:

Ejemplo 5.8:
El siguiente script hace uso de la función isset() para comprobar si la variable
$titulo se encuentra definida, y en función de esa comprobación genera un
mensaje diferente en la página:

<?php
if (isset($titulo)) {
echo "Su película favorita es \"$titulo\".";
echo "Muchas gracias por su opinión";
} else {
echo "No nos ha indicado su película favorita";
}
?>

Otra de las utilidades de esta forma de transferir datos a los scripts es la generación
dinámica de enlaces; en este caso, los URL con las variables son incluidos en
etiquetas HTML de definición de enlaces.

Ejemplo 5.9:
Supóngase que se desea diseñar un formulario para introducir datos de películas y una
serie de enlaces que permitan verificar y confirmar los datos antes de ser enviados al
servidor.

148
PHP Y LOS FORMULARIOS DE HTML

El primer paso sería el diseño del formulario:

Figura 5.5 Formulario de recogida de datos sobre películas

El código HTML que genera este formulario es:

<html>
<head><title>Datos de películas</title></head>
<body>
<form action="procesarpelicula.php">
Titulo: <input type="text" name="titulo" size="90">
<br>
Actores: <input type="text" name="actores" size="85">
<br>
Director: <input type="text" name="direccion" size="40">
<br>
Guión: <input type="text" name="guion" size="30">
Producción: <input type="text" name="produccion"
size="30">
<hr>
Año: <input type="text" name="anno" size="4">
Nacionalidad:
<input type="text" name="nacionalidad" size="15">
Género:
<select name="genero">
<option selected> Comedia
<option> Drama
<option> Acción
<option> Terror
<option> Suspense
<option> Otras
</select>
Duración: <input type="text" name="duracion" size="3">
(minutos)
<br>
Restricciones de edad:
<input type="radio" name="edad" value="Apta">

149
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Todos los públicos


<input type="radio" name="edad" value="Mayores de 7">
Mayores de 7 años
<input type="radio" name="edad" value="Mayores de 18">
Mayores de 18 años
<br>
<input type="submit" value="Enviar">
<input type="reset" value="Borrar">
</form>
</body>
</html>

El usuario podría cumplimentar el formulario con los datos que se muestran en la


Figura 5.6.

Figura 5.6 Introducción de datos de una película

Cuando el usuario pulse el botón "Enviar", los datos serán transferidos al script que
se encuentra en el archivo procesarpelicula.php y cuyo contenido se incluye a
continuación:

<html>
<head><title>Confirmación de datos</title></head>
<body>
Datos recibidos correctamente,
si quiere confirmar los valores active el enlace
correspondiente
<br>
<?php

150
PHP Y LOS FORMULARIOS DE HTML

$url1="confirmar.php?datos=a&titulo=$titulo&" .
"actores=$actores&genero=$genero";
echo "<A HREF=\"$url1\"> Ficha artística </A> <BR>";
$url2="confirmar.php?datos=t&direccion=$direccion&" .
"produccion=$produccion&guion=$guion";
echo "<A HREF=\"$url2\"> Ficha técnica </A> <BR>";
$url3="confirmar.php?datos=o&nacionalidad=$nacionalidad&"
.
"anno=$anno&duracion=$duracion&edad=$edad";
echo "<A HREF=\"$url3\"> Otros datos </A> <BR>";
?>
</body>
</html>

Como puede apreciarse, este script recibe las variables con los datos introducidos
por el usuario y genera de manera dinámica tres simples enlaces, obteniéndose la
página que muestra la Figura 5.7.

Figura 5.7 Página con los enlaces generados dinámicamente

Todos los enlaces tienen como destino un tercer archivo (confirmar.php), pero en
cada uno de ellos se añaden al URL diferentes variables que serán transferidas al
script. Además se utiliza una nueva variable (datos) para que el script destino
sepa cuáles son las variables que vienen dentro del URL que reciba.

El código que se encuentra en el archivo confirmar.php se incluye a continuación.


Como puede apreciarse, el script destino de los enlaces generará una página
diferente en función de las variables que se reciben desde la página origen.

151
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<html>
<body>
<?php
if($datos=="a") {
print "<h1> $titulo </h1>";
print "Género: $genero <br>";
print "Protagonizada por $actores <br>";
}
elseif ($datos=="t") {
print "Dirigida por $direccion <br>";
print "Producida por $produccion <br>";
print "Guión de $guion <br>";
}
elseif ($datos=="o") {
print "Nacionalidad: $nacionalidad <br>";
print "Año: $anno <br>";
print "Duración: $duracion minutos <br>";
print "Autorizada para: $edad <br>";
}
?>
</body>
</html>

De esta manera, dependiendo de cuál sea el enlace que active el usuario, la página mostrará
una información u otra. En concreto, las páginas que se generarán por cada uno de los
enlaces anteriores son las que muestran la Figura 5.8, la Figura 5.9 y la Figura 5.10.

Figura 5.8 Página generada después de seleccionar el enlace "Ficha Artística"

152
PHP Y LOS FORMULARIOS DE HTML

Figura 5.9 Página generada después de seleccionar el enlace "Ficha técnica"

Figura 5.10 Página generada después de seleccionar el enlace "Otros datos"

5.6. TRATAMIENTO DE FORMULARIOS CON


LISTAS DE SELECCIÓN MÚLTIPLE
Cuando los formularios incluyen listas de selección múltiple, debe tenerse en
cuenta que si se desea que se transfieran al script todas las opciones seleccionadas

153
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

por el usuario en la lista, el correspondiente campo no puede tener un nombre


simple como los restantes campos de formulario.

Ejemplo 5.10:
Si se desea diseñar un formulario en el que el usuario seleccione uno o varios
temas de interés dentro de una lista, se podría optar por incluir en la definición del
formulario el siguiente código HTML:

<SELECT MULTIPLE NAME=tema SIZE=5>


<OPTION>Música
<OPTION>Cine
<OPTION>Deportes
<OPTION>Informática
<OPTION>Viajes
</SELECT>

En este caso, la lista viene identificada por el nombre tema. Si el usuario opta por
seleccionar varias opciones de la lista (por ejemplo, tal como muestra la Figura
5.11), cuando los datos se transfieran al script de destino, la variable $tema tendrá
el valor "Informática"; es decir, la variable guardará el valor de la última
opción seleccionada por el usuario.

Figura 5.11 Página que muestra una lista de selección múltiple

Evidentemente, la principal utilidad de las listas de selección múltiple es permitir al


usuario seleccionar varias opciones y que todas ellas puedan ser tratadas
adecuadamente. Para conseguir que al script destino llegue no la última opción

154
PHP Y LOS FORMULARIOS DE HTML

seleccionada sino todas ellas, a la hora de dar un nombre al campo del formulario
se deberían utilizar un par de corchetes vacíos para señalar que realmente se
guardará todo un vector o array de valores.

<SELECT MULTIPLE NAME=tema[] SIZE=5>


<OPTION>Música
<OPTION>Cine
<OPTION>Deportes
<OPTION>Informática
<OPTION>Viajes
</SELECT>

El script recibirá en este caso un array $tema[] que podrá ser procesado para
obtener todas sus componentes individuales. Como se verá en el próximo capítulo
existen incluso estructuras iterativas que permiten recorrer todos los elementos de
un array de una manera simple.

155
SENTENCIAS DE
CONTROL

6.1. INTRODUCCIÓN
Todo lenguaje de programación requiere de estructuras que permitan variar el flujo
normal de ejecución de los programas en función del valor de una expresión o de la
satisfacción de determinadas condiciones. Las denominadas sentencias de control son
las que permiten alterar el orden secuencial habitual en la ejecución de las sentencias.
Básicamente las sentencias de control se clasifican en dos grandes bloques:

— Estructuras condicionales.
— Estructuras iterativas.

Las primeras son las que permiten seleccionar porciones de código a ejecutar si se
cumplen determinadas condiciones; las segundas permiten establecer un bloque de
instrucciones que se ejecutarán un número determinado de veces o mientras se
satisfaga una condición.

En las próximas secciones se analizarán las diferentes sentencias de control


disponibles en PHP a partir de sencillos ejemplos prácticos.

157
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

6.2. ESTRUCTURAS CONDICIONALES

6.2.1. SENTENCIA IF
La primera de las estructuras condicionales con las que cuenta PHP es la sentencia
if. Esta estructura permite ejecutar una sentencia o bloque de sentencias siempre
que se cumpla determinada condición.

Esta sentencia condicional, con su sintaxis propia, está presente en todos los
lenguajes de programación. En el caso del lenguaje PHP la sintaxis es totalmente
similar a la del lenguaje C:

if (expresión)
sentencia

o bien

if (expresión) {
bloque de sentencias
}

Cuando la expresión se evalúa como verdadera, se ejecutan la sentencia o bloque


de sentencias que siguen; en caso contrario, estas sentencias son ignoradas.

Como puede apreciarse, en el caso de que se deseen ejecutar varias sentencias en


función del valor de la expresión, estas deben introducirse entre llaves.

Recordar igualmente que en PHP toda expresión que produzca como resultado un
valor numérico distinto de cero, una cadena diferente de la cadena vacía o un array
no vacío, si aparece dentro de un contexto lógico es tratada como el valor booleano
verdadero (true).

Con objeto de que el código de los programas resulte más legible suele
ser recomendable utilizar diferentes niveles de sangrado para identificar
los bloques de sentencias que se ejecutan en caso de verificarse una
NOTA condición. Debe advertirse sin embargo que esto únicamente tiene un
efecto "estético" en el programa y no influye en la ejecución del mismo.

158
SENTENCIAS DE CONTROL

Ejemplo 6.1:
Considérese el siguiente fragmento de programa en el que se genera un mensaje en
la página solo cuando el valor de la variable $descuento es mayor que 0:

if ($descuento > 0)
print "Artículo con precio rebajado";

Debe tenerse especial cuidado cuando se desea ejecutar más de una sentencia si la
condición es cierta.

Ejemplo 6.2:
Por ejemplo, dada la estructura siguiente:

if ($x > 0)
$y = 2 * $x;
$z = 1 / $x;

si el valor de la variable $x fuese 0 generaría un error de tipo aritmético (división


por cero). ¿Por qué se produce ese error? La razón es que la segunda sentencia de
asignación (la de asignación de valor a la variable $z) sería ejecutada siempre,
independientemente del resultado de la condición $x > 0. El hecho de que esa
sentencia esté en el mismo nivel de sangrado que la sentencia anterior no tiene
ninguna relevancia a efectos de la ejecución; el error que se está cometiendo al
escribir la estructura anterior es el olvido de las llaves para delimitar todo el bloque
de código que debe ejecutarse cuando la condición sea cierta. En ausencia de
llaves, solo se ejecutaría la primera sentencia que se encuentra, quedando la
segunda, por tanto, fuera de la estructura condicional. La forma correcta de escribir
la estructura condicional es:

if ($x > 0) {
$y = 2 * $x;
$z = 1 / $x;
}

Por supuesto, la forma de colocar las llaves para delimitar el bloque se presta a que
cada programador opte por un estilo propio; por ejemplo, se conseguiría el mismo
efecto escribiendo el código de cualquiera de las siguientes maneras:

if ($x > 0)
{
$y = 2 * $x;
$z = 1 / $x;
}

159
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

if ($x > 0)
{$y = 2 * $x;
$z = 1 / $x;}

e incluso

if ($x > 0) { $y = 2 * $x; $z = 1 / $x; }

Las expresiones que determinan la condición de ejecución de las sentencias en la


estructura condicional deben ser siempre dadas entre paréntesis. En este sentido el
lenguaje PHP es sintácticamente más estricto que otros lenguajes.

Ejemplo 6.3:
La sentencia:

if $fila <= 5
$ocupada = true;

produciría un error con el siguiente mensaje:

Parse error: parse error, unexpected T_VARIABLE, expecting '('

por no indicar entre paréntesis la condición. Incluso cuando la condición es una


simple variable de valor lógico, esta debe darse entre paréntesis. Por ejemplo:

if ($ocupada)
print "Lo siento, asiento no disponible";

En las expresiones condicionales es habitual también el uso de los operadores


lógicos para definir condiciones más complejas.

Ejemplo 6.4:
La siguiente estructura condicional escribiría el mensaje "Lo siento, asiento no
disponible" cuando la variable $fila tome un valor entre 10 y 12 o la variable
$vendida tenga el valor true. Obsérvese de nuevo la necesidad de introducir
toda la condición entre paréntesis y usar igualmente paréntesis para establecer el
orden de evaluación de la expresión.

if ((($fila >= 10) and ($fila <= 12)) or $vendida)


print "Lo siento, asiento no disponible";

160
SENTENCIAS DE CONTROL

Finalmente, en relación a la condición, advertir de nuevo algo que ya se comentó a


la hora de presentar los diferentes operadores del lenguaje: debe tenerse especial
cuidado en no confundir el operador de comparación de igualdad con el de
asignación.

Ejemplo 6.5:
La sentencia

if ($fila = 15)
print "Última fila de la sala";

escribiría siempre el mensaje "Última fila de la sala" independientemente del valor


de la variable $fila, ya que en la propia estructura condicional se está realizando
una asignación del valor 15 a esa variable y no una comparación. La estructura
condicional correcta sería:

if ($fila == 15)
print "Última fila de la sala";

Por supuesto, las estructuras condicionales pueden anidarse unas dentro de otras.

Ejemplo 6.6:

if ($fila <= 5) {
print "Fila próxima a la pantalla";
if (($asiento == 1) or ($asiento == 20)) {
print "Mala visibilidad de la pantalla";
}
}

En este caso cuando la variable $fila toma un valor menor o igual que 5 se
advierte al usuario de la proximidad a la pantalla; si además de eso el asiento
corresponde a los números 1 ó 20, se advierte de una mala visibilidad.

Ya se ha comentado que las expresiones que se evalúan en las condiciones, pueden


ser no solo expresiones lógicas, sino también expresiones numéricas, cadenas de
caracteres o incluso arrays. Cualquier expresión numérica que dé como resultado
un número diferente de 0, o cualquier cadena o array no vacío equivale al valor
lógico true.

161
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.7:
La sentencia

if($precio)
print "El precio es $precio euros";

escribiría un mensaje con el precio cuando el valor de la variable sea diferente de


cero (valor true).

Ejemplo 6.8:
La sentencia

if(!$nombre)
print "Por favor, díganos su nombre";

mostraría el mensaje cuando la variable $nombre tenga como valor la cadena de


caracteres vacía.

6.2.2. LA CLÁUSULA ELSE


Es frecuente encontrarse con situaciones en las que se quiere que un bloque de
sentencias sea ejecutado cuando se cumpla cierta condición, y otro bloque lo sea
cuando esa condición es falsa. En principio esto podría conseguirse encadenando
dos sentencias condicionales if; sin embargo existe una forma mucho más
efectiva de programar estas estructuras: el uso de la cláusula else dentro de la
sentencia if.

La sintaxis concreta de la sentencia if...else sería:

if (condición)
{
sentencias a ejecutar si la condición es cierta
}
else
{
sentencias a ejecutar si la condición es falsa
}

Las sentencias del bloque else se ejecutarán solamente si la condición se evalúa


como falsa.

162
SENTENCIAS DE CONTROL

De nuevo, en caso de que alguno de los bloques esté constituido por una única
sentencia, las llaves podrían suprimirse.

Ejemplo 6.9:
Supuesto que la variable $edad guarda la edad de una persona, y se desea asignar
valores diferentes a la variable $precio para los niños menores de 12 años o
jubilados y para el resto de personas, se podría escribir una sentencia condicional
con una cláusula else:

if (($edad < 12) or ($edad >= 65))


$precio = 3.5;
else
$precio = 4.75;

Ejemplo 6.10:
La sentencia

if($precio)
print "El precio es $precio euros";
else
print "Entrada gratuita";

escribiría el mensaje con el precio cuando la correspondiente variable tenga un


valor diferente de cero (equivalente a true) y escribiría "Entrada gratuita" en
otro caso (valor numérico 0, o equivalentemente false).

Obsérvese cómo en ambos casos las llaves han podido suprimirse por estar
constituidos los bloques por una sola sentencia. De todas formas debe tenerse un
especial cuidado con la supresión de esas llaves porque pueden provocar errores
que en ocasiones resultan difíciles de detectar.

Ejemplo 6.11:
Considérese la estructura condicional siguiente:

if ($num == 126)
$fila = 12;
$asiento = 8;
else
$fila = 10;
$asiento = 6;

163
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Tal como está escrita se generaría el siguiente error:

Parse error: parse error, unexpected T_ELSE

debido a que al no utilizar llaves en el bloque a ejecutar en el caso de que la


variable $num tome el valor 126, la segunda de las sentencias de ese bloque haría
finalizar la estructura condicional.

En cambio, la sentencia

if ($num == 126) {
$fila = 12;
$asiento = 8;
}
else
$fila = 10;
$asiento = 6;

no produce ningún error, pero tampoco produce el efecto deseado, ya que la


ausencia de llaves en el bloque else hace que la segunda sentencia del bloque se
considere fuera de la estructura condicional y por tanto se ejecuta siempre,
independientemente del valor de la condición. De manera que, por ejemplo, si la
variable $num tiene el valor 126, después de esas sentencias $fila valdría 12
pero $asiento valdría 6.

En definitiva, la estructura condicional correcta requiere en este caso agrupar entre


llaves cada uno de los bloques de sentencias a ejecutar:

if ($num == 126) {
$fila = 12;
$asiento = 8;
}
else {
$fila = 10;
$asiento = 6;
}

Además de las sentencia if...else, PHP dispone del operador


condicional que ya fue presentado cuando se mostraron los diferentes
operadores del lenguaje. Este operador condicional resulta útil para
NOTA realizar sencillas asignaciones en las que el valor asignado dependa del
resultado de una condición.

164
SENTENCIAS DE CONTROL

6.2.3. SENTENCIA IF ... ELSEIF ... ELSE


Por supuesto, las estructuras if pueden encadenarse una tras otra o anidarse para
poder indicar bloques de sentencias a ejecutar en función de varias condiciones
diferentes; de todas formas, existe una estructura condicional optimizada que
permite realizar esta acción, se trata de la estructura if...elseif...if. La
sintaxis general de esta sentencia es:

if (condición1)
{
sentencias a ejecutar si la condición1 es cierta
}
elseif (condición2)
{
sentencias a ejecutar si la condición2 es cierta
}
elseif (condición3)
{
sentencias a ejecutar si la condición3 es cierta
}
...
else
{
sentencias a ejecutar si ninguna de las
condiciones anteriores es cierta
}

Como en las estructuras condicionales anteriores, cuando los bloques de órdenes a


ejecutar en cada caso están compuestos por una única sentencia, las llaves se
pueden suprimir. Además, debe indicarse que es igualmente opcional la utilización
de la cláusula else para indicar sentencias a ejecutar cuando todas las condiciones
sean falsas.

El funcionamiento de esta sentencia es el esperado: si la primera condición es


evaluada como cierta, entonces se ejecutan las sentencias del bloque
correspondiente y tras ello finaliza la ejecución de la sentencia. En el caso de que la
primera condición sea falsa, el intérprete continuará evaluando de manera
consecutiva las siguientes condiciones hasta encontrar la primera que es cierta, en
cuyo caso se ejecutan las sentencias de su bloque y se finaliza. Es de destacar, por
tanto, que el orden en el que se indiquen las diferentes condiciones resulte decisivo,
ya que únicamente se ejecutará el bloque asociado a la primera condición cierta,
ignorando los restantes bloques aunque su condición pueda ser igualmente cierta.

165
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.12:
La siguiente estructura condicional asigna diferente valor a la variable $precio
en función del valor de la variable $edad:

if ($edad < 3) {
$precio = 0;
}
elseif ($edad <= 16) {
$precio = 8;
}
elseif ($edad > 16 and $edad < 65) {
$precio = 12;
}
else {
$precio = 10;
}

En este caso, las llaves de cada bloque podrían suprimirse.

Comentar igualmente que la estructura anterior se podría escribir también en la


forma:

if ($edad < 3) {
$precio = 0;
}
else
if ($edad <= 16) {
$precio = 8;
}
else

if ($edad > 16 and $edad < 65) {


$precio = 12;
}
else {
$precio = 10;
}

En este caso se estarían utilizando tres sentencias condicionales anidadas.

Como puede observarse en este ejemplo, en una estructura condicional se


conseguiría el mismo efecto utilizando la palabra elseif o las palabras else
if, a pesar de tener diferente significado sintáctico (en el primer caso se estaría

166
SENTENCIAS DE CONTROL

ante una sola sentencia y en el segundo ante dos sentencias condicionales


anidadas).

Ejemplo 6.13:
Supóngase que se desea que una página web muestre un mensaje de bienvenida
diferente dependiendo de la hora del día; por ejemplo, considérese el siguiente
script:

$hora=date("H");
if ($hora<5)
print("Buenas noches, ");
elseif ($hora<12)
print("Buenos días, ");
elseif ($hora<20)
print("Buenas tardes, ");
else
print("Buenas noches, ");
print("bienvenido a nuestra página web");

En este caso se generaría un mensaje de "Buenas noches", "Buenos días" o


"Buenas tardes" en función del valor de la variable $hora. Para saber la hora
actual se hace uso de la función date() que será estudiada con detalle en el
capítulo dedicado a las funciones predefinidas en PHP (Capítulo 9). Esta función se
puede utilizar para obtener tanto fechas como horas en diferentes formatos, para
ello se debe indicar como argumento una cadena de caracteres que actúa de patrón
de formato. En este caso la cadena "H" indica que lo que se desea obtener es el
número de hora de 0 a 23.

Debe recordarse que PHP es un lenguaje de programación del lado del


servidor, lo que significa que los programas son ejecutados en el
servidor y no en el cliente. Por tanto, la fecha y la hora que se obtienen
NOTA con la función date() serían las del servidor, que no necesariamente
coinciden con la fecha y hora del cliente que acceda a la página.

6.2.4. SINTAXIS ALTERNATIVA DE LAS SENTENCIAS IF


PHP admite una sintaxis alternativa para la construcción de estructuras
condicionales; con esta sintaxis el bloque de sentencias a ejecutar se delimita entre
el signo ':' y la palabra reservada endif:

167
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

if (condición) :
sentencias a ejecutar si la condición es cierta
endif;

Ejemplo 6.14:
Un sencillo ejemplo de construcción de una estructura condicional con esta sintaxis
sería:

if ($x != 0) :
$y = 1 / $x;
endif;

en este caso se asigna a la variable $y el inverso del valor de $x siempre que este
último sea diferente de 0.

En las estructuras if...elseif...else también es posible utilizar esta


sintaxis alternativa;

Ejemplo 6.15:

if ($y == 1):
$z = 3;
elseif ($y == 2):
$z = 5;
else:
$z = 7;
endif;

Una de las características más sorprendentes, pero al mismo tiempo más


útiles, del lenguaje PHP es la posibilidad de partir una estructura en dos
scripts diferentes, integrando entre ellos código HTML puro. En el caso
NOTA de estructuras condicionales esta posibilidad permite enviar al cliente
un código HTML solo cuando se verifique determinada condición.

La sintaxis alternativa de las sentencia if resulta especialmente apropiada cuando


se desea fraccionar la estructura en dos o más scripts, ya que el inicio y final de
cada bloque queda señalado de forma muy clara y sin prestarse a confusión.

168
SENTENCIAS DE CONTROL

Ejemplo 6.16:
El siguiente fragmento de código incluye dos scripts entre los que se está
colocando código HTML puro. En este caso, el primer script comienza una
estructura condicional en la que se pregunta si la variable $edad se encuentra
definida y si su valor es menor que 7; en caso de que esto ocurra la página
mostrará una lista HTML con un conjunto de películas autorizadas para todos los
públicos.

<?php if (isset($edad) and ($edad < 7)) : ?>


Listado de películas <U>autorizadas para todos los
públicos</U>:
<UL>
<LI>Nemo
<LI>Hermano Oso
<Ul>
<?php endif; ?>

Obsérvese cómo después de incluir el código HTML de definición de la lista, un


nuevo script PHP cierra la estructura condicional abierta en el primer script. Por
supuesto, el mismo efecto se podría haber conseguido con un único script en el que
todas los comandos HTML fuesen generados con las funciones echo() o
print(), pero sin lugar a dudas, esta posibilidad de "romper" la estructura
condicional permite escribir ese código HTML de una manera mucho más sencilla.

6.2.5. ESTRUCTURAS CONDICIONALES


SWITCH...CASE
La sentencia switch permite definir estructuras condicionales en las que
diferentes bloques de sentencias serán ejecutados dependiendo del valor de una
misma variable o expresión. En principio cualquier estructura switch se podría
escribir de forma equivalente con una sentencia if...elseif...else, sin
embargo, las sentencias switch facilitan la generación de la estructura cuando lo
que se quiere comprobar en todas las condiciones es el valor que toma una misma
variable o expresión.

La sintaxis básica de la sentencia es:

switch (expresion) {
case valor1:
sentencias
case valor2:

169
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

sentencias
...
case valorN:
sentencias
default:
sentencias
}

Esta sentencia evalúa la expresión y sucesivamente compara el valor devuelto con


los valores que van apareciendo en cada una de las cláusulas case, cuando el
valor coincide ejecuta las sentencias que van a continuación hasta llegar al final de
la estructura o encontrarse una sentencia de finalización break.

La cláusula default es opcional y permite indicar las sentencias a ejecutar


cuando la expresión no toma ninguno de los valores anteriores.

La expresión que se evalúa y compara en la estructura switch puede ser


cualquier expresión que se evalúe a un tipo simple, es decir, números enteros o de
punto flotante y cadenas de caracteres. En cada una de las cláusulas case se puede
indicar uno de los valores admisibles de la expresión, pero no se pueden indicar
condiciones lógicas sobre esos valores.

Ejemplo 6.17:
A continuación se presenta un sencillo ejemplo de estructura condicional switch
con su estructura equivalente if...elseif...else, en este caso la estructura
se encarga de asignar diferentes valores a la variable $precio en función del
valor que tome otra variable $dia:

switch ($dia) {
case 'L':
$precio = 4;
break;
case 'M':
$precio = 3;
break;
case 'X':
$precio = 4.5;
break;
case 'J':
$precio = 4.5;
break;
case 'V':
$precio = 5;

170
SENTENCIAS DE CONTROL

break;
case 'S':
$precio = 5;
break;
case 'D':
$precio = 4.5;
break;
}

La sentencia if equivalente sería:

if ($dia == 'L')
$precio = 4;
elseif ($dia == 'M')
$precio = 3;
elseif ($dia == 'X')
$precio = 4.5;
elseif ($dia == 'J')
$precio = 4.5;
elseif ($dia == 'V')
$precio = 5;
elseif ($dia == 'S')
$precio = 5;
elseif ($dia == 'D')
$precio = 4.5;

En una sentencia switch la condición, o expresión que la define, se evalúa solo


una vez y el resultado se compara con cada uno de los valores que aparecen en las
cláusulas case. En una sentencia if..elseif...else, en cambio, la
condición se evalúa en cada una de las cláusulas elseif, por lo que a efectos de
ejecución y dependiendo de la complejidad de la condición, las estructuras
switch pueden resultar más rápidas que sus equivalentes estructuras if.

Debe tenerse presente la forma en la que se ejecuta la sentencia


switch: cuando el valor de la expresión coincide con alguno de los
valores dados en la sentencia, se ejecutan todas las sentencias que van a
NOTA continuación hasta encontrarse una sentencia break o alcanzar el final
de la estructura. Si no aparece ningún break, se seguirán ejecutando
las sentencias correspondientes a los siguientes bloques case. Esta
particularidad suele ser fuente de errores en programadores noveles.

171
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.18:
Si la sentencia switch anterior se hubiese escrito de la forma siguiente:

switch ($dia) {
case 'L':
$precio = 4;
case 'M':
$precio = 3;
case 'X':
$precio = 4.5;
case 'J':
$precio = 4.5;
case 'V':
$precio = 5;
case 'S':
$precio = 5;
case 'D':
$precio = 4.5;
}

el valor de la variable $precio siempre sería 4.5 ya que al no existir ninguna


sentencia break, en cuanto la variable $dia tome uno cualquiera de los 7 valores
predefinidos, se ejecutarían todas las sentencias correspondientes hasta el final y
por tanto la única asignación que tendría efecto es la última. Para evitar esto es para
lo que se utiliza la orden break al final del bloque de sentencias que se deseen
ejecutar en cada caso. De esta manera, cuando el valor de la variable coincide con
uno de los valores preestablecidos se procede a la asignación del valor
correspondiente a $precio y se abandona la estructura. Evidentemente, el último
break no sería necesario.

En el caso de que el valor de la variable $dia no coincida con ninguno de los


valores predefinidos (L, M, X, J, V, S y D), la variable $precio no tendría
ningún valor asignado. Si se desea evitar esto podría utilizarse la cláusula
default para establecer un valor a asignar por defecto:

switch ($dia) {
case 'L':
$precio = 4; break;
case 'M':
$precio = 3; break;
case 'X':
$precio = 4.5; break;
case 'J':
$precio = 4.5; break;

172
SENTENCIAS DE CONTROL

case 'V':
$precio = 5; break;
case 'S':
$precio = 5; break;
case 'D':
$precio = 4.5; break;
default:
$precio = 0;
}

Finalmente, indicar que es posible que la lista de sentencias de un case se


encuentre vacía, en cuyo caso, al no encontrar tampoco ninguna sentencia break,
el programa pasaría a ejecutar las sentencias del siguiente case. Esta característica
permite optimizar el código de estructuras switch en las que un mismo conjunto
de sentencias se repiten para diferentes casos, tal como ocurre, por ejemplo, en la
estructura anterior en la que hay asignaciones iguales en diferentes casos. Teniendo
en cuenta esta observación, la sentencia anterior podría escribirse de la siguiente
manera:

switch ($dia) {
case 'L':
$precio = 4;
break;
case 'M':
$precio = 3;
break;
case 'X':
case 'J':
case 'D':
$precio = 4.5;
break;
case 'V':
case 'S':
$precio = 5;
break;
default:
$precio = 0;
}

Al igual que ocurría con la sentencia if, la sentencia switch dispone de una
sintaxis alternativa en la que el inicio del bloque de casos se señala con un signo ':'
y el final de la estructura con la palabra endswitch. A continuación se puede ver
un sencillo ejemplo con esta nueva sintaxis.

173
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.19:

switch ($nombre) :
case 'Juan':
case 'Pedro':
case 'Daniel':
print("Soltero");
break;
case 'Ana':
case 'Luis':
print("Casado");
break;
default:
print("Desconocido");
endswitch;

Ejemplo 6.20:
Como ejemplo final, supóngase que se desea calcular el número de días que tiene
un mes concreto, considerando además si el año es bisiesto o no (un año es bisiesto
cuando es múltiplo de 4 pero no de 100, o bien cuando es múltiplo de 400).
Supóngase que las variables $mes y $anno identifican el mes concreto del que se
desea conocer el número de días, el siguiente programa asigna ese número a la
variable $nd:

switch($mes) {
case 2:
if((($anno%4==0) and ($anno%100!=0)) or
($anno%400==0))
$nd=29;
else
$nd=28;
break;
case 4: case 6: case 9: case 11:
$nd=30;
break;
default:
$nd=31;
}

174
SENTENCIAS DE CONTROL

6.3. ESTRUCTURAS ITERATIVAS


La segunda categoría de estructuras de control está constituida por las sentencias
que permiten construir bucles; es decir, que permiten ejecutar varias veces de
forma iterativa un mismo conjunto de instrucciones.

6.3.1. SENTENCIA WHILE


Los bucles construidos con la sentencia while constituyen las estructuras
iterativas más simples con las que cuenta el lenguaje PHP. En este caso, las
sentencias que constituyen el cuerpo del bucle se ejecutarán mientras el valor de
una expresión lógica sea verdadero. La sintaxis de la sentencia es:

while (expresión)
sentencia

En el caso de que el cuerpo del bucle esté formado por más de una sentencia, estas
deben ser dadas entre llaves:

while (expresión) {
sentencias
}

La expresión es evaluada cada vez que se inicie una iteración del bucle, pudiéndose
dar el caso incluso de que las sentencias del bucle no se ejecuten ni una sola vez si
la expresión es inicialmente falsa. Por supuesto, dentro del bloque de sentencias a
ejecutar en cada iteración debe haber alguna que modifique el valor de la
expresión, ya que en caso contrario se entraría en un bucle infinito.

Al igual que ocurre con las restantes sentencias de control, existe una sintaxis
alternativa de la sentencia while:

while (expresión) :
sentencias
endwhile;

Dentro del bloque de sentencias a ejecutar, en cada iteración pueden incluirse


sentencias condicionales u otras estructuras iterativas anidadas.

175
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.21:
Mediante el siguiente programa se genera una lista HTML con los múltiplos de 5
menores o iguales que 100:

print "<OL>";
$n = 5;
while ($n <= 100) {
print "<LI> $n";
$n += 5;
}
print "</OL>";

6.3.2. SENTENCIA DO...WHILE


Los bucles do...while son muy similares a los bucles while, la única
diferencia es que la condición es comprobada al final de cada iteración en lugar de
hacerlo al comienzo. Esta diferencia en el momento de comprobación de la
condición hace que en un bucle do...while se tenga garantizada la ejecución de
las sentencias del cuerpo del bucle al menos una vez. La sintaxis de la sentencia
do..while es la siguiente:

do
{
sentencias
}
while (condición);

En el caso de esta sentencia, no existe sintaxis alternativa.

El funcionamiento del bucle es el obvio: mientras la condición sea cierta se


ejecutan las sentencias del cuerpo del bucle.

Ejemplo 6.22:
El bucle para generar una lista con los múltiplos de 5 menores o iguales que 100
también podría construirse utilizando esta sentencia:

print "<OL>";
$n = 5;
do {
print "<LI> $n";
$n += 5;

176
SENTENCIAS DE CONTROL

}
while ($n <= 100)
print "</OL>";

En este caso concreto, ambas estructuras iterativas (bucle while y bucle


do...while) producen exactamente el mismo resultado; sin embargo, en otros
casos el uso de una u otra estructura puede conducir a resultados diferentes, tal
como puede verse en el siguiente ejemplo.

Ejemplo 6.23:
Considérese el siguiente bucle:

$n = 0;
while ($n > 0) {
print $n;
$n--;
}

En este caso, al utilizarse la sentencia while, la condición del bucle se comprueba


al inicio de cada iteración y por tanto, al no verificarse ni siquiera en la iteración
inicial el bucle no se ejecutaría ni una sola vez.

En cambio, si se utiliza la sentencia do...while para definir el bucle:

$n = 0;
do {
print $n;
$n--;
}
while ($n > 0);

la condición se comprobará después de cada iteración, por tanto, el cuerpo del


bucle se ejecuta una vez y después se comprueba la condición; al no verificarse
esta, el bucle finaliza. En definitiva, la sentencia habrá escrito el valor 0 y al salir
del bucle la variable $n tendrá el valor –1.

Ejemplo 6.24:
A continuación se muestra el uso de la sentencia do...while para comprobar la
conjetura de Collatz, que establece que cualquiera que sea el número entero
positivo n de partida, la sucesión de números enteros f(n), f(f(n)), f(f(f(n))),...
siempre llega a alcanzar el valor 1, siendo f(n) la siguiente función:

177
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

­n / 2 si n es par
f ( n) = ®
¯(3n + 1) / 2 si n es impar

En el siguiente programa se asume que $n contiene el valor de partida (por


ejemplo, podría venir de un formulario previo). Con ese valor inicial se construye
un bucle que finaliza cuando se alcanza el valor 1. En cada una de las iteraciones
del bucle se redefine $n aplicando sobre el valor previo la función de Collatz y se
van introduciendo los resultados en un control de tipo lista de HTML.

print "<SELECT>";
print "<OPTION> Valor inicial: $n";
$niter = 0;
do {
if($n%2==0) {
$n = $n/2;
}
else {
$n = (3*$n+1)/2;
}
$niter++;
print "<OPTION> Iteración $niter: $n";
} while ($n!=1);
print "</SELECT>";

Por ejemplo, asumiendo que el valor inicial es 23, se generaría una lista como la
que se muestra en la Figura 6.1.
.

Figura 6.1 Resultado de la ejecución del programa para el valor inicial 23

178
SENTENCIAS DE CONTROL

6.3.3. SENTENCIA FOR


La sentencia for es la sentencia más potente, y al mismo tiempo la más compleja,
con las que cuenta el lenguaje PHP para la construcción de bucles. Cualquier bucle
construido con las sentencias while o do...while podría implementarse de
manera equivalente con la sentencia for. La sintaxis y funcionamiento de esta
sentencia es totalmente similar a su análoga en el lenguaje C. Su sintaxis general es:

for (inicialización; condición; modificación)


{
sentencias a ejecutar mientras la condición es cierta
}

Como puede apreciarse, en la sintaxis de construcción del bucle intervienen cuatro


elementos diferenciados:

— Inicialización: las sentencias que aparezcan en esta parte se ejecutarán una


sola vez al principio del bucle. Lo habitual es situar en esta parte las
sentencias de inicialización de las variables que actúen de contadores de
iteraciones del bucle. En el caso de querer indicar varias sentencias de
inicialización, estas deberán separarse por comas.

— Condición: expresión lógica que se evaluará al comienzo de cada una de


las iteraciones, si esta expresión se evalúa como cierta entonces la iteración
se realiza, en caso contrario finaliza la ejecución del bucle.

— Modificación: sentencias que se ejecutan al finalizar cada una de las


iteraciones del bucle. Lo normal es que estas sentencias modifiquen los
valores de las variables que actúan de contadores del bucle de manera que
la condición de continuación del bucle pueda verse igualmente alterada. Al
igual que ocurría en la parte de inicialización, si se necesitan varias
sentencias de modificación, estas deben darse separadas por comas.

— Sentencias: bloque de sentencias a ejecutar en cada iteración del bucle. En


el caso de que este bloque esté constituido por una única sentencia, las
llaves que lo delimitan podrían suprimirse.

Para la sentencia for existe también una sintaxis alternativa:

for (inicialización; condición; modificación) :


sentencias a ejecutar mientras la condición es cierta
endfor;

179
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.25:
A continuación se muestra la construcción de un sencillo bucle que calcula la suma
de los 100 primeros números naturales: 1+2+3+4+...+99+100:

$suma = 0;
for ($n=1; $n<=100 ; $n++){
$suma = $suma + $n;
}

En este caso se utiliza una variable $suma en la que se irán acumulando las sumas
parciales y una variable $n que actuará de contador en el bucle. La variable
contador se inicializa con el valor 1, y mientras su valor sea menor o igual que
100 se seguirá ejecutando el bucle. Al finalizar cada iteración, la variable contador
se incrementa en una unidad. El cuerpo del bucle lo único que hace es sumar el
valor de la variable contador a la suma parcial acumulada hasta el momento.
A la hora de utilizar la sentencia for PHP admite bastante flexibilidad; como
prueba de ello se muestra a continuación la manera de escribir la estructura
iterativa anterior de una forma mucho más compacta:

for ($suma=0,$n=1; $n<=100 ; $n++, $suma+=$n);

En este caso, tanto la variable contador como la que acumula las sumas parciales,
toman sus valores iniciales en la parte de inicialización del bucle; obsérvese cómo
ambas inicializaciones se separan con una coma. De la misma manera, la variable
$suma actualiza su valor en cada una de las iteraciones en la parte de modificación
de variables del bucle junto con el incremento a la variable contador. Finalmente,
obsérvese que en este caso el cuerpo del bucle no tiene ninguna sentencia, por lo
que se finaliza con un punto y coma.

En la sentencia for es opcional no solo la presencia del cuerpo del bucle sino
también cualquiera de las otras tres partes que la forman. En el caso de que no se
indique ninguna condición, PHP asume que esta es siempre cierta, con lo que se
estaría definiendo un bucle infinito. Evidentemente, un bucle infinito no tiene
ninguna utilidad práctica a no ser que dentro del cuerpo del bucle se utilice la
sentencia break para forzar la salida del mismo.

Aunque resulte sorprendente, la sentencia:

for( ; ; );

180
SENTENCIAS DE CONTROL

es sintácticamente correcta, pero evidentemente no tiene ningún interés, a no ser


que se desee bloquear el programa con un bucle infinito que no produce ninguna
acción en cada una de sus iteraciones.

Ejemplo 6.26:
Otro ejemplo de bucle infinito sería:

for($n=1; ;$n++)
print $n;

En este caso se construye un bucle que escribe los números 1,2,3,4,.... y así
indefinidamente, ya que no hay condición de finalización.

PHP dispone de un mecanismo de seguridad para evitar situaciones como las que
se producen en los bucles anteriores; se trata de limitar el tiempo máximo de
ejecución de un script, de manera que cuando se entra en un bucle infinito y se
supera ese límite, automáticamente se aborta la ejecución y se genera el mensaje de
error:

Fatal error: Maximum execution time of 30 seconds exceeded in … on line …

Por defecto el tiempo máximo de ejecución de un script está fijado en 30


segundos; de todas formas ese tiempo puede ser modificado en el fichero
NOTA de inicialización de PHP (php.ini) asignando el tiempo deseado al
parámetro max_execution_time

A continuación se presentan algunos ejemplos adicionales de construcción de


bucles.

Ejemplo 6.27:
Uno de los ejemplos "clásicos" de estructuras iterativas es el cálculo del factorial
de un número (n!=1*2*3*...*(n-1)*n). La implementación de este bucle
sería:

$fact = 1;
for ($i = 2; $i <= $n; $i++ ) {
$fact *= $i;
}

181
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Al igual que en el caso del bucle que efectuaba la suma de los números menores o
iguales que 100, el bucle anterior puede escribirse de una forma más compacta:

for ($fact=1, $i=2; $i <= $n; $fact*=$i, $i++);

Ejemplo 6.28:
Supóngase que se desea construir, de forma aleatoria, una contraseña formada por
8 letras. Se puede utilizar la función rand() para generar un número aleatorio
entre 97 y 122 (códigos ASCII correspondientes a las letras minúsculas) y la
función chr() para obtener el carácter asociado a un código ASCII dado.

$codigo="";
for($i=1;$i<=8;$i++) {
$letra = chr(rand(97,122));
$codigo = $codigo.$letra;
}
print("Contraseña asignada es:<B>$codigo</B>");

Ejemplo 6.29:
En los bucles es posible utilizar más de una variable que actúe como contador, por
ejemplo:

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


{
echo $i*$j . "--";
}

Como resultado de este bucle se generaría la siguiente secuencia de números:

2--8--18--32--50--72--98--128--162--200--

Como puede apreciarse, en cada iteración se escribe el resultado del producto de


dos variables ($i y $j); la primera se irá incrementando de uno en uno hasta llegar
a su valor máximo (10) y la segunda lo hará de dos en dos.

También es posible generar bucles anidados, es decir, bucles cuyas iteraciones


ejecutan un nuevo bucle.

Ejemplo 6.30:
Supóngase que se desea generar en la página web la tabla de multiplicar del 1 al
10; esto puede hacerse de una manera muy sencilla con dos bucles for anidados:

182
SENTENCIAS DE CONTROL

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


print("<B>Tabla de multiplicar del $i <BR></B>");
for ($j = 1; $j <= 10; $j++) {
print("$i * $j =" . $i*$j . "<BR>");
}
}

La salida de este bucle sería:

Tabla de multiplicar del 1


1 * 1 =1
1 * 2 =2
1 * 3 =3
1 * 4 =4
1 * 5 =5
1 * 6 =6
1 * 7 =7
1 * 8 =8
1 * 9 =9
1 * 10 =10
Tabla de multiplicar del 2
2 * 1 =2
2 * 2 =4
............

El bucle anterior podría ser modificado para que la salida generada correspondiera
realmente a un formato de tabla en HTML. En este caso, el propio bucle debería
encargarse de ir generando las diferentes etiquetas de construcción de tablas
HTML en los lugares adecuados:

print("<TABLE BORDER>\n");
// Generación de la fila de cabecera
print("<TR ALIGN=CENTER>\n <TH> * </TH>");
for ($i = 1; $i <= 10; $i++)
print("<TH> $i </TH>");
print("\n</TR>\n");
// Generación de las restantes filas
for ($i = 1; $i <= 10; $i++) {
print("<TR ALIGN=CENTER> <TH>$i</TH> ");
for ($j = 1; $j <= 10; $j++) {
print("<TD>" . $i*$j . "</TD>");
}
print("\n</TR>\n");
}
print('</TABLE>');

183
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ahora sí, el resultado de la ejecución del script sería la tabla:

*  1  2  3  4  5  6  7  8  9  10 
1 1 2 3 4 5 6 7 8 9 10
2 2 4 6 8 10 12 14 16 18 20
3 3 6 9 12 15 18 21 24 27 30
4 4 8 12 16 20 24 28 32 36 40
5 5 10 15 20 25 30 35 40 45 50
6 6 12 18 24 30 36 42 48 54 60
7 7 14 21 28 35 42 49 56 63 70
8 8 16 24 32 40 48 56 64 72 80
9 9 18 27 36 45 54 63 72 81 90
10 10 20 30 40 50 60 70 80 90 100

En ocasiones los bucles for pueden ser utilizados para generar dinámicamente
campos de formularios.

Ejemplo 6.31:
A continuación puede verse la definición de un formulario HTML dentro del cuál
se incluye un script PHP con sendos bucles que generan las opciones de dos
controles de tipo lista:

<FORM NAME=FORMHORA>
<?php
print("HORAS: <SELECT HORA>");
for($i=0; $i<=23; $i++)
print("<OPTION VALUE=$i> $i");
print("</SELECT>");
print("<BR>MINUTOS: <SELECT MINUTOS>");
for($i=0; $i<=55; $i+=5)
print("<OPTION VALUE=$i> $i");
print("</SELECT>");
?>
</FORM>

184
SENTENCIAS DE CONTROL

Ejemplo 6.32:
Como último ejemplo de construcción de bucles con la sentencia for se presenta a
continuación un programa más complejo que es capaz de generar el calendario de
un mes concreto. Se asume que las variables $mes y $anno contienen los valores
del mes y año cuyo calendario se quiere generar. El código del programa sería:

$diasemana=date("w",mktime(0,0,0,$mes,1,$anno));
if($diasemana==0) $diasemana=7;
switch($mes) {
case 1:
$nd=31; $nombremes="Enero";
break;
case 2:
if((($anno%4==0) and ($anno%100!=0)) or
($anno%400==0))
$nd=29;
else
$nd=28;
$nombremes="Febrero";
break;
case 3:
$nd=31; $nombremes="Marzo";
break;
case 4:
$nd=30; $nombremes="Abril";
break;
case 5:
$nd=31; $nombremes="Mayo";
break;
case 6:
$nd=30; $nombremes="Junio";
break;
case 7:
$nd=31; $nombremes="Julio";
break;
case 8:
$nd=31; $nombremes="Agosto";
break;
case 9:
$nd=30; $nombremes="Septiembre";
break;
case 10:
$nd=31; $nombremes="Octubre";
break;
case 11:
$nd=30; $nombremes="Noviembre";

185
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

break;
case 12:
$nd=31; $nombremes="Diciembre";
break;
}
// generación del calendario en una tabla HTML
print("<B>$nombremes $anno </B>");
print("<TABLE BORDER ALING=CENTER>");
print("<TR>
<TH>Lu</TH><TH>Ma</TH><TH>Mi</TH><TH>Ju</TH>");
print("<TH>Vi</TH><TH>Sa</TH><TH>Do</TH> </TR>");
print("<TR>");
$aux=1;
// genera celdas en blanco hasta llegar el día
// de comienzo del mes
while($aux<$diasemana) {
print("<TD>&nbsp;</TD>");
$aux++;
}
for($i=1;$i<=$nd;$i++) {
if(($diasemana==6) or ($diasemana==7))
print("<TD BGCOLOR=#00FFFF>$i</TD>");
else
print("<TD>$i</TD>");
$diasemana++;
if($diasemana==8) {
// comienza nueva semana
print("</TR>");
print("<TR>");
$diasemana=1;
}
}
print("</TR></TABLE>");

El modelo de calendario que genera el programa anterior es:

Julio 2004
Lu Ma Mi Ju Vi Sa Do
   1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

186
SENTENCIAS DE CONTROL

Como puede apreciarse, el primer dato que se necesita es saber en qué día de la
semana comienza el mes, para ello se utiliza la combinación de las funciones
date() y mktime(), ambas serán estudiadas con detalle en el Capítulo 9; de
momento, únicamente indicar que la función mktime() permite generar un
instante de tiempo, en este caso el instante que se genera corresponde a las 0 horas,
0 minutos, 0 segundos del día 1 del mes y año dados. Con ese instante de tiempo la
función date() es capaz de devolver un valor numérico de 0 a 6 indicando el día
de la semana (0 corresponde al domingo). Para que el programa quede más claro,
se asigna el valor 7 a los domingos.

El siguiente paso es la definición de una estructura condicional para determinar el


número de días del mes y generar una cadena de caracteres con el nombre del mes
correspondiente. Tras esa estructura condicional se incluyen las estructuras
iterativas que generan las diferentes celdas de la tabla que mostrarán los días del
calendario. Obsérvese que las celdas correspondientes a los fines de semana
tendrán un color de fondo.

6.3.4. SENTENCIA FOREACH


La última de las sentencias de construcción de bucles con las que cuenta el
lenguaje PHP es la sentencia foreach. Se trata de una sentencia que fue
incorporada en la versión PHP 4, ya que hasta entonces no existía. La sentencia
foreach permite recorrer todos los elementos de un array de una forma muy
simple. Los arrays son estructuras de datos que permiten almacenar, bajo un
nombre común, una serie de valores a los que se puede acceder a través de un
índice numérico o palabra clave; en el Capítulo 8 se estudiarán estas estructuras de
datos y se presentarán con más detalle las estructuras iterativas que permiten
recorrer todos sus elementos.

Se incluye a continuación la sintaxis básica de la sentencia foreach y un sencillo


ejemplo de aplicación:

foreach (nombre_array as nombre_variable)


{
sentencias a ejecutar para cada elemento del array
}

Como puede apreciarse, debe indicarse el nombre del array en el que están
almacenados todos los datos y el nombre de una variable. En la iteración inicial
esta variable contendrá el valor del primer elemento del array y en las sucesivas
iteraciones del bucle esta variable hará referencia a los siguientes elementos.

187
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.33:
Las siguientes sentencias

$lista = array ("Luis","Pedro","Ana","Susana");


foreach ($lista as $nombre)
{
print "Bienvenido, $nombre <BR>";
}

generarían los siguientes mensajes en la página:


Bienvenido, Luis
Bienvenido, Pedro
Bienvenido, Ana
Bienvenido, Susana

6.3.5. SENTENCIAS BREAK Y CONTINUE


Las sentencias break y continue permiten alterar la ejecución prevista de una
estructura iterativa; la primera de ellas permite cancelar completamente la
ejecución del bucle y la segunda permite cancelar una de las iteraciones y pasar
directamente a la siguiente.

La sentencia break, además de permitir abandonar una estructura iterativa se


utiliza también dentro de las estructuras condicionales switch. En el caso de su
uso dentro de bucles, break admite un parámetro opcional que determina el
número de estructuras de control de las que hay que salir, el valor por defecto de
este parámetro es 1.

Ejemplo 6.34:
Si se desea construir un bucle que escriba todos los números pares menores o
iguales que 100, se podría utilizar una sentencia for como la siguiente:

for ($i = 2; $i <= 100; $i+=2) {


print $i;
}

pero también es posible construir un bucle con condición de finalización vacía en


el que se fuerce la salida desde dentro del cuerpo del bucle.

for ($i = 2; ; $i+=2) {


if ($i > 100)

188
SENTENCIAS DE CONTROL

break;
print $i;
}

En esta segunda opción es obligado utilizar la sentencia break, ya que de no ser


así se entraría en un bucle infinito.

En el caso de estructuras de control anidadas, se puede utilizar el parámetro


opcional de la sentencia break para indicar de cuántas estructuras se quiere salir.

Ejemplo 6.35:
Considérense los siguientes bucles anidados:

for($i=1;$i<=10;$i++) {
$j=10;
print "<BR> <B>$i</B>: ";
while ($j>0) {
if ($i>$j) {
break;
}
else {
print "$j ";
}
$j--;
}
}

En este caso, el bucle interno se ejecutaría en principio mientras la variable $j


tome un valor positivo, pero dentro del cuerpo de ese bucle se fuerza la salida
cuando el valor de $i supere a $j. Al utilizarse la sentencia break sin ningún
parámetro, se asume el valor por defecto (1) lo que implica que se sale solamente
del bucle interior pero no del bucle for; en definitiva, la salida producida por las
sentencias anteriores sería:

1: 10 9 8 7 6 5 4 3 2 1
2: 10 9 8 7 6 5 4 3 2
3: 10 9 8 7 6 5 4 3
4: 10 9 8 7 6 5 4
5: 10 9 8 7 6 5
6: 10 9 8 7 6
7: 10 9 8 7
8: 10 9 8
9: 10 9
10: 10

189
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En cambio, si se utiliza la sentencia break pero con un valor de 2 para su


parámetro opcional, cuando se verifique por primera vez la condición $i>$j se
producirá la salida y terminación de los dos bucles anidados.

La salida producida por la construcción siguiente:

for($i=1;$i<=10;$i++) {
$j=10;
print "<BR> <B>$i</B>: ";
while ($j>0) {
if ($i>$j) {
break 2;
}
else {
print "$j ";
}
$j--;
}
}

sería:
1: 10 9 8 7 6 5 4 3 2 1
2: 10 9 8 7 6 5 4 3 2

Ejemplo 6.36:
En el siguiente programa puede verse otro ejemplo de salida de dos estructuras de
control anidadas, en este caso un bucle y una estructura condicional:

$n = 10;
while (--$n) {
switch ($n) {
case 1:case 3:case 5:case 7:case 9:
print "$n (impar) ";
break;
case 2:case 4:case 6:case 8:
print "$n (par) ";
break;
case 0:
break 2;
}
}

En este caso las sentencias break dentro de los primeros casos de la estructura
condicional tienen por objeto únicamente salir de esa estructura; mientras que el

190
SENTENCIAS DE CONTROL

break situado dentro del último caso fuerza la salida de las dos estructuras
anidadas (la estructura condicional y el bucle). La salida producida por las
sentencias anteriores sería:

9 (impar) 8 (par) 7 (impar) 6 (par) 5 (impar) 4 (par) 3 (impar) 2 (par) 1 (impar)

La sentencia continue, por su parte, permite abandonar una iteración del bucle
pero sin omitir el resto de iteraciones. Cuando el intérprete de PHP se encuentra
una sentencia continue, ignora las posibles sentencias que queden por ejecutar
en la iteración actual del bucle y pasa directamente a las sentencias de la siguiente
iteración.

Ejemplo 6.37:
Una forma de calcular la suma de los números pares menores o iguales que 100
sería:

$suma = 0;
for($n=1;$n<=100;$n++) {
if($n%2 != 0) // el número es impar
continue;
$suma = $suma + $n;
}

En este caso, se construye un bucle que recorre todos los números menores o
iguales que 100, tanto los pares como los impares; en cada iteración se comprueba
si el número es impar, y de ser así se abandona esa iteración y se pasa a la
siguiente.

Por supuesto, este ejemplo tiene por único objeto mostrar el funcionamiento de la
sentencia continue, ya que el cálculo de la suma se podría realizar de una forma
más optimizada con un bucle que recorra solamente los números pares. De hecho,
la siguiente sentencia sería suficiente para conseguir el mismo efecto:

for($suma=0,$n=2;$n<=100;$n+=2);

Al igual que la sentencia break, la sentencia continue admite un parámetro


opcional que determina, en el caso de estructuras anidadas, cuántos niveles deben
ser saltados para continuar la ejecución.

191
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 6.38:
Los siguientes bucles anidados generan todos los pares de números formados por
combinaciones de los dígitos del 1 al 9, siendo además los dos componentes del par
diferentes. Obsérvese cómo cuando en la iteración interna se comprueba que las
dos componentes son iguales, se abandona dicha iteración

for($i=1;$i<10;$i++)
for($j=1;$j<10;$j++)
if($i == $j)
continue;
else
print "($i,$j) ";

El resultado generado por la estructura anterior es:

(1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8) (1,9) (2,1) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8)
(2,9) (3,1) (3,2) (3,4) (3,5) (3,6) (3,7) (3,8) (3,9) (4,1) (4,2) (4,3) (4,5) (4,6) (4,7)
(4,8) (4,9) (5,1) (5,2) (5,3) (5,4) (5,6) (5,7) (5,8) (5,9) (6,1) (6,2) (6,3) (6,4) (6,5)
(6,7) (6,8) (6,9) (7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (7,8) (7,9) (8,1) (8,2) (8,3) (8,4)
(8,5) (8,6) (8,7) (8,9) (9,1) (9,2) (9,3) (9,4) (9,5) (9,6) (9,7) (9,8)

En cambio, si se utiliza la sentencia continue 2, cuando se observa que las dos


componentes son iguales se pasa a la siguiente iteración pero no del bucle interno
sino del externo (segundo nivel)

for($i=1;$i<10;$i++)
for($j=1;$j<10;$j++)
if($i == $j)
continue 2;
else
print "($i,$j) ";

El resultado sería:

(2,1) (3,1) (3,2) (4,1) (4,2) (4,3) (5,1) (5,2) (5,3) (5,4) (6,1) (6,2) (6,3) (6,4) (6,5)
(7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (8,1) (8,2) (8,3) (8,4) (8,5) (8,6) (8,7) (9,1) (9,2)
(9,3) (9,4) (9,5) (9,6) (9,7) (9,8)

192
DEFINICIÓN DE
FUNCIONES

7.1. ¿CÓMO SE DEFINEN FUNCIONES EN PHP?


PHP permite al programador la creación de sus propias funciones, ahorrando
tiempo y esfuerzo y facilitando un mejor diseño de los programas
implementados. El programador puede crearse sus propias librerías de funciones o
utilizar las innumerables funciones implementadas por la comunidad de
desarrolladores en PHP. En este capítulo se aborda el proceso de definición y
creación de funciones para su posterior utilización dentro de un programa PHP.

La sintaxis que debe adoptarse a la hora de definir una función en PHP sigue el
siguiente esquema general:

function NombreFuncion (argumentos) {


sentencias de definición
return ValorDevuelto;
}

193
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Como puede apreciarse, toda definición de función comienza con la palabra


reservada function seguida del nombre asignado, la lista de argumentos y el
bloque de definición de la función.

En los nombres de las funciones no se distingue entre mayúsculas y minúsculas,


aunque siempre es aconsejable efectuar la llamada a una función tal y como ha sido
definida. Respecto a los argumentos, estos son unos parámetros formales que
vienen representados por variables. Conviene recordar que en PHP no se declaran
tipos para las variables, por tanto en los argumentos de la función tampoco es
necesario indicar tipo alguno. Es posible definir funciones sin argumentos, en este
caso, a continuación del nombre deberían colocarse paréntesis vacíos:

function NombreFuncion()

La sentencia return permite que la función devuelva un valor de retorno. Una vez
ejecutada esa sentencia se abandona la función, sin ejecutar cualquier sentencia
posterior que se encuentre en el cuerpo de la misma. El valor devuelto puede ser una
cadena de caracteres, un valor numérico, un valor booleano, un array,... Este valor será
recogido en una variable a la hora de efectuar la llamada a la función o utilizado
directamente en alguna otra sentencia. Debe destacarse que a la hora de definir una
función, no es indispensable que esta devuelva valores; en este sentido en PHP no hay
distinción sintáctica entre lo que en otros lenguajes son funciones y procedimientos.

Se muestran a continuación los primeros ejemplos de definición de funciones en PHP.

Ejemplo 7.1:
En este primer caso, se define una función que calcula la suma de sus dos
argumentos numéricos. La sentencia return devuelve el resultado:

function Suma($x,$y) {
return ($x+$y);
}

Ejemplo 7.2:
La siguiente función no devuelve ningún valor, simplemente imprime en pantalla
una serie de cadenas de caracteres a modo de saludo:

function Saluda() {
print("Bienvenido ");
print("¿Cómo estás?");
}

194
DEFINICIÓN DE FUNCIONES

Ejemplo 7.3:
Avanzando un paso más se muestra cómo definir una función que calcula el
factorial de un número dado:

function factorial ($n) {


if ($n < 0 ) {
return "¡Solo se admiten valores positivos!";
}
else if($n==0)
return 1;
else {
$aux = 1;
for ($i = 2; $i <= $n; $i++) {
$aux = $aux * $i;
}
return $aux;
}
}

En este caso se implementa el proceso iterativo de cálculo del factorial de un número


(n! = 1*2*3*...*n). Además puede observarse que el valor devuelto por la función
puede ser de tipo diferente según determinadas condiciones, en el ejemplo la función
devuelve una cadena de caracteres con un mensaje de error cuando $n es menor que 0,
y un número entero en otro caso.

Ejemplo 7.4:
En este ejemplo se programa una función que genera un array a partir de dos
valores numéricos dados. El primer elemento es el menor valor de ambos. A partir
de él se generan los siguientes elementos sumando una unidad al anterior hasta
llegar al segundo de los valores dados. Los arrays serán estudiados en profundidad
en el capítulo siguiente.

function GeneraArray($min,$max) {
$x = array();
$d = $min;
while ($d<=$max){
$x[]=$d;
$d++;
}
return $x;
}

195
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En la definición de funciones se admite la recursividad, es decir, se permite la


llamada a una función dentro de su propia definición. Un ejemplo clásico que
ilustra este concepto es de nuevo la función factorial de un número natural. De
hecho, el factorial de un natural n se puede definir como:

n! = n* (n-1)!

Por tanto, la definición de la función factorial del Ejemplo 7.3 se podría


condensar en menos líneas de código de la siguiente manera:

function factorial ($n) {


if ($n < 0 ) {
return "¡Solo se admiten valores positivos!";
}
else if($n==0)
return 1;
else{
$aux = $n*factorial($n-1);
return $aux;
}
}

De todas formas conviene advertir que el uso de recursividad en la definición de


funciones hace que estas requieran de más memoria para su ejecución y resulten en
ocasiones más lentas que sus funciones iterativas equivalentes.

7.2. LLAMADA A LAS FUNCIONES


Una vez definida una función, ¿cómo acceder a ella?, ¿cómo utilizarla cuando se
necesite a lo largo del programa? Se deben tener en cuenta los siguientes puntos:

— La función debe encontrarse definida antes del lugar en el que se efectuará la


llamada, a no ser que el servidor web trabaje con las versiones PHP 4 o 5. En
ese caso, la llamada a la función puede realizarse con anterioridad a su
definición. No obstante, es práctica habitual y recomendable definir las
funciones incluso antes de cualquier código HTML, por ejemplo, colocar los
scripts que las definen antes del comando <HTML> o dentro del encabezado del
documento.
— En la llamada, los argumentos, en el caso de que existan, deben ser pasados en
el mismo orden en el que aparecen en la definición. Como argumentos pueden
pasarse variables, valores o expresiones. Los valores numéricos pueden ser

196
DEFINICIÓN DE FUNCIONES

escritos directamente o entrecomillados. En el caso de funciones que no


reciban argumentos, en la llamada deben colocarse los paréntesis vacíos.
— Si se pasan menos argumentos que los que tiene la función en su definición, los
últimos argumentos se asumirán como nulos, la función ejecutará las
instrucciones pero se generarán mensajes de aviso (warnings).
— Si la función devuelve un valor, este puede ser asignado a una variable en la
llamada o utilizado directamente en otra expresión.

Ejemplo 7.5:
Dada la función:

function Suma($x,$y) {
return ($x+$y);
}

las siguientes llamadas son todas ellas válidas:

$x=2;
$y=3;
$z=Suma($x,$y);

$z=Suma(2,3);

$x=2;
echo SUMA($x,3);

$z=Suma("2","3");

$z=suma((2+3)*5,4);

echo suma(suma(2,3)*5,4);

Ejemplo 7.6:
La siguiente página muestra la generación de un array con ayuda de la función
GeneraArray() definida en el Ejemplo 7.4. Como puede observarse, el código
de la página incorpora dos scripts PHP diferentes, el primero, situado antes del
código HTML, define la función; mientras que en el segundo es donde se realiza la
llamada a la misma.

<?PHP
function GeneraArray($min,$max) {

197
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$x = array();
$d = $min;
while ($d<=$max){
$x[]=$d;
$d++;
}
return $x;
}
?>

<HTML>
<HEAD>
<TITLE>Generación de un array</TITLE>
</HEAD>
<BODY>
<?PHP
print "<PRE>";
print_r(GeneraArray(3,10));
print "</PRE>";?>
</BODY>
</HTML>

La salida de este programa resulta ser.

Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
[5] => 8
[6] => 9
[7] => 10
)

En este ejemplo se ha utilizado la función print_r() que permite visualizar los


contenidos de variables o expresiones de cualquier tipo. Si estas variables son
números o cadenas de caracteres, la función print_r() produce exactamente el
mismo efecto que la función print(); pero en el caso de arrays u objetos,
print_r() permite visualizar todas sus componentes de una forma clara.

198
DEFINICIÓN DE FUNCIONES

7.3. ARGUMENTOS DE UNA FUNCIÓN

7.3.1. ARGUMENTOS OPCIONALES


En PHP todos los argumentos de las funciones pueden ser considerados opcionales,
de manera que a la hora de realizar la llamada a una función, pueden pasarse un
número de argumentos distinto del que acepta la función. Si se pasan menos
argumentos de los esperados, los últimos se asumirá que tienen el valor nulo. En el
caso de pasarse más argumentos de los esperados, los que sobran pueden ser
ignorados. En cualquiera de los dos casos la llamada y ejecución de la función
puede realizarse con normalidad.

Ejemplo 7.7:
Considérese una función que reciba tres argumentos correspondientes a una
cantidad de horas, minutos y segundos, y devuelva el número total de segundos
equivalentes a dicho periodo. A continuación puede verse la definición de esa
función y tres llamadas a la misma con diferente número de argumentos.

<?PHP
function Cuenta_segundos($horas,$minutos,$segundos) {
return (3600*$horas + 60*$minutos + $segundos);
}
?>
<HTML>
<HEAD>
<TITLE>Generación de un array</TITLE>
</HEAD>
<BODY>
<?PHP
$h=2; $m=15; $s=30;
$ss = Cuenta_segundos($h,$m,$s);
print "$h horas, $m minutos y $s segundos
son $ss segundos <BR>";
$h=3; $m=20;
$ss = Cuenta_segundos($h,$m);
print "$h horas y $m minutos son $ss segundos <BR>";
$h=5;
$ss = Cuenta_segundos($h);
print "$h horas son $ss segundos <BR>";
?>
</BODY>
</HTML>

199
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La salida generada por el programa sería:

2 horas, 15 minutos y 30 segundos son 8130 segundos

Warning: Missing argument 3 for cuenta_segundos() in C:\\www\~scp.php


on line 2
3 horas y 20 minutos son 12000 segundos

Warning: Missing argument 2 for cuenta_segundos() in C:\\www\~scp.php


on line 2
Warning: Missing argument 3 for cuenta_segundos() in C:\\www\~scp.php
on line 2
5 horas son 18000 segundos

Como puede apreciarse, en la primera llamada se pasan los tres argumentos,


mientras que en las dos llamadas restantes se pasan las horas y los minutos, y
únicamente las horas, respectivamente. En estos dos casos los argumentos que no
son pasados tomarán el valor 0 y la ejecución de la función podrá realizarse con
normalidad. Sin embargo, como puede apreciarse, se generan unos mensajes de
aviso notificando el hecho de recibirse menos argumentos de los previstos.

Puede configurarse el intérprete de PHP para que los avisos en tiempo


de ejecución (warnings) no sean presentados en la propia página web,
evitando situaciones como la del ejemplo anterior, en la que a pesar de
NOTA esos mensajes de aviso, el programa se ejecuta correctamente. Dentro
del fichero de inicialización php.ini se debe configurar el parámetro
error_reporting para indicar al intérprete qué tipo de errores
debe mostrar en la página. Por ejemplo, si se realiza en ese fichero la
asignación: error_reporting = E_ALL & ~E_WARNING
PHP mostraría en la página los mensajes correspondientes a todos los
errores salvo los errores no graves en tiempo de ejecución (warnings).

7.3.2. ARGUMENTOS CON VALORES POR DEFECTO


Al definir funciones pueden darse valores por defecto para argumentos, de tal
forma que si un argumento no está presente en la llamada, se le asigna ese valor
por defecto en lugar de tomar el valor nulo. Para indicar un valor por defecto basta
asignar dicho valor con el signo "=" en la lista de argumentos de la cabecera de la
función. Si la función tiene argumentos que no llevan valor por defecto y otros que
sí lo llevan, estos últimos deben estar situados al final en la lista de argumentos de
la función.

200
DEFINICIÓN DE FUNCIONES

Ejemplo 7.8:
A continuación se define una función que crea enlaces en una página web, a partir
de dos argumentos: el texto del enlace y la dirección URL de destino. A este
segundo argumento se le asignará un valor por defecto:

function CrearEnlace($texto,$url="http://www.cinemas.es")
{
echo "<a href=$url>$texto</a>";
}

Al llamar a la función anterior se podrían indicar los dos argumentos o únicamente


el primero, tomando en este caso el segundo su valor por defecto. Llamadas válidas
a esta función serían:

CrearEnlace("Página web de Cinem@s");


CrearEnlace("Disney","http://www.disney.es");

Por supuesto, todos los argumentos de la función pueden tomar valores por
defecto:

function CrearEnlace($texto="Pulse aquí",


$url="http://www.cinemas.es")
{
echo "<a href=$url>$texto</a>";
}

En este caso, una llamada podría ser simplemente:

CrearEnlace();

En este caso, los dos argumentos tomarían sus respectivos valores por defecto.

7.3.3. LISTAS DE ARGUMENTOS DE LONGITUD


VARIABLE
A partir de PHP 4 se admite que las funciones definidas por el usuario puedan
recibir listas de argumentos de longitud variable. En este caso, a la hora de definir
la función se puede dejar la lista de argumentos vacía y utilizar una serie de
funciones predefinidas para recuperar los argumentos que realmente han sido
pasados a la hora de efectuar la llamada a la función.

201
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La primera de las funciones que puede ser utilizada es:

func_num_args()

que devuelve el número de argumentos que efectivamente han sido pasados.

Una vez que se sabe cuántos argumentos han sido pasados, es necesario también
disponer de algún mecanismo para recuperar los valores de los mismos. La
siguiente función permite recuperar el valor del argumento número n:

func_get_arg(n)

Debe tenerse en cuenta que la numeración de los argumentos comienza en 0, es


decir, para obtener el primer argumento habría que utilizar la sintaxis
func_get_arg(0). Si se llama a la función con un índice fuera del rango de
argumentos recibidos, esta genera un aviso (warning) y devolverá el valor
booleano falso.

Si lo que se quiere es recuperar todos los valores de los argumentos en una


estructura de datos y en una sola operación, puede usarse la función:

func_get_args()

que devuelve un array con todos los valores de los argumentos.

Ejemplo 7.9:
A continuación se define una función que calcula la suma de los valores de todos
sus argumentos. Como puede observarse, en la cabecera de la definición no se
declara ningún argumento y estos son recuperados en el cuerpo de la propia
función.

function suma() {
$n = func_num_args();
$aux = 0;
for ($i=0;$i<$n;$i++)
$aux += func_get_arg($i);
return $aux;
}

A la hora de efectuar la llamada a esta función, pueden ser pasados tantos


argumentos como se desee. Por ejemplo, las sentencias

print suma(2,5,6) . "<BR>";

202
DEFINICIÓN DE FUNCIONES

print suma(1,5,7,2) . "<BR>";


print suma() . "<BR>";

generarían como resultado:

13
15
0

7.3.4. PASO DE ARGUMENTOS POR VALOR O POR


REFERENCIA
A la hora de efectuar la llamada a una función, los argumentos pueden ser pasados
por valor o por referencia. En el primer caso, lo que se pasa realmente es una copia
del correspondiente valor para que la función lo reciba y realice con él las
correspondientes operaciones. En el segundo caso, en cambio, cuando se pasa una
variable como argumento, no se pasa a la función una copia de su valor sino la
dirección de memoria donde se encuentra dicha variable. De esta forma la función
puede acceder directamente a esa zona de memoria y leer o modificar el valor de la
variable.

Antes de analizar las diferencias entre el paso de argumentos por valor y por
referencia, conviene entender ambos conceptos pero aplicados al caso de la
asignación de variables.

Asignar a una variable dada un valor por referencia no supone almacenar un valor
concreto, sino una dirección de memoria que remite a otra variable. Cualquier
modificación sobre esta segunda variable se verá reflejada en la variables asignada
por referencia.

Si se desea asignar por referencia a una variable $b la información de otra variable


$a debería utilizarse el operador de dirección (&):

$b = &$a;

El siguiente ejemplo muestra las diferencias en el resultado final entre las dos
formas de inicialización de variables, la directa, o por valor, y la asignación por
referencia.

203
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 7.10:
Dadas las sentencias de asignación siguientes:

$a = "¡Hola!";
$b = $a;
$a = "¡Adiós!";
echo "$b"; //Se imprime "¡Hola!", el valor inicial de $a

cuando se da la orden de escribir el valor de $b, lo que realmente se escribe es el valor


inicial de $a, ya que, en el momento de realizar la asignación a $b, se realiza una
asignación por valor, es decir, se asigna a $b una copia del valor que en ese momento tenía
$a. Cualquier modificación posterior de la variable $a no tiene ningún efecto sobre la
asignación previa.

En cambio, si la asignación a $b se realiza por referencia, $b en todo momento


estará apuntando a la posición de memoria de $a, con lo que las modificaciones
posteriores de $a tienen reflejo también en $b.

$a = "¡Hola!";
$b = &$a;
$a = "¡Adiós!";
echo "$b"; //Se imprime "¡Adiós!", el nuevo valor de $a

Se puede anular una asignación por referencia mediante la función unset():

$a = "¡Hola!";
$b = &$a;
unset($a);
$a = "¡Adiós!";
echo "$b"; //Se imprime "¡Hola!", el valor inicial de $a

En este caso, tras realizar la asignación por referencia a la variable $b, la variable
$a es destruida con la función unset(), quedando $b con el valor que hasta ese
momento tenía la variable destruida. Posteriormente, al hacer la última asignación,
la variable $a vuelve a ser creada pero ocupando una posición de memoria
diferente a la que tenía en principio, por lo que la referencia de $b no es
recuperada.

De forma similar al caso de las variables, pasar un argumento de una función por
referencia significa que lo que realmente se pasa es la dirección de memoria de una
variable y no su valor. Para indicar que un argumento es pasado por referencia, se
antepone, de nuevo, el signo "&" al nombre de la variable en la lista de argumentos

204
DEFINICIÓN DE FUNCIONES

de la función. Si los argumentos se pasan por referencia, cualquier modificación


que se haga dentro de la función tiene su efecto sobre la variable que se pasó.

Ejemplo 7.11:
En la siguiente función se pasan dos argumentos por valor ($x y $y) y otros dos
por referencia ($suma y $prod) para que la función guarde en estos dos últimos
el valor de la suma y del producto, respectivamente, de los dos primeros:

function Opera($x, $y, &$suma, &$prod)


{
$suma = $x+$y;
$prod = $x*$y;
}

A la hora de llamar a la función:

$a=3; $b=2;
Opera($a,$b,$s,$p);

// se puede acceder a las variables $s y $p


// desde fuera de la función
echo "Suma: $s Producto: $p";

Si en la definición de la función se hubiera prescindido del signo & en los dos


últimos argumentos, al llamarla se estaría trabajando no sobre las posiciones de
memoria de las dos variables sino sobre una copia de su valor (paso por valor).
Esto significa que al devolver el control del programa al punto en el que se efectuó
la llamada, las dos variables enviadas ($s y $p) no tendrían ningún valor asignado.

Ejemplo 7.12:
Para apreciar la diferencia entre ambas maneras de pasar los argumentos de una
función, se define a continuación una función que toma como argumento una
variable numérica y multiplica su valor por 20, pero implementando las dos
versiones: pasando el argumento por valor (función Fvalor()) y pasándolo por
referencia (función Frefer()).

function Fvalor($x){
$x *= 20;
}
function Frefer(&$x){
$x *= 20;
}

205
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Con las funciones anteriores, las sentencias

$z = 3;
Fvalor($z);
echo "$z";

escribirían en la página el valor 3, valor inicial de la variable $z y que no se ve


afectado por el cambio de valor del argumento dentro de la función, por ser pasado
por valor.

Por el contrario, si se pasa el argumento por referencia, al efectuar las sentencias:

$z = 3;
Frefer($z);
echo "$z";

escribiría en la página el valor 60, ya que al pasar el argumento por referencia, la


modificación que sufre dentro de la función se mantiene fuera de ella.

7.4. ÁMBITO DE LAS VARIABLES

7.4.1. VARIABLES LOCALES

Toda variable definida dentro de una función tiene un ámbito local a la misma; es
decir, únicamente podrá ser utilizada dentro de la propia función.

Ejemplo 7.13:
Dada la función f(), en la que se define una variable local $titulo, cualquier
referencia a esa variable fuera de la función devolvería un valor nulo (variable no
definida). Así, con las siguientes sentencias no se imprimiría ningún mensaje:

function f() {
$titulo = "Mar adentro";
print $titulo;
}

print $titulo;

206
DEFINICIÓN DE FUNCIONES

7.4.2. VARIABLES GLOBALES


Por otra parte, una variable declarada fuera de una función tiene un ámbito global,
y no puede ser utilizada dentro de una función, a no ser que se declare
explícitamente su globalidad.

Ejemplo 7.14:
El siguiente programa tampoco escribiría ningún mensaje, ya que al hacer la
referencia a la variable $director dentro de la función, PHP buscará esa variable
localmente.

$director = "Amenábar"; // variable de ámbito global

function g()
{
print $director; // referencia a una variable local
}

g(); // llamada a la función

Puede observarse que el funcionamiento de PHP en este sentido es diferente al de


otros lenguajes como C, en los que cualquier variable global puede ser utilizada
directamente dentro de las funciones, a no ser que se oculten por una variable local
con el mismo nombre.

En PHP las variables globales deben ser declaradas como tal dentro de la función que
quiera utilizarlas, esta declaración se hace utilizando la palabra reservada global.
No existe ningún límite al número de variables globales que pueden aceptar las
funciones.

Ejemplo 7.15:
Si se desea utilizar la variable $director dentro de la función g(), la
declaración debería hacerse de la siguiente manera:

$director = "Amenábar"; // variable de ámbito global

function g()
{
global $director; // declaración de variable global
print $director; // referencia a la variable global
}

207
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Una segunda forma de acceder a las variables globales dentro de una función es
utilizar el array $GLOBALS, que siempre almacena todas las variables globales
definidas. Así, en la función anterior, también se podría acceder a la variable
$director utilizando la siguiente sintaxis:

function g()
{
print $GLOBALS["director"];
}

$GLOBALS es un array asociativo en el que para acceder a sus elementos se utiliza,


en lugar de un índice numérico, el propio nombre de la variable pero sin el signo $.
En el Capítulo 8 se estudiarán en detalle este tipo de arrays.

7.4.3. VARIABLES ESTÁTICAS


Otro aspecto importante relacionado con el ámbito de las variables es la posibilidad de
definir variables estáticas. Una variable estática tiene un ámbito local a la función en la
que se define pero no pierde su valor cuando se termina la ejecución de la misma. Es
decir, conserva el valor entre llamadas sucesivas a la función; en contra de lo que
ocurre con las variable locales, que pierden su valor una vez que la ejecución de la
función ha finalizado.

Ejemplo 7.16:
La siguiente función declara una variable estática, con valor inicial 0, y en cada
iteración la incrementa en una unidad y escribe su nuevo valor.

function h()
{
static $n = 0;
$n++;
print "$n ";
}

Para comprobar que realmente la variable no se destruye al salir de la función, se


podría implementar un bucle de llamadas sucesivas con el siguiente:

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

208
DEFINICIÓN DE FUNCIONES

Puede comprobarse que el bucle generaría el siguiente resultado:

1 2 3 4 5 6 7 8 9 10

Si la variable $n no hubiese sido declarada estática, en cada llamada a la función


se perdería el valor previo, inicializándose de nuevo en 0.

7.5. CLÁUSULAS INCLUDE Y REQUIRE


Al programar es bastante frecuente que unas mismas líneas de código o conjunto
de funciones se necesiten en varios documentos. Puede tratarse por ejemplo, de:

— Funciones de validaciones de datos.


— Funciones para mostrar cabeceras o pies de páginas.
— Código de configuración para acceso a una base de datos.
— Definición de determinados parámetros del programa.

En lugar de copiar el código, se puede optar por escribir el código correspondiente


en ficheros externos e incluirlos tantas veces como se quiera en otros ficheros
diferentes. Las cláusulas include y require permiten incluir y ejecutar el
contenido del fichero indicado en aquél que contiene la cláusula. De esta forma
pueden escribirse completas librerías de funciones y facilitar su portabilidad y
reusabilidad.

La sintaxis de las dos sentencias de inclusión es idéntica:

include("fichero.php");

require("fichero.php");

La inclusión puede realizarse en cualquier punto del programa, incluso puede


depender del flujo de ejecución, por ejemplo, una inclusión dentro de un bloque
if.

El nombre del fichero a incluir puede estar incluso almacenado en una variable y
cambiar de valor durante la ejecución del programa. Además, en el caso de que el
fichero a incluir se encuentre en un directorio diferente del que incluye al fichero
que hace la llamada, el nombre del mismo debería ir acompañado de la ruta relativa
para localizarlo.

209
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La única diferencia entre include y require es que, en caso de no localizar el


fichero a incluir, require produce un “Error Fatal” y no ejecuta el resto del programa
ni continúa con la carga de la página. En cambio, con include, si el fichero no se
encuentra, se genera un aviso pero se sigue con la ejecución del resto del programa y
carga de la página.

Ejemplo 7.17:
A continuación se muestra el uso de la cláusula require para incluir en un
programa las asignaciones realizadas en el fichero de nombre definiciones.php. El
contenido de este podría ser:

<?php
$titulo = "Los increibles";
$director = "Brad Bird";
$genero = "aventuras";
?>

Si otro documento quiere incluir estas definiciones, debería hacerlo de la siguiente


manera:

<HTML>
<BODY>
<?php
require("definiciones.php");
echo "Nuestro próximo estreno: $titulo, ";
echo "película del genero $genero, ";
echo "dirigida por $director";
?>
</BODY>
</HTML>

Por supuesto, la inclusión puede tener lugar en cualquier punto, incluso dentro de
una función, tal como ocurre en el código siguiente:

function estreno(){
include("definiciones.php");
echo "Nuestro próximo estreno: $titulo, ";
echo "película del genero $genero, ";
echo "dirigida por $director";
}

En este último caso, al incluirse las definiciones dentro del cuerpo de la función,
las variables definidas pasarán a tener un ámbito local, y por tanto solo podrán ser

210
DEFINICIÓN DE FUNCIONES

utilizadas dentro de esa función. Si se quiere acceder a cualquiera de las tres


variables definidas desde una línea de código externa a la función, se debería
indicar en la definición de la misma que dicha variable sea declarada global:

function estreno(){
global $titulo;
global $director;
global $genero;
include("definiciones.php");
echo "Nuestro próximo estreno: $titulo, ";
echo "película del genero $genero, ";
echo "dirigida por $director";
}

7.6. FUNCIONES VARIABLES


PHP soporta el concepto de funciones variables, lo que significa que el nombre de
una función puede estar almacenado en una variable, y por tanto, cambiar durante
la ejecución del programa. Cuando en un programa PHP una variable va seguida de
los paréntesis que se utilizan para dar valores a los argumentos de una función,
PHP automáticamente buscará una función cuyo nombre coincida con el valor de la
correspondiente variable y tratará de aplicarla.

Ejemplo 7.18:
Supóngase que se dispone de dos funciones diferentes que pueden realizar el
cálculo del precio total a pagar por un número $n de entradas a adquirir:

function precio_normal($n) {
return ($n * 4.5);
}

function precio_reducido($n) {
return ($n * 3);
}

Como puede apreciarse, las dos funciones tienen nombres diferentes, una aplica un
precio de 4.5 á por entrada, mientras que para la otra el precio unitario es de 3.

En el fragmento de código que se incluye a continuación se utiliza una variable


$tarifa que guardará el nombre de la función concreta que se desea aplicar, y se
utiliza esa variable para hacer una llamada a dicha función.

211
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$num_entradas = 5;
$tarifa = "precio_normal";
$importe = $tarifa($num_entradas);
print "El importe total de las $num_entradas entradas
es $importe euros.";

En este caso concreto, se está llamando a la función precio_normal(), y, por


tanto, la salida del programa sería:

El importe total de las 5 entradas es 22.5 euros.

Por supuesto, el valor de la variable que hace referencia a la función podría ser
asignado a partir de determinadas condiciones en el programa, por ejemplo, si el día
actual es un miércoles se podría aplicar la tarifa reducida y en cualquier otro día la
tarifa normal:

if(date("w") == 3)
$tarifa = "precio_reducido";
else
$tarifa = "precio_normal";
$importe = $tarifa($num_entradas);

Para obtener el día de la semana correspondiente al día actual se utiliza la función


date() con el parámetro "w", en esta situación esta función devuelve un valor de
0 a 6, correspondiendo el 0 al domingo y el 6 al sábado.

Si se utilizan funciones variables, se debe tener especial cuidado en evitar la


asignación a la variable de un nombre de una función inexistente, ya que en caso
contrario se produciría un error grave en tiempo de ejecución y se finalizaría
bruscamente la ejecución del programa. Para asegurarse de que una función
realmente existe, PHP dispone de la función function_exists(), que
devuelve un valor booleano indicando si la función cuyo nombre se pasa como
argumento existe o no.

function_exists() busca la correspondiente función tanto entre la funciones


internas del lenguaje como entre las definidas por el propio programador. De
hecho, es posible obtener un array con los nombres de todas las funciones
disponibles en el programa, para ello basta hacer una llamada a una nueva función
de PHP:

get_defined_functions()

212
DEFINICIÓN DE FUNCIONES

Por ejemplo, una simple ejecución de las sentencias

$f = get_defined_functions();
print_r($f);

mostraría en la página una lista con las más de 700 funciones predefinidas en PHP.

213
ARRAYS

8.1. CONCEPTOS FUNDAMENTALES


Los arrays son estructuras de datos que están presentes en prácticamente la
totalidad de lenguajes de programación. Permiten el almacenamiento y
procesamiento de grandes volúmenes de datos sin necesidad de tener que recurrir al
uso de un elevado número de variables. Una vez almacenada la información en un
array, puede accederse a ella y modificarse siempre que sea necesario, gracias a la
multitud de funciones que permiten la gestión y manipulación de arrays, aspecto
este último en el que destaca especialmente el lenguaje PHP.

Este capítulo se centra en explicar los procesos de construcción de arrays y sus


características principales; para terminar abordando con detalle las funciones más
interesantes de manipulación de arrays.

Un array o matriz es un conjunto de datos que se almacenan bajo un nombre


común y a los que se puede acceder utilizando uno o más índices. En PHP los datos
que componen el array pueden ser de diferente tipo, de manera que en un único
array pueden almacenarse indistintamente cadenas de caracteres, valores
numéricos, otros arrays,... Una de las particularidades que distinguen a PHP de
otros lenguajes de programación surge a la hora de crear el array: no es necesario
determinar la dimensión antes de inicializarlo. Esto dota de una gran flexibilidad a

215
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

los programas, pues permite la modificación posterior del array, suprimiendo o


añadiendo nuevos elementos cuando sea necesario.

8.1.1. CONSTRUCCIÓN DE ARRAYS


Los elementos que componen un array, como cualquier otro elemento, son
almacenados en una variable, para indicar que dicha variable contiene un array se
utilizan los caracteres [], situando entre ellos un índice numérico que permitirá
identificar a cada uno de los elementos individuales.

Ejemplo 8.1:
Una primera forma de definir un array consiste en asignar directamente sus valores,
por ejemplo, a continuación se define un array de nombre $x, con cuatro elementos
indexados numéricamente comenzando en la posición 0:

$x[0] = 1;
$x[1] = "¡¡hola!!";
$x[2] = 3;
$x[] = "Último";

A la hora de añadir un último elemento no es necesario indicar el índice


correspondiente. En este ejemplo, automáticamente se asigna a la posición 3.
Además, puede observarse cómo el array puede contener datos de tipos diferentes,
en este caso dos valores numéricos y dos cadenas de caracteres.

Como alternativa se podría haber creado e inicializado el anterior array con ayuda
de la función array(), de la siguiente forma:

$x = array(1, "¡¡hola!!",3, "Último");

En este caso no se han especificado índices y se consideran por defecto los valores
0, 1, 2…

Para acceder a cada uno de los elementos del array, de nuevo se utiliza el índice,
pudiéndose utilizar esos valores en una expresión como cualquier otra variable. Por
ejemplo:

$z = $x[0] + 5*$x[2];

216
ARRAYS

En este primer ejemplo se ha mostrado la forma de construir un array indexado


numéricamente; pero en PHP es posible indexar los elementos de cualquier array
con cadenas de caracteres, lo que permite al programador una identificación más
efectiva de sus elementos. Este tipo de arrays se conocen como arrays asociativos.

Ejemplo 8.2:
Supóngase que se desea almacenar los años de un conjunto de películas. Se puede
construir un array de elementos numéricos (los años) indexados mediante una
cadena de caracteres (el título de la película correspondiente).

$peliculasAño["La costilla de Adán"] = 1949;


$peliculasAño["La gran ilusión"] = 1937;
$peliculasAño["Roma, ciudad abierta"] = 1944;
$peliculasAño["Sabrina"] = 1954;
$peliculasAño["Vive como quieras"] = 1938;

Opcionalmente, con ayuda de la función array() se podría generar el array de la


siguiente manera:

$peliculasAño=array("La costilla de Adán" => 1949,


"La gran ilusión" => 1937,
"Roma, ciudad abierta" => 1944,
"Sabrina" => 1954,
"Vive como quieras" => 1938);

En este caso, al construir el array debe indicarse tanto la palabra clave que actúa de
índice como el valor asociado a ese elemento del array. Aunque el array se haya
construido con la función array(), en cualquier momento se podría añadir un
nuevo elemento:

$peliculasAño["West Side Story"] = 1961;

Para acceder a los elementos del array se utiliza de nuevo la palabra clave:

echo "El año de producción de la película <i>Sabrina</i>


es $peliculasAño[Sabrina]";

En el caso de que la palabra clave no contenga espacios en blanco, basta con


colocar dicha palabra entre los corchetes para acceder al elemento, pero cuando sí
contiene espacios en blanco o caracteres especiales, se debería dar, a su vez,
entrecomillada.

$a = $peliculasAño["Roma, ciudad abierta"];

217
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Cualquier intento de acceso a un elemento del array mediante un índice


o palabra clave no definida produce una notificación de error por parte
del intérprete de PHP. Sin embargo, este tipo de errores no son
NOTA
considerados graves y las restantes sentencias del programa pueden
seguir siendo ejecutadas.

8.1.2. ARRAYS MULTIDIMENSIONALES

El lenguaje PHP permite la creación de arrays multidimensionales, es decir, arrays


cuyos elementos son nuevos arrays. La sintaxis es similar al caso de una
dimensión, siendo necesario indicar los dos índices por separado.

Ejemplo 8.3:
A continuación se crea un array de nombre $M y de dos dimensiones:

$M[0][0] = 5;
$M[0][1] = 3;
$M[1][0] = -2;
$M[1][1] = 7;

La definición equivalente usando la función array() sería:

$M=array(array(5,3),array(-2,7));

Para acceder a los elementos individuales del array se deberían utilizar los dos
índices:

$d = $M[0][0]*$M[1][1] - $M[0][1]*$M[1][0];

Por supuesto, es posible definir arrays asociativos multidimensionales, e incluso


combinar índices numéricos y alfabéticos

Ejemplo 8.4:
$pelicula["George Cukor"][1949] = "La costilla de Adán";
$pelicula["Jean Renoir"][1937] = "La gran ilusión";
$pelicula["Roberto Rossellini"][1944] = "Roma, ciudad
abierta";
$pelicula["Billy Wilder"][1954] = "Sabrina";
$pelicula["Frank Capra"][1938] = "Vive como quieras";

218
ARRAYS

Conviene advertir de la necesidad de tener especial cuidado al utilizar arrays


multidimensionales dentro de cadenas de caracteres ya que para que se expandan
correctamente deben ser encerrados entre llaves.

echo "Hoy se proyectará una producción de 1937 dirigida


por
Jean Renoir: {$pelicula["Jean Renoir"][1937]}";

Ejemplo 8.5:
También es posible indexar los elementos de un array multidimensional:

$peliculas = array(
"La costilla de Adán" =>
array("Director"=>"G. Cukor","Año"=>1949),
"La gran ilusión" =>
array("Director"=>"J. Renoir","Año"=>1937),
"Roma, ciudad abierta" =>
array("Director"=>"R. Rossellini","Año"=>1944),
"Sabrina" =>
array("Director"=>"B. Wilder, "Año"=>1954),
"Vive como quieras" =>
array("Director"=>"F. Capra","Año"=>1938)
);

echo "El director de la película


<i>Roma, ciudad abierta</i>
es
{$peliculas["Roma, ciudad abierta"]["Director"]}";

8.2. RECORRIDO DE TODOS LOS ELEMENTOS


DE UN ARRAY
Una vez creado e inicializado un array unidimensional o multidimensional, puede
que se esté interesado en mostrar o manipular todos sus elementos. Para mostrar
todos los elementos de un array, una primera opción es el uso de la función
print_r(), que aplicada sobre un array muestra en la página la estructura del
mismo de acuerdo al siguiente esquema:

([indice1]=>elemento1
[indice2]=>elemento2
....................
[indiceN]=>elementoN)

219
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Para la manipulación de los elementos de arrays se dispone de estructuras iterativas


que simplifican la tarea, en particular, es de destacar una sentencia específica para
recorrer todos los elementos de un array:

foreach(array as valor)

Ejemplo 8.6:
La siguiente sentencia recorre todos los elementos de un array y los muestra en la
página:

$actors = array("Marlon Brando","Gary Cooper",


"Cary Grant","James Stewart");
foreach($actores as $nombre){
echo "$nombre <br>";
}

Cada elemento del array se asigna en cada iteración a una misma variable, (en el
ejemplo, la variable $nombre), que es la que se manipula. El ejemplo se limita a
imprimir uno a uno todos los nombres que componen el array. Se ha añadido un
comando <HTML> de cambio de línea de forma que cada nueva iteración comience
a escribir en un nuevo renglón. El resultado sería:

Marlon Brando
Gary Cooper
Cary Grant
James Stewart

Si además de recuperar los elementos del array, se desea también conocer el índice,
tanto en el caso de índices numéricos como en arrays asociativos, se puede utilizar
una sintaxis alternativa del bucle foreach:

foreach(array as índice => valor)

Ejemplo 8.7:
Dado el array y el bucle siguientes:

$películasAño = array("La costilla de Adán" => 1949,


"La gran ilusión" => 1937,
"Roma, ciudad abierta" => 1944,
"Sabrina" => 1954,
"Vive como quieras" => 1938);
foreach($películasAño as $indice => $valor){

220
ARRAYS

echo "<i>$indice,</i> ($valor) <br>\n";


}

el resultado generado sería:

La costilla de Adán, (1949)


La gran ilusión, (1937)
Roma, ciudad abierta, (1944)
Sabrina, (1954)
Vive como quieras, (1938)

También es posible construir bucles que recorran todos los elementos del array
usando las restantes estructuras iterativas. El problema que surge habitualmente es
que puede no saberse cuántos elementos existen en el array y cuáles son los índices
asociados a esos elementos, ya que una particularidad de los arrays de PHP es que
no es necesario que sus elementos tengan asociados índices numéricos
consecutivos. Estos problemas pueden salvarse mediante la función

each(array)

En cada llamada a dicha función se recupera un elemento del array; cuando se


alcance el final del array la función devuelve un valor booleano falso. Realmente,
en cada llamada a la función each() se recupera un array con dos elementos, el
primero el índice y el segundo el valor del correspondiente elemento del array. Se
puede utilizar la función list() para asignar esos dos elementos a sendas
variables y operar posteriormente con ellas. Esta función permite generar una lista
cuyos elementos son los argumentos que se pasen, cuando se asigna a esa lista un
array, PHP realiza una asignación elemento a elemento con las variables de la lista
y los elementos del array.

Ejemplo 8.8:
La siguiente estructura iterativa recorre e imprime todos los elementos del array
$actores:

while(list($ind,$nombre) = each($actores))
echo "$nombre <br>";

Mientras no se alcance el final del array, en cada iteración del ciclo, el índice del
elemento del array se almacena en la variable $ind y el elemento correspondiente
en la variable $nombre. Tras alcanzar el último elemento, la función
each()toma el valor falso y el ciclo while finaliza.

221
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Por supuesto, también es posible utilizar estas estructuras iterativas anidadas para
recorrer arrays multidimensionales.

Ejemplo 8.9:
$peliculas=array(
"La costilla de Adán" =>
array("Director"=>"G. Cukor","Año"=>1949),
"La gran ilusión" =>
array("Director"=>"J. Renoir","Año"=>1937),
"Roma, ciudad abierta" =>
array("Director"=>"R. Rossellini","Año"=>1944),
"Sabrina" =>
array("Director"=>"B. Wilder","Año"=>1954),
"Vive como quieras" =>
array("Director"=>"F. Capra","Año"=>1938)
);
foreach($peliculas as $indice => $titulo){
echo "Datos de $indice:<BR>\n";
foreach($titulo as $indice => $valor){
echo "&nbsp&nbsp $indice: $valor <BR>\n";
}
}

El resultado generado por estas estructuras iterativas es:

Datos de La costilla de Adán:


Director: G. Cukor
Año: 1949
Datos de La gran ilusión:
Director: J. Renoir
Año: 1937
Datos de Roma, ciudad abierta:
Director: R. Rossellini
Año: 1944
Datos de Sabrina:
Director: B. Wilder
Año: 1954
Datos de Vive como quieras:
Director: F. Capra
Año: 1938

222
ARRAYS

Cuando se desea conocer el número de elementos de un array, puede usarse la


función count(). Debe advertirse que esta función devuelve el número de
elementos del array y que esa cantidad no necesariamente coincide con el índice de
su último elemento, ya que en PHP no es necesario utilizar índices consecutivos
para los elementos del array.

Ejemplo 8.10:
A continuación se define una función de creación de tablas. Toma como argumento
un array bidimensional, que se asume indexado numéricamente con valores
0,1,2,..., y muestra todos sus elementos en una tabla HTML. La función también
recibe como argumentos un array con los rótulos de las columnas y otro con los
encabezamientos de las filas.

function crearTabla($a,$col,$f) {
echo "<TABLE BORDER CELLPADDING=5>";
//Cabecera
echo "<TR>";
echo "<TD>&nbsp</TD>";
for($i=0;$i<count($col);$i++){
echo "<TH>$col[$i]</TH>";
}
echo "</TR>";
// Cuerpo de la tabla
for($i=0;$i<count($a);$i++){
echo "<TR>";
// encabezado de la fila i-ésima
echo "<TH>$f[$i]</TH>";
// resto de la fila
for($j=0;$j<count($a[$i]);$j++){
echo "<TD>{$a[$i][$j]}</TD>";
}
echo "</TR>";
}
echo "</TABLE>";
}

Considérese, por ejemplo, la necesidad de mostrar una tabla de distancias


kilométricas entre una serie de ciudades, tal como se ve en la Figura 8.1. El
siguiente programa construye dicha tabla utilizando la función anterior y calcula la
distancia en kilómetros de una ruta determinada. Se asume que la función anterior
se encuentra definida en otro documento, de nombre funciones.php, y se utiliza la
función include() para incluirla.

223
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 8.1 Tabla de distancias kilométricas

<?php
include("funciones.php");
echo "<H2>Cálculo de distancias de rutas</H2><BR>";
$datos = array(array(0,100,124,198,235),
array(100,0,224,98,34),
array(124,224,0,115,56),
array(198,98,115,0,122),
array(235,34,56,122,0));
// Generación de los arrays de cabeceras
$cabecera = array();
for($i=0;$i<count($datos[0]);$i++){
$aux = $i+1;
$cabecera[$i] = "Ciudad $aux";
}
// Construcción de la tabla
crearTabla($datos,$cabecera,$cabecera);
// Determinación de la ruta
$ruta = array(1,3,5,1);
$suma = 0;
// Generación de una lista con los datos de cada etapa
echo "<UL>";
for($i=0;$i<count($ruta)-1;$i++){
$aux1 = $ruta[$i];
$aux2 = $ruta[$i+1];
$distancia = $datos[$aux1-1][$aux2-1];

224
ARRAYS

$suma += $distancia;
echo "<LI>De la ciudad $aux1 a la
ciudad $aux2: $distancia kilómetros";
}
echo "<B>Distancia total: $suma kilómetros</B>";
echo "</UL>";
?>

8.3. FUNCIONES DE MANIPULACIÓN DE


ARRAYS
En esta sección se describen las funciones más representativas a la hora de
manipular un array. Estas funciones permiten, entre otras cosas, la modificación de
los índices o de los elementos de un array, la subdivisión o prolongación, la
comparación de elementos entre arrays, la búsqueda de un índice o de un elemento
concretos, etc. Atendiendo a la tarea descrita se agruparán los diversos métodos en
categorías diferentes. Es de destacar la gran diversidad de funciones predefinidas
para la manipulación de arrays que existen en PHP.

8.3.1. TRANSFORMACIÓN DE LOS ÍNDICES


— array_change_key_case(array,caso): en el caso de arrays
asociativos, esta función devuelve un nuevo array pero transformando las
palabras clave a mayúsculas o minúsculas, según el argumento opcional
caso. Los valores posibles de este segundo argumento son las constantes
CASE_UPPER (conversión a mayúsculas) y CASE_LOWER (conversión a
minúsculas), siendo este último el valor por defecto.

Ejemplo 8.11:
El siguiente fragmento de código:

$actores["Primer actor"] = "Gary Cooper";


$actores["Segundo actor"] = "Cary Grant";
$actores["Tercer actor"] = "Spencer Tracy";
$actoresMay=array_change_key_case($actores,CASE_UPPER);
foreach($actoresMay as $indice => $valor)
echo "$indice: $valor <BR>\n";

225
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

produce la siguiente salida:

PRIMER ACTOR: Gary Cooper


SEGUNDO ACTOR: Cary Grant
TERCER ACTOR: Spencer Tracy

8.3.2. SUBDIVISIÓN

— array_chunk(array,dimensión,valor_booleano): el array dado


como argumento se subdivide en arrays más pequeños de dimensión la
indicada con el argumento dimensión. Se genera así un array
multidimensional de índices numéricos que comienzan con el valor 0. El
último parámetro es un valor booleano que indica si se desea conservar los
índices del array original en los diferentes subarrays. Este parámetro es
opcional, siendo su valor por defecto FALSE.

Ejemplo 8.12:
El siguiente código:

$oeste = array(
"Solo ante el peligro","Fred Zinnemann","Gary Cooper",
"Raíces profundas","George Stevens","Alan Ladd",
"Horizontes de grandeza","William Wyler");
$oesteOrdenado = array_chunk($oeste,3);
foreach($oesteOrdenado as $indice => $valor){
echo "$indice-> <BR>";
foreach($valor as $indice => $valor){
echo "&nbsp&nbsp&nbsp $indice-> $valor <BR>";
}
}

da lugar a la salida:
0->
0-> Solo ante el peligro
1-> Fred Zinnemann
2-> Gary Cooper
1->
0-> Raíces profundas
1-> George Stevens
2-> Alan Ladd
2->

226
ARRAYS

0-> Horizontes de grandeza


1-> William Wyler

Se ha considerado el valor por defecto del último argumento, lo que provoca que
cada nuevo subarray se numere desde 0. Si se quieren conservar los índices del
array original, se debe dar como tercer argumento el valor TRUE:

$oesteOrdenado = array_chunk($oeste,3,TRUE);

De esta manera, el resultado obtenido sería:

0->
0-> Solo ante el peligro
1-> Fred Zinnemann
2-> Gary Cooper
1->
3-> Raíces profundas
4-> George Stevens
5-> Alan Ladd
2->
6-> Horizontes de grandeza
7-> William Wyler

8.3.3. CONTABILIZACIÓN DE ELEMENTOS

— array_count_values(array): devuelve un array formado por valores


numéricos que representan el número de veces que cada elemento del array
inicial aparece repetido. Los índices de esta nueva matriz son cada uno de los
elementos iniciales.

— count(array): devuelve el número de elementos de un array. Es útil en


especial cuando se emplea un bucle for para acceder a cada elemento del
array.

Ejemplo 8.13:

$a = array("a", "b", "c", "a", "d", "e", "b", "d", "a");


$n = count($a);
echo "El array tiene $n letras, repartidas
de la siguiente manera: <BR>";

227
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$c = array_count_values($a1);

foreach($c as $indice=>$valor)
echo "$indice: $valor <BR>\n";

El resultado generado sería:

El array tiene 9 letras, repartidas de la siguiente manera:


a: 3
b: 2
c: 1
d: 2
e: 1

8.3.4. BÚSQUEDA DE DATOS

Para la realización de procesos de filtrado y búsquedas sobre los elementos de un


array PHP dispone de funciones muy útiles. A continuación se presentan
brevemente alguna de ellas, acompañadas de sencillos ejemplos ilustrativos.

— array_filter(array,función): aplica una función de filtro booleana


a cada uno de los elementos de un array dado. Aquellos para los que se obtiene
el valor de retorno TRUE forman parte de un nuevo array de salida,
conservando sus índices originarios.

Ejemplo 8.14:
A continuación se muestra un ejemplo de selección de determinadas películas de
una lista en función de su año de producción. En concreto, se trata de conseguir de
las películas almacenadas, las realizadas desde el año 1960 en adelante:

function año($a){
return($a >= 1960);
}

$peliculas = array("El apartamento"=>1960,"Charada"=>1963,


"Doctor Zhivago"=>1965,"Gigí"=>1958,
"El gran dictador"=>1940,"El hombre tranquilo"=>1952,
"Lawrence de Arabia"=>1962,"West Side Story"=>1961
);

$selección = array_filter($peliculas,"año");

228
ARRAYS

foreach($seleccion as $indice=>$valor)
echo "$indice: $valor <BR>\n";

Como puede apreciarse, lo primero que se necesita es una función booleana que,
dado un elemento del array, indique si debe ser seleccionado o no. El nombre de
esa función es pasado a array_filter() como segundo argumento. El
resultado final del programa anterior sería:

El apartamento: 1960
Charada: 1963
Doctor Zhivago: 1965
Lawrence de Arabia: 1962
West Side Story: 1961

— array_keys(array,elemento): devuelve un array con los índices del array


dado como primer argumento. Opcionalmente, se pueden pedir únicamente aquellos
correspondientes a un elemento dado.

Ejemplo 8.15:
El siguiente programa lista los nombres de los actores que aparecen como claves en
un array asociativo:

$actores=array(
"Gary Cooper" => array("Solo ante el peligro",
"La gran prueba", "El secreto de vivir"),
"Cary Grant" => array("La fiera de mi niña",
"Arsénico por compasión","Historias de
Filadelfia"),
"Marlon Brando" => array("La ley del silencio",
"Sayonara","¡Viva Zapata!")
);

$busqueda=array_keys($actores);
foreach($busqueda as $indice=>$valor)
echo "$valor <br>\n";

Como resultado se obtiene la lista:

Gary Cooper
Cary Grant
Marlon Brando

229
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 8.16:
En este segundo caso, se localizan los índices asociados a un determinado valor. En
concreto, se listan las películas almacenadas correspondientes al año 1940:

$peliculas=array(
"El apartamento"=>1960,"Charada"=>1963,
"Doctor Zhivago"=>1965,"Gigí"=>1958,
"El gran dictador"=>1940,"Historias de
Filadelfia"=>1940,
"El hombre tranquilo"=>1952,"Lawrence de Arabia"=>1962,
"Rebeca"=>1940
);

$busqueda=array_keys($peliculas,1940);
foreach($busqueda as $indice=>$valor)
echo "$valor <br>\n";

Se obtiene así el siguiente listado:

El gran dictador
Historias de Filadelfia
Rebeca

— array_key_exists(índice,array): función booleana que devuelve el valor


TRUE si el índice dado está en el array.

Ejemplo 8.17:
Dado el array $actores definido en el Ejemplo 8.15, se comprueba si el nombre
de un actor está entre las palabras claves del array, y en caso afirmativo se muestra
el listado de todas sus películas:

$actor="Gary Cooper";

if(array_key_exists($actor,$actores)) {
echo "<B>Películas de $actor:</B><BR>";
foreach($actores[$actor] as $indice=>$valor)
echo "$valor <BR>\n";
}

— array_rand(array,num_elementos): devuelve un array formado al


seleccionar aleatoriamente los índices correspondientes a un número de
elementos del array dado. El segundo parámetro es opcional, si no se indica se
asume el valor 1.

230
ARRAYS

Ejemplo 8.18:
En el siguiente ejemplo, se diseña una página de manera que cada vez que un
usuario accede a ella obtiene entradas gratis para dos películas de un ciclo de cine:

$peliculas=array("El halcón maltés","Laura","Cayo Largo",


"El sueño eterno","Forajidos");
// se obtienen al azar los índices de dos películas
$sorteo = array_rand($peliculas,2);
echo "<H2>¡Enhorabuena! Ha conseguido entradas gratis para
los pases de las siguientes películas del ciclo de
cine negro:</H2>";
// se muestran las películas seleccionadas
for ($i = 0; $i<count($sorteo); $i++ ){
$j = $sorteo[$i];
echo "<H3><I>$peliculas[$j]</I></H3>";
}

El resultado de la ejecución de este programa es una página como la que aparece en


la Figura 8.2; por supuesto, cada vez que se acceda a esa página el resultado varía,
ya que el sorteo se repite.

Figura 8.2 Resultado del sorteo

— array_search(elemento_buscado,array,valor_logico):
devuelve el índice de elemento_buscado si este pertenece al array dado.
En caso contrario, devuelve FALSE. Si dicho elemento aparece más de una vez
dentro del array, solo se obtiene el índice correspondiente a la primera
aparición. El tercer argumento es opcional y corresponde a un valor lógico que

231
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

indica si el elemento a buscar debe coincidir con el del array tanto en el valor
como en el tipo.

— array_values(array): devuelve una lista con todos los elementos del


array dado, donde ahora los índices son los numéricos por defecto,
independiente de los que tuviera previamente.

— in_array(elemento,array): busca un elemento dado dentro de un


array. Devuelve TRUE si dicho elemento pertenece al array, FALSE en caso
contrario.

8.3.5. GENERACIÓN DE ARRAYS


A continuación se recogen algunas funciones que permiten generar arrays a partir
de valores individuales o a partir de otros arrays.

— array_combine(índices,elementos): función que devuelve un


array formado por los elementos dados como segundo argumento. Se indexan
en correspondencia con el primer argumento de la función. Ambos argumentos
deben ser arrays. La función devuelve el valor FALSE si ambos argumentos no
tienen el mismo número de elementos.

— compact(ListaVariables): dada una lista de variables, se genera


un array asociativo con los valores de esas variables, utilizando como
palabras clave para los elementos del array el nombre de la
correspondiente variable. Las variables se pueden pasar o bien con
cadenas de caracteres conteniendo el nombre de las mismas, o bien
introduciendo dichos nombres en un array.

Ejemplo 8.19:
A partir de tres variables que almacenan los datos de una determinada película,
(título, director y año),

$película = "La diligencia";


$director = "J. Ford";
$año = 1939;

se desea generar un array formado por esos tres elementos e indexados con el
nombre de sus respectivas variables. Esto se podría hacer de dos maneras:

232
ARRAYS

$listaAux=array("pelicula","director","año");
$lista=compact($listaAux);

o bien:

$lista=compact("pelicula","director","año");

— extract(array,extracción): este método procede de forma inversa al


anterior. En este caso, a partir de un array con elementos indexados se genera
una serie de variables de nombre igual a cada uno de los índices y de valor el
elemento correspondiente. De forma opcional se puede indicar la forma de
extracción, es decir qué hacer si existe una variable inicializada previamente y
de nombre igual a alguno de los índices. En concreto, algunos de los valores
que puede tomar el segundo argumento son las constantes:

EXTR_OVERWRITE: la variable ya existente toma el nuevo valor. Este es


el valor que se toma por defecto.
EXTR_SKIP: la variable ya existente no modifica su valor.
EXTR_PREFIX_SAME: se añade un prefijo (tercer argumento en forma de
cadena de caracteres) a la nueva variable.
EXTR_PREFIX_ALL: se añade un prefijo a todas las variables.

Ejemplo 8.20:
A continuación se crean tres variables a partir de los índices de un array dado y se
inicializan automáticamente con los valores correspondientes. Obsérvese que
previamente a la construcción del array y a la llamada a la función extract(),
ya se ha inicializado una variable de nombre idéntico a uno de los índices del array.

$titulo = "Misión de audaces";


$película = array("titulo"=>"La diligencia",
"director"=>"J. Ford",
"protagonista"=>"J. Wayne");
extract($pelicula);
echo "$titulo, de "$director, con "$protagonista";

Al no indicarse forma de extracción, la variable $titulo toma el nuevo valor,


con lo que el mensaje que se genera es:

La diligencia, de J. Ford, con J. Wayne

233
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Si en lugar de la llamada a la función extract() con un solo parámetro, se hace la


llamada siguiente:

extract($pelicula,EXTR_SKIP);

el resultado sería:

Misión de audaces, de J. Ford, con J. Wayne

— range(inicio,final,aumento): se genera un array numérico o de


caracteres, comenzando en el valor inicial hasta llegar al valor final dado.
Como argumento opcional, se incluye el criterio de paso de un elemento a otro,
cuyo valor por defecto es 1. Este tercer argumento fue incorporado en la
versión 4.4 del lenguaje. La Tabla 8.1 muestra algunos ejemplos de uso de la
función range().

Sentencia Array generado


range(3,15) (3,4,5,6,7,8,9,10,11,12,13,14,15)
range(15,3) (15,14,13,12,11,10,9,8,7,6,5,4,3)
range(3,10,2) (3,5,7,9)
range('b','k') ('b','c','d','e','f','g','h','i','j','k')
range('k','b') ('k','j','i','h','g','f','e','d','c','b')
range('casa','gato') ('c','d','e','f','g')
Tabla 8.1 Ejemplos de usos de la función range()

— array_slice(array,fragmento,dimensión): se obtiene un array a


partir de determinados elementos de uno dado. Estos elementos se determinan
con ayuda de los argumentos fragmento y dimensión, de acuerdo a los
siguientes criterios:
ƒ Si fragmento es positivo, indica la posición a partir de la cual se
extraen los elementos de la matriz dada.
ƒ Si fragmento es negativo, extrae elementos comenzando por el final
del array. El número de elementos a extraer coincide en este caso con
el valor sin signo de fragmento.
ƒ Si se indica el argumento dimensión, este representa el número de
elementos a extraer, en el caso de ser positivo, o el número de
elementos a dejar en el array, en el caso de que sea negativo.

234
ARRAYS

La Tabla 8.2 muestra algunos sencillos ejemplos del uso de esta función.

Sentencia Array generado


$a = array(1,2,3,4,5,6)
array_slice($a,3) (4,5,6)
array_slice($a,-2) (5,6)
array_slice($a,3,2) (4,5)
array_slice($a,-2,1) (5)
array_slice($a,1,-2) (2,3,4)
array_slice($a,-4,-2) (3,4)
Tabla 8.2 Ejemplos de uso de la función array_slice()
— array_splice(array,frag,dim,nuevo): si no se especifica como
cuarto argumento una lista de elementos nuevos, este método funciona
exactamente igual que el anterior. En caso contrario, estos nuevos elementos
sustituyen a los eliminados.

Ejemplo 8.21:
Las siguientes sentencias permiten apreciar el funcionamiento de esta función:

$a = array(1,2,3,4,5,6);
print_r($a);
print "<br>";
/* inserción de tres nuevos elementos, en sustitución del
cuarto y el quinto: a1=(1,2,3,0,1,2,6) */
array_splice($a,3,2,array(0,1,2));
print_r($a);
print "<br>";

El resultado de la ejecución de estas sentencias es:

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 0 [4] => 1 [5] => 2 [6] => 6 )

Ejemplo 8.22:
El siguiente ejemplo muestra una página de actualización del listado de directores
de los que se tienen películas disponibles.

$directores = array("Frank Capra","John Ford",


"Elia Kazan","Jean Renoir",
"Roberto Rossellini","William Wyler");

235
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

//Lista de directores dados de baja


$directoresAus = array("Jean Renoir","William Wyler");

// bucle que recorre todos los directores dados de baja


for($i=0;$i<count($directoresAus);$i++){
// se comprueba si pertenece a la lista general
if(in_array($directoresAus[$i],$directores)){
// en caso afirmativo se accede a su índice
$posicion = array_search($directoresAus[$i],
$directores);
//y se procede a la sustitución
array_splice($directores,$posicion,1,
"$directoresAus[$i]=><b>No
disponible</b>");
}
}
echo "<H2>Bienvenido. Esta es nuestra lista
actualizada de directores</H2>";
foreach($directores as $indice=>$valor)
echo "<i>$valor</i> <br>";

La página generada por este programa puede ver en la Figura 8.3.

Figura 8.3 Lista de directores

236
ARRAYS

8.3.6. PROLONGACIÓN O TRUNCAMIENTO DE UN


ARRAY

— array_fill(índice,cantidad,elemento): función que devuelve


un array en el que se ha introducido un elemento dado tantas veces como se
desee a partir de un índice también dado.

— array_pad(array,tamaño_final,elemento_nuevo): prolonga el
array dado con un nuevo elemento, hasta completar el tamaño especificado. La
prolongación se realiza por la derecha o por la izquierda, dependiendo de si el
valor del argumento tamaño_final es positivo o negativo,
respectivamente. El correcto funcionamiento de la operación exige que el
tamaño especificado en el argumento sea mayor que la dimensión del array.

— array_pop(array): extrae el último elemento de una matriz dada,


quedando esta modificada con un elemento menos.

— array_push(array,elemento1,elemento2,...): añade al array


dado los elementos que se indican como argumentos. La función devuelve la
nueva dimensión del array.

— array_shift(array): extrae el primer elemento del array dado,


quedando este modificado con un elemento menos.

— array_unique(array): elimina los elementos repetidos del array dado,


conservándose únicamente la primera posición encontrada de dichos
elementos. La función devuelve un nuevo array, manteniendo los índices
anteriores de sus elementos.

Ejemplo 8.23:
La función array_unique() considera elementos iguales aquellos cuya
representación en forma de cadena es idéntica. Este ejemplo ilustra su
funcionamiento:

$a = array(1,2,"1",3,4,5,"4",6,7,"6",8,6);
$b = array_unique($a);
foreach($b as $indice=>$valor)
echo "$indice: $valor <BR>\n";

237
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El resultado obtenido es:

0: 1
1: 2
3: 3
4: 4
5: 5
7: 6
8: 7
10: 8

— array_unshift(array,elementos): función que añade al inicio del


array dado los elementos indicados como argumentos y devuelve el número de
elementos del nuevo array.

8.3.7. COMBINACIÓN DE ARRAYS

— array_merge(array1,array2,array3,...): devuelve un nuevo


array formado uniendo todos los elementos de los arrays pasados como
argumentos. Si dos o más elementos tienen el mismo índice alfabético en
varios de los arrays iniciales, se incluye en la unión el último de ellos.

Ejemplo 8.24:
A continuación se muestra la unión de dos arrays asociativos en los que una de las
claves se repite en ambos.

$peliculas1 = array(
"B. Wilder"=>"Primera plana",
"J. Ford"=>"Río Grande",
"G. Cukor"=>"Cena a las ocho");
$peliculas2 = array(
"F. Capra"=>"Sucedió una noche",
"B. Wilder"=>"Sabrina",
"W. Wyler"=>"Horizontes de grandeza");
$p = array_merge($peliculas1,$peliculas2);

Como resultado de la unión se generaría un array $p con los siguientes elementos:

("B. Wilder"=>"Sabrina", "J. Ford"=>"Río Grande",


"G. Cukor"=>"Cena a las ocho", "F. Capra"=>"Sucedió una noche",
"W. Wyler"=>"Horizontes de grandeza").

238
ARRAYS

— array_diff_assoc(array1,array2,array3,...): función que


devuelve un array formado por los elementos del array dado como primer argumento
y que no se encuentren en ninguno de los restantes arrays. Los índices de los
elementos se tienen en cuenta en la comparación, es decir, un mismo valor pero
asociado a índices diferentes en los dos arrays no se considera igual.

— array_diff(array1,array2,array3,...): a diferencia de la función


anterior, aquí no se tienen en cuenta los índices, se comparan exclusivamente los
valores de los elementos; por lo demás el funcionamiento de la función es el mismo.

— array_intersect_assoc(array1,array2,array3,...): devuelve un
array con los elementos comunes a todos los argumentos de la función. En la
comparación se tienen en cuenta los índices.

— array_intersect(array1,array2,array3,...): a diferencia de la
función anterior, en este caso, se realiza la intersección pero los índices de los
elementos no se tienen en cuenta en la comparación.

Ejemplo 8.25:
Dados los siguientes arrays:

$oeste = array("a"=>"J. Ford", "b"=>"W. Wyler",


"c"=>"H. Hawks", "d"=>"G. Stevens");
$comedia = array("a"=>"J. Ford", "b"=>"F. Capra",
"c"=>"G. Cukor", "d"=>"H. Hawks");
$drama = array("a"=>"W. Wyler", "b"=>"D. Sirk",
"c"=>"R. Walsh", "d"=>"G. Cukor");

Si se realiza la operación:

$c = array_diff_assoc($oeste,$comedia,$drama);

se obtendría un array con los siguientes elementos:

("b"=>"W. Wyler", "c"=>"H. Hawks", "d"=>"G. Stevens")

pues, si bien los tres primeros elementos del array $oeste se repiten en posteriores
arrays, únicamente el primero de ellos aparece repetido con el mismo índice.
Si en lugar de utilizar la función array_dic_assoc() se ejecuta la siguiente
sentencia:

$c = array_diff ($oeste,$comedia,$drama);

239
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

el array $c sería:

("d"=>"G. Stevens")

ya que ahora los tres primeros elementos del array $oeste deberían ser
eliminados al estar repetidos en los otros, aunque los índices o palabras clave
puedan ser iguales.

8.3.8. APLICACIÓN DE FUNCIONES

— array_map(función,array1,array2,...): función que devuelve


un nuevo array donde cada uno de sus elementos es el resultado de aplicar la
función dada como primer argumento, a los elementos respectivos elementos
de array1, array2,…. El número de argumentos de función deberá
coincidir con el de arrays dados. En cuanto a la longitud de estos, si es
diferente, el de menor número de elementos se prolonga con elementos vacíos.

Ejemplo 8.26:
El siguiente programa toma una lista con los nombres y apellidos de una serie de
directores de cine. El objetivo es crear una lista nueva donde el nombre de cada
director aparece solo con su inicial. En el programa se utilizan algunas funciones
de manipulación de cadenas de caracteres que serán estudiadas con más detalle en
el próximo capítulo.

/* función que toma la primera palabra de una cadena y la


transforma en su inicial seguida de un punto. */
function abreviar($cadena){
// primera palabra de la cadena
$separacion = strtok($cadena," ");
// concatenación de la inicial con un punto
$abrev = substr($separacion,0,1).".";
// generación de la cadena resultado
return(str_replace($separacion,$abrev,$cadena));
}

// Definición del array


$directores=array("D1"=>"Charles Chaplin",
"D2"=>"Stanley Donen","D3"=>"John Ford",
"D4"=>"David Lean","D5"=>"Vincent Minnelli");

// Aplicación de la función sobre cada director

240
ARRAYS

$directoresAbrev = array_map("abreviar",$directores);
// Impresión del resultado
foreach($directoresAbrev as $indice=>$valor){
echo "$indice -> $valor<BR>";
}

La salida generada por el programa es:

D1 -> C. Chaplin
D2 -> S. Donen
D3 -> J. Ford
D4 -> D. Lean
D5 -> V. Minnelli

Ejemplo 8.27:
En el caso de considerar más de un array, la función a aplicar debe tener más de un
argumento. El siguiente programa muestra un ejemplo de esta situación:

function union($a1,$a2){
return("El Óscar del año $a1 es $a2.");
}

$años = array(1940,1945,1951,1955,1960);
$peliculas = array("Rebeca","Días sin huella",
"Un americano en París","Marty",
"El apartamento");

$oscar = array_map("union",$años,$peliculas);

Tras aplicar la función array_map(), el array $oscar tendría el siguiente


contenido:

(0=>" El Óscar del año 1940 es Rebeca.",


1=>" El Óscar del año 1945 es Días sin huella.",
2=>" El Óscar del año 1951 es Un americano en París.",
3=>" El Óscar del año 1955 es Marty.",
4=>" El Óscar del año 1960 es El apartamento.")

Ejemplo 8.28:
Con la ayuda de la función array_map() es posible construir un array
multidimensional a partir de una serie de arrays unidimensionales. En el siguiente
ejemplo se muestra el proceso:

241
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$películas = array("El apartamento","Charada",


"Doctor Zhivago","Gigí",
"El gran dictador","El hombre
tranquilo");
$directores = array("B. Wilder","S. Donen","D. Lean",
"V. Minnelli","C. Chaplin","J. Ford");
$a = array(1960,1963,1965,1958,1940,1952);

//Se incluye como primer argumento null


$listado=array_map(null,$peliculas,$directores,$a);

Si se indica como primer argumento de la función array_map() la palabra


null, no se considerará ninguna función a aplicar y lo que se generará es un array
bidimensional en el que cada elemento es un array con el título de la película, su
director y su año de realización.

— array_walk(array,nombreFunción,argumentos): aplica una


función determinada a cada elemento de la matriz dada y a su correspondiente
clave. Los argumentos de la función aplicada deben ser, por este orden:
elemento, índice, otros argumentos.

Ejemplo 8.29:
Dado un array de años, correspondientes a películas dadas como índices, a continuación
se utiliza la función array_walk() para escribir en la página un listado con el título
de cada película junto con su año entre paréntesis. Para ello se define previamente una
función que realiza genera el mensaje correspondiente a cada película, y se pasa como
segundo argumento a array_walk() el nombre de esa función:

function unir($a,$b){
echo "$b, ($a).<BR>";
}

$peliculas = array(
"El apartamento"=>1960,
"Charada"=>1963,
"Doctor Zhivago"=>1965,
"Gigí"=>1958,
"El gran dictador"=>1940,
"Historias de Filadelfia"=>1940,
"El hombre tranquilo"=>1952,
"Lawrence de Arabia"=>1962,
"Rebeca"=>1940
);

242
ARRAYS

array_walk($peliculas,'unir');

El resultado final de la llamada a esta función es:

El apartamento, (1960).
Charada, (1963).
Doctor Zhivago, (1965).
Gigí, (1958).
El gran dictador, (1940).
Historias de Filadelfia, (1940).
El hombre tranquilo, (1952).
Lawrence de Arabia, (1962).
Rebeca, (1940).

En la llamada a array_walk() se pueden pasar argumentos adicionales que serán


enviados a la función a evaluar junto con el índice y valor de cada elementos del
array. Por ejemplo, definiendo la siguiente función:

function unir2($a,$b,$cadena){
echo "$b, $cadena $a.<BR>";
}

la sentencia

array_walk($peliculas,'unir2',"película realizada en ");

generaría una salida como esta:

El apartamento, película realizada en 1960.


Charada, película realizada en 1963.
Doctor Zhivago, película realizada en 1965.
Gigí, película realizada en 1958.
El gran dictador, película realizada en 1940.
Historias de Filadelfia, película realizada en 1940.
El hombre tranquilo, película realizada en 1952.
Lawrence de Arabia, película realizada en 1962.
Rebeca, película realizada en 1940.

243
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

8.3.9. ORDENACIÓN DE LOS ELEMENTOS DE UN


ARRAY

En el aspecto de funciones de ordenación de arrays, PHP destaca especialmente por


la disponibilidad de un buen número de funciones diferentes.

— asort(array) y arsort(array): estas funciones permiten ordenar los


elementos de una lista dada, bien en orden ascendente (asort) o descendente
(arsort). Su particularidad es que cada elemento conserva su índice original.

Ejemplo 8.30:
Dado el array del Ejemplo 8.29, si se desea que la lista mostrada incluya las
películas en orden cronológico, desde la más actual a la más antigua, podría
realizarse una simple llamada a la función arsort() antes de la llamada a
array_walk(). La ordenación se produce sobre el valor de los elementos del
array, permaneciendo la clave de cada uno inalterada.

arsort($peliculas);
array_walk($peliculas,'unir',"película realizada en ");

La salida obtenida sería:

Doctor Zhivago, película realizada en 1965.


Charada, película realizada en 1963.
Lawrence de Arabia, película realizada en 1962.
El apartamento, película realizada en 1960.
Gigí, película realizada en 1958.
El hombre tranquilo, película realizada en 1952.
Rebeca, película realizada en 1940.
El gran dictador, película realizada en 1940.
Historias de Filadelfia, película realizada en 1940.

— ksort(array) y krsort(array): ordenan los elementos del array según


el índice o clave correspondiente, bien en orden ascendente (ksort) o inverso
(krsort). Se mantiene la relación entre índice y valor del elemento.

Ejemplo 8.31:
Si en el ejemplo anterior se opta por el orden inverso de los índices:

244
ARRAYS

krsort($peliculas);

el resultado sería:

Rebeca, película realizada en 1940.


Lawrence de Arabia, película realizada en 1962.
Historias de Filadelfia, película realizada en 1940.
Gigí, película realizada en 1958.
El hombre tranquilo, película realizada en 1952.
El gran dictador, película realizada en 1940.
El apartamento, película realizada en 1960.
Doctor Zhivago, película realizada en 1965.
Charada, película realizada en 1963.

— natsort(array) y natcasesort(array): estas dos funciones


ordenan cadenas alfanuméricas de un array dado atendiendo al orden alfabético
natural. La diferencia entre ambos es que natcasesort() no distingue
entre mayúsculas y minúsculas. Se conserva la relación entre índice y
elemento.

— array_reverse(array): devuelve un nuevo array con los elementos del


array original, pero dispuestos en orden inverso.

— sort(array) y rsort(array): estos métodos reordenan los


elementos de una matriz en orden ascendente o inverso, respectivamente. Los
índices se reasignan según la nueva disposición.
Ejemplo 8.32:
Como ejemplo final, se crea a continuación una tabla a partir de un array de
películas. Las películas serán clasificadas atendiendo a su director y a su año de
producción. La página generada por el programa es la que se muestra en la Figura
8.4.

Los datos a partir de los que se generará la tabla se encuentran almacenados en el


siguiente array bidimensional:

$películas = array(
"Ariane"=>
array("Director"=>"B. Wilder","Año"=>1957),
"La costilla de Adán"=>
array("Director"=>"G. Cukor","Año"=>1949),
"La gran ilusión"=>
array("Director"=>"J. Renoir","Año"=>1937),

245
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

"El héroe solitario"=>


array("Director"=>"B. Wilder","Año"=>1957),
"Historias de Filadelfia"=>
array("Director"=>"G. Cukor","Año"=>1940),
"Roma, ciudad abierta"=>
array("Director"=>"R. Rossellini","Año"=>1944),
"Vive como quieras"=>
array( "Director"=>"F. Capra","Año"=>1938)
);

El programa que genera la tabla es:

echo "<H2>Películas disponibles</H2><BR>";


// array de encabezados de filas: años de producción
$filas = array();
$i = 0;
foreach($peliculas as $titulo){
$filas[$i] = $titulo["Año"];
$i++;
}
// eliminación de años repetidos
$filas = array_unique($filas);
// ordenación en orden ascendente
sort($filas);
// array con nombres de directores
$columnas = array();
$i = 0;
foreach($peliculas as $titulo){
$columnas[$i] = $titulo["Director"];
$i++;
}
// eliminación de repetidos
$columnas = array_unique($columnas);
// ordenación alfabética por apellidos
function extraer($cadena){
return(strchr($cadena," "));
}
$columnasAbrev = array_map("extraer",$columnas);
natcasesort($columnasAbrev);
$indices = array_keys($columnasAbrev);
// encabezados ordenados de las columnas
$columnasOrdenado = array();
for($i=0;$i<count($indices);$i++){
$columnasOrdenado[$i] = $columnas[$indices[$i]];
}
// construcción de la tabla
echo "<TABLE BORDER CELLPADDING=5>\n";

246
ARRAYS

echo "<TR>";
echo "<TD>&nbsp</TD>";
for($i=0;$i<count($columnasOrdenado);$i++){
echo "<TH>$columnasOrdenado[$i]</TH>";
}
echo "</TR>";
// lista con los títulos que hay que colocar en la tabla
$datos = array_keys($peliculas);

// en cada año se recorren los nombres ordenados de los


// directores y se disponen en la fila los títulos de ese
// año que correspondan a uno o a varios de los directores
for($i=0;$i<count($filas);$i++){
echo "<TR>";
echo "<TH>$filas[$i]</TH>";
for($j=0;$j<count($columnasOrdenado);$j++){
// se obtiene la lista de películas
correspondientes
// a la pareja director - año
$ps=array_keys($peliculas,

array("Director"=>$columnasOrdenado[$j],
"Año"=>$filas[$i]));
// si hay alguna película se crea la celda con
// los títulos obtenidos
if(count($ps)!=0){
echo "<TD ALIGN=CENTER>";
for($k=0;$k<count($ps);$k++){
echo $ps[$k]."<br>";
}
echo "</TD>";
}
// en caso contrario la celda es vacía
else
echo "<TD ALIGN=CENTER>"."----------"."</TD>";
}
echo "</TR>";
}
echo "</TABLE>";

247
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 8.4 Página con la tabla de películas disponibles

248
FUNCIONES
PREDEFINIDAS

9.1. INTRODUCCIÓN
PHP cuenta con un gran número de funciones predefinidas, más de 700, que
pueden ser usadas en cualquier programa sin necesidad de invocar a ninguna
librería. En el capítulo previo ya han sido presentadas muchas de ellas, en
concreto, las relacionadas con el tratamiento y manipulación de arrays. En este
capítulo se presentarán algunas funciones predefinidas adicionales,
clasificándolas en diversos grupos atendiendo al cometido al que están
destinadas. Se empezará por presentar funciones de manipulación de cadenas de
caracteres, para finalizar con el repaso a las funciones de fechas y horas, y una
lista de funciones matemáticas. En capítulos posteriores del libro se presentarán
nuevas funciones, como son las relacionadas con ficheros y directorios,
funciones de conectividad a base de datos,...

249
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

9.2. FUNCIONES DE MANIPULACIÓN DE


CADENAS DE CARACTERES

9.2.1. RECONOCIMIENTO DE CARACTERES


Las funciones de tipo booleano que a continuación se detallan permiten detectar los
diversos tipos de caracteres que constituyen una cadena determinada. En concreto,
pueden resultar muy útiles para realizar operaciones de validación de los datos que
los usuarios introducen en los formularios. A esta categoría pertenecen las
funciones siguientes:

— ctype_alnum(cadena): devuelve TRUE si cada carácter de la cadena es


alfanumérico (letra o un número), FALSE en caso contrario.
— ctype_alpha(cadena): devuelve TRUE si cada carácter de la cadena es
una letra, FALSE en caso contrario.
— ctype_digit(cadena): devuelve TRUE si cada carácter de la cadena es
un dígito decimal, FALSE en caso contrario.
— ctype_lower(cadena): devuelve TRUE si cada carácter de la cadena es
una letra minúscula, FALSE en caso contrario.
— ctype_upper(cadena): devuelve TRUE si cada carácter de la cadena es
una letra mayúscula, FALSE en caso contrario.
— ctype_print(cadena): devuelve TRUE si cada carácter de la cadena es
un carácter imprimible (letras, dígitos, signos, espacios en blanco,…)
— ctype_punct(cadena): devuelve TRUE si cada carácter de la cadena es
imprimible pero no es ni una letra, ni un dígito ni un espacio en blanco.
— ctype_space(cadena): devuelve TRUE si cada carácter de la cadena es
un espacio en blanco, considerando como espacios en blanco también las
tabulaciones, retornos de carro,...

9.2.2. CONVERSIONES ENTRE CADENAS Y ARRAYS


En muchas ocasiones se necesita obtener cadenas de caracteres a partir de los
elementos de un array, o al revés, "trocear" una cadena de caracteres para formar
un array con los elementos resultantes. Para este tipo de labores PHP dispone de las
siguientes funciones:

250
FUNCIONES PREDEFINIDAS

— explode(separador,cadena,límite): función que devuelve un array


resultado de fragmentar una cadena dada en segmentos delimitados por una cadena
de separación, (un espacio en blanco, por ejemplo). Si no se indica límite, cada
elemento del array es uno de esos segmentos. En caso contrario, este valor indica el
número exacto de elementos que debe tener el array de salida. El último de ellos
corresponderá al final de la cadena que no haya podido fragmentarse.

— implode(separador,array) y join(separador,array):
funciones que disponen los elementos de un array dado en una cadena
de caracteres, pero separados por la cadena dada como primer
argumento. Ambas funciones actúan de igual forma.

Ejemplo 9.1:
La sentencia

explode(" ","Hola, ¿qué tal?");

genera un array de 3 cadenas de caracteres:

([0] => Hola, [1] => ¿qué [2] => tal?)

Si al hacer la llamada a la función explode() se añade un valor límite

explode(" ","Hola, ¿qué tal?", 2);

el array que se obtendría es:

([0] => Hola, [1] => ¿qué tal? )

Ejemplo 9.2:
En el siguiente programa, dado un array de arrays, se aplica la función implode() a
cada uno de sus elementos para obtener una serie de cadenas de caracteres.

$peliculasMusicales=array(
array("Un americano en París","V. Minnelli",1951),
array("Hello,Dolly!","G. Kelly",1968),
array("¡Qué noche la de aquel día!","R. Lester",1964));

foreach($peliculasMusicales as $pelicula){
$p = implode("--->",$pelicula);
print "$p<BR>";
}

251
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El resultado generado es:

Un americano en París--->V. Minnelli--->1951


Hello, Dolly!--->G. Kelly--->1968
¡Qué noche la de aquel día!--->R. Lester--->1964

— str_word_count(cadena,formato): contabiliza el número de


palabras que forman una cadena dada. Si no se especifica ningún formato,
se obtiene un número entero. Si el argumento formato toma el valor 1,
entonces la función devuelve un array con todas las palabras de la cadena;
si ese argumento es 2, devuelve el array con las palabras, pero asociando a
cada una como índice del array la posición que ocupa dentro de la cadena.

Ejemplo 9.3:
Dada la siguiente cadena:

$cadena = "Bienvenido a nuestro cine.";

la sentencia

str_word_count($cadena);

devuelve el número de palabras que forman la frase indicada, es decir, 4.

Si la llamada se realiza de la siguiente forma:

str_word_count($cadena,1);

la función devolvería es siguiente array:

([0] => Bienvenido, [1] => a, [2] => nuestro, [3] => cine)

En cambio, con la llamada

str_word_count($cadena,2);

el array generado sería:

([0] => Bienvenido, [11] => a, [13] => nuestro, [21] => cine)

252
FUNCIONES PREDEFINIDAS

9.2.3. PROLONGACIÓN DE UNA CADENA


— str_pad(cadena,longitud,cadena_añadida,clase_adición)
: devuelve una nueva cadena formada al prolongar la cadena dada al inicio, al
final o en ambos lados hasta completar la longitud indicada. Si no se indica una
nueva cadena, la prolongación se realiza con espacios en blanco. El tipo de
prolongación viene determinado por el cuarto argumento de la función, cuyo
valor pueder ser:

STR_PAD_RIGHT: prolongación al final de la cadena. Valor por defecto.


STR_PAD_LEFT: prolongación al inicio.
STR_PAD_BOTH: prolongación en ambas direcciones.

Si la longitud indicada es negativa o menor que la de la cadena inicial, no se


efectúa la prolongación.

Ejemplo 9.4:
Considérese una cadena de 27 caracteres de longitud, si se quiere prolongarla a
ambos lados con 16 caracteres, repartidos a partes iguales a ambos lados, el código
necesario sería el siguiente:

echo str_pad("¡Bienvenido a nuestro cine!",


41,"********",STR_PAD_BOTH);

generándose de este modo la cadena

********¡Bienvenido a nuestro cine!********

Si como longitud se indica 30, 3 más que la inicial, aunque la nueva cadena aporte
8 caracteres, se truncará en 3, repartidos a izquierda y derecha. Así, el código:

echo str_pad("Bienvenido a nuestro cine",


30,"********",STR_PAD_BOTH);

genera la cadena:

*Bienvenido a nuestro cine**

— str_repeat(cadena,número): devuelve una cadena formado al repetir


la cadena dada tantas veces como se indica en el segundo argumento.

253
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 9.5:
La sentencia:

echo str_repeat("oOoxXx",5);

genera el siguiente mensaje:

oOoxXxoOoxXxoOoxXxoOoxXxoOoxXx

9.2.4. MODIFICACIÓN DE UNA CADENA


— str_replace(buscar,reemplazar,cadena): función que devuelve
una nueva cadena como resultado de reemplazar en la cadena dada todas las
apariciones del argumento buscar por el argumento reemplazar.

Ejemplo 9.6:
Dadas las variables

$cadena = "Bienvenido a nuestro cine.";


$nombreCliente = "Pablo González";

la sentencia

echo str_replace(".", ", $nombreCliente.", $cadena);

escribiría el siguiente mensaje:

Bienvenido a nuestro cine, Pablo González.

— strrev(cadena): devuelve una nueva cadena como resultado de invertir la


cadena original.

— strtolower(cadena) y strtoupper(cadena): funciones que, dada una


cadena, generan otra transformando todos los caracteres a minúsculas o a
mayúsculas, respectivamente.

— substr_replace(cadena,reemplazar,posición,longitud): dada
una cadena inicial se obtiene una nueva cadena como resultado de reemplazar
la porción delimitada por los argumentos posición y longitud, por el

254
FUNCIONES PREDEFINIDAS

argumento reemplazar. Se deben tener en cuenta las siguientes


consideraciones:

• Si el valor de posición es positivo, la sustitución comienza


en la posición correspondiente de la cadena; mientras que si es
negativo, la sustitución comienza en la posición correspondiente
de la cadena pero contando desde el final de la misma.
• Si no se especifica el argumento longitud, se entiende que la
sustitución se realiza hasta el final de la cadena. Por el
contrario, si su valor es positivo indica la porción de cadena a
sustituir, y si es negativo indica el número de caracteres,
contados desde el final de la cadena, que deben quedar intactos.
En todo caso se considera que la posición del primer carácter es
0.

Ejemplo 9.7:
Dadas las cadenas

$cadena = "Bienvenido a nuestro cine. Ha efectuado usted


la
decisión correcta.";
$nombreCliente = ", Pablo González. ";

las llamadas siguientes

substr_replace($cadena,$nombreCliente,25,1);
substr_replace($cadena,$nombreCliente,25,-41);
substr_replace($cadena,$nombreCliente,-42,1);
substr_replace($cadena,$nombreCliente,-42,-41);

generan todas el mismo resultado, la cadena

Bienvenido a nuestro cine, Pablo González. Ha efectuado usted la decisión


correcta.

— ucfirst(cadena): convierte a mayúsculas el primer carácter de la cadena


dada.

— ucwords(cadena): convierte a mayúsculas el primer carácter de cada


palabra de la cadena dada.

255
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

9.2.5. COMPARACIÓN DE CADENAS


— strcasecmp(cadena1,cadena2) y strcmp(cadena1,cadena2):
comparan dos cadenas dadas según el orden establecido por los códigos ASCII
de sus respectivos caracteres (orden computacional). Ambas funciones
devuelven un valor menor que 0 si cadena1 es menor que cadena2; un
valor mayor que 0 si cadena1 es mayor que cadena2 y 0 si ambas son
iguales. La única diferencia entre las dos funciones es que la segunda distingue
mayúsculas y minúsculas.

— strnatcasecmp(cad1,cad2) y strnatcmp(cad1,cad2):
comparan cadenas alfanuméricas teniendo en cuenta el orden alfabético
natural. Se obtiene un valor menor que 0 si la primera cadena es menor
que la segunda; un valor mayor que 0 si es mayor y 0 si ambas son
iguales. La única diferencia entre ambas funciones es que la primera no
distingue entre mayúsculas y minúsculas.

Ejemplo 9.8:
La comparación de cadenas alfabéticas como las siguientes da el mismo resultado
independientemente de la función de comparación empleada:

strcasecmp("Pedro Colsa", "pedro colsa"); // devuelve 0


strcmp("Pedro Colsa", "pedro colsa"); // devuelve -1
strnatcasecmp("Pedro Colsa","pedro colsa"); // devuelve 0
strnatcmp("Pedro Colsa","pedro colsa"); // devuelve -1

En el caso de cadenas alfanuméricas, el resultado varía:

//orden computacional: a11 < a2


strcasecmp("a11","a2"); // devuelve -1
strcmp("a11","a2"); // devuelve -1
//orden lógico: a11 > a2
strnatcasecmp("a11","a2"); // devuelve 1
strnatcmp("a11","a2"); // devuelve 1

9.2.6. BÚSQUEDA DE DATOS


— strchr(cadena,carácter) y strrchr(cadena,carácter):
encuentran la primera y última aparición, respectivamente, de un carácter en

256
FUNCIONES PREDEFINIDAS

una cadena dada. Devuelven la cadena inicial desde la posición localizada


hasta el final.

— stristr(cadena,fragmento) y strstr(cadena,fragmento):
devuelven la cadena dada desde la primera aparición de un carácter o
fragmento determinado. Si el fragmento no se encuentra, se obtiene el valor
booleano FALSE. La diferencia entre ambos métodos es que el primero no
distingue entre mayúsculas y minúsculas.

— strpos(cadena,fragmento,inicio_búsqueda): se obtiene la
posición correspondiente a la primera aparición de un fragmento determinado
dentro de una cadena dada. Como tercer argumento opcionalmente se puede
indicar la posición a partir de la cual iniciar la búsqueda.

— strrpos(cadena,carácter): devuelve la posición correspondiente a la


última aparición de un carácter dentro de una cadena dada.

— substr(cadena,posición_inicial,longitud): se extrae de una


cadena dada, una subcadena delimitada por los dos últimos argumentos. Si el
valor de posición_inicial es positivo, el fragmento comienza en la
posición correspondiente de la cadena; mientras que si es negativo, el
fragmento comienza en la posición correspondiente de la cadena pero contando
desde el final de la misma. Si no se indica el argumento longitud, se extrae
el fragmento hasta el final de la cadena. Por el contrario, si su valor es positivo,
indica la dimensión del fragmento extraído, y si es negativo, la extracción
finaliza a tantos caracteres desde el final de la cadena como indica dicho valor.

— substr_count(cadena,fragmento): devuelve el número de


apariciones de un fragmento dado dentro de una cadena.

Ejemplo 9.9:
Dada la cadena:

$cadena = "¡Bienvenido a nuestros cines!"

la Tabla 9.1 muestra algunos ejemplos de usos de las funciones anteriores.

De la misma manera, la Tabla 9.2 muestra nuevos ejemplos de usa de la función


substr(), pero tomando como cadena de partida:

257
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$cadena = "Bienvenido a nuestro cine. Ha efectuado usted


la
decisión correcta.";

Llamada a la función Valor devuelto


strchr($cadena,'e'); envenido a nuestros cines!
strrchr($cadena,'e'); es!
stristr($cadena,"nuestros"); nuestros cines!
stristr($cadena,'e'); envenido a nuestros cines!
strpos($cadena,"e"); 3
strpos($cadena,"e",14); 16
strpos($cadena,"nuestros"); 14
Tabla 9.1 Ejemplos de usos de funciones de búsqueda en cadenas

Llamada a la función Valor devuelto


substr($cadena,27); Ha efectuado usted la decisión correcta.
substr($cadena,-27); usted la decisión correcta.
substr($cadena,27,5); Ha ef
substr($cadena,27,-5); Ha efectuado usted la decisión corr
substr($cadena,-45,10); ine. Ha ef
substr($cadena,-45,-5); ine. Ha efectuado usted la decisión corr

Tabla 9.2 Ejemplos de uso de la función substr()

9.2.7. SUBDIVISIÓN DE CADENAS


— wordwrap(cadena,ancho,separación): particiona el texto de la
cadena dada en líneas del ancho indicado. Por defecto, si no se indica otra cosa,
el texto se fragmenta al llegar a una anchura de 75 con un carácter de cambio
de línea: '\n'.

— strtok(cadena,delimitador): se fragmenta la cadena dada según la


delimitación indicada. La primera llamada a este método devuelve el primer
fragmento. Las siguientes llamadas requieren como único argumento el
delimitador.

Ejemplo 9.10:
El siguiente código fragmenta una cadena dada considerando como delimitador la coma:

$p = "Solo ante el peligro, Fred Zinnemann, Gary Cooper";


// escritura del título (hasta la primera coma)

258
FUNCIONES PREDEFINIDAS

echo strtok($p,',');
echo "<BR>";
// $i cuenta el número de comas leídas
$i = 1;
// número total de comas dentro de la cadena inicial
$frecuencia=substr_count($p,',');
// bucle que fragmenta el resto de la cadena
while($i<=$frecuencia){
echo strtok(',');
echo "<BR>";
$i++;
}

La salida generada por este programa sería:

Solo ante el peligro


Fred Zinnemann
Gary Cooper

9.2.8. LONGITUD DE UNA CADENA


strlen(cadena): devuelve la longitud de una cadena, es decir, el número de
caracteres que contiene.

9.3. FUNCIONES DE FECHA Y HORA


Otro grupo importante de funciones predefinidas en PHP está constituido por todas
las que permiten realizar manipulaciones con fechas y horas.

En PHP cualquier instante de tiempo viene determinado por un número entero que
representa el número de segundos transcurridos desde las 00:00 del día 1 de enero
de 1970; así por ejemplo, la función que calcula el instante de tiempo actual,
función time(), devuelve en realidad un número entero. Por supuesto, es posible
trabajar con fechas y horas en formatos más sencillos para el usuario, para ello
PHP dispone de la función mktime() que permite generar instantes de tiempo y
la función date() para convertir el instante de tiempo en una cadena de
caracteres siguiendo un formato preestablecido.

A continuación se recogen las funciones más importantes para trabajar con


instantes de tiempo y se ilustra su funcionamiento con algunos ejemplos.

259
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— time(): devuelve la hora actual expresada como el número de segundos


transcurridos desde las 00 horas del 1 de enero de 1970.

— mktime(hora,minuto,segundo,mes,día,año): devuelve un instante


de tiempo identificado por el número de segundos transcurridos desde las 00:00
del 1 de enero de 1970 hasta el momento determinado por los argumentos pasados.
Obsérvese el orden en el que deben ser pasados estos argumentos. Los argumentos
son opcionales, de manera que cualquier argumento omitido tomará
automáticamente el valor correspondiente al instante actual.

— checkdate(mes,día,año): devuelve el valor entero 1 si la fecha dada


como argumento es válida, entendiendo por fecha valida aquella que sigue los
siguientes criterios:
o El año debe estar comprendido entre 0 y 32767.
o El mes entre 1 y 12.
o El día debe estar en el rango admisible del mes considerado. Se
tienen en cuenta los años bisiestos.

— date(formato,instante): devuelve una cadena de caracteres con la


fecha y/o hora de acuerdo al formato indicado en el primer argumento. El
segundo argmento será un número entero que identificará el instante asociado a
dicha fecha y hora. Este segundo argumento es opcional, en caso de omitirse se
asumirá automáticamente la fecha y hora actual en el servidor.

La cadena de formato que recibe la función date() como primer argumento


incluye determinados caracteres con un significado especial. La siguiente lista
incluye alguno de estos caracteres, explicando el significado de su presencia en la
cadena de formato:

Formato para el año:


— “Y” con cuatro dígitos.
— “y” con dos dígitos.
Día del año:
— “z” de 0 a 365.
Formato para el mes:
— “F” el nombre completo en inglés.
— “M” nombre abreviado en inglés.
— “m” del 01 al 12.
— “n” del 1 al 12.
— “t” número de días del mes.

260
FUNCIONES PREDEFINIDAS

Formato para el día del mes:


— “d” del 01 al 31.
— “j” del 1 al 31.
Formato para el día de la semana:
— “l” nombre completo en inglés.
— “D” nombre abreviado en inglés.
— “w” día de la semana del 0 (domingo) al 6 (sábado).
Formato para la hora:
— “g” la hora de 1 hasta 12.
— “G” la hora de 0 a 23.
— “h” la hora de 01 a 12.
— “H” la hora de 00 a 23.
— “i” los minutos de 00 a 59.
— “s” los segundos de 00 a 59.
— “a” am o pm.
— “A” AM o PM.
Años bisiestos:
— “L” 1 si el año es bisiesto, 0 en otro caso.

Ejemplo 9.11:
El siguiente programa genera una página de bienvenida en la que se muestra la
fecha local del servidor con el formato escogido en el correspondiente argumento
de la función date():

print("Bienvenido, la hora local en nuestro servidor es: ");


print(date("h:i A"));
print(" y estamos en el día ");
print(date("z"));
print(" del año ");
print(date("Y."));

En la página aparecerá un mensaje como el siguiente:

Bienvenido, la hora local en nuestro servidor es: 06:03 PM y estamos en el


día 296 del año 2004.

Ejemplo 9.12:
Si se quiere mostrar el mes en curso, basta la siguiente línea de código:

print(date("M"));

261
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Sin embargo, si se quiere mostrar un mes del año, distinto al actual, se debe añadir
como segundo argumento de la función date() una llamada a la función
mktime() con los argumentos adecuados: en este caso, basta indicar el número
de mes y un día del mes, (el 1, por ejemplo):

print(date("M",mktime(0,0,0,1,1,0)));

Ejemplo 9.13:
Si se desea averiguar el día de la semana correspondiente al 2 de marzo de 1972 se
podría escribir la siguiente línea de código:

print(date("w",mktime(0,0,0,3,2,1972)));

Se obtiene el valor 4, correspondiente al jueves.

Ejemplo 9.14:
Mediante el siguiente programa se generará el calendario del mes en curso en el
momento de acceder a una página dada, incluyendo además dos enlaces: uno al
calendario del mes anterior y otro al del mes siguiente. El aspecto de este
calendario puede verse en la Figura 9.1.

Figura 9.1 Calendario del mes actual

262
FUNCIONES PREDEFINIDAS

El programa se estructura en cuatro ficheros:

— Datos.php: fichero de datos generales, que almacena dos arrays con los
nombres de los meses y de los días y variables relacionadas con la fecha en
curso. También implementa la función crearCalendario(), que permite
construir el calendario de un mes y año dados. Toda esta información será
añadida en los restantes ficheros con la sentencia include.
— Calendario.php: construye el calendario del mes en curso en el momento de
acceder a la página y se crean dos enlaces que remiten al calendario del mes
anterior y del mes siguiente, respectivamente.
— MesAnterior.php y MesSiguiente.php: generan el calendario correspondiente al
mes anterior y al mes siguiente al mes en curso.

A continuación se incluye el código completo de cada fichero y se comentan sus


sentencias más significativas:

Fichero Datos.php

<?php
$meses = array("Enero", "Febrero", "Marzo",
"Abril", "Mayo","Junio",
"Julio", "Agosto", "Septiembre",
"Octubre", "Noviembre", "Diciembre");
$semana = array("Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do");
$añoActual = date("Y");
$mesActual = date("n");
$mesActualTr = $meses[$mesActual-1];
$diaActual = date("j");

function crearCalendario($mes,$año,$fechaActual){

$nummes = array_search($mes,$GLOBALS["meses"])+1
$diasemana=date("w",mktime(0,0,0,$nummes,1,$año));
if($diasemana==0)
$diasemana=7;
$diasMes= date("t",mktime(0,0,0,$nummes,1,$año));

// generación del calendario


echo "<B>$mes $año</B>";
echo "<TABLE BORDER ALING=CENTER>";
echo "<TR>";

// cabeceras de la tabla
for($i=0;$i<=6;$i++){

263
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

echo "<TH>".$GLOBALS["semana"][$i]."</TH>";
}
echo "</TR>";

// días en blanco hasta el inicio del mes


echo "<TR>";
$aux = 1;
while($aux<$diasemana){
echo "<TD>&nbsp;</TD>";
$aux++;
}

// días del mes


for($i=1;$i<=$diasMes;$i++) {
if(($diasemana==6) or ($diasemana==7)){
if($fechaActual){
if($i==$GLOBALS["diaActual"])
echo "<TH BGCOLOR=#00FFFF >$i</TH>";
else
echo "<TD BGCOLOR=#00FFFF >$i</TD>";
}
else
echo "<TD BGCOLOR=#00FFFF >$i</TD>";
}
else{
if($fechaActual){
if($i==$GLOBALS["diaActual"])
echo "<TH>$i</TH>”;
else
echo "<TD>$i</TD>";
}
else
echo "<TD>$i</TD>";
}
$diasemana++;
if($diasemana==8) {
echo "</TR>";
echo "<TR>";
$diasemana=1;
}
}
echo "</TR></TABLE>";
}
?>

Como puede apreciarse, este fichero comienza con las definición de dos arrays,
que almacenan los nombres de los meses y de los días de la semana, y cuatro

264
FUNCIONES PREDEFINIDAS

variables que almacenarán el año, el mes y el día del mes correspondientes al


momento de visitar la página. Para la obtención de estos últimos valores se utiliza la
función date().

Posteriormente, se define la función crearCalendario() que toma como


argumentos: un mes expresado como cadena de caracteres, un año en cuatro dígitos
y una variable booleana que toma el valor TRUE si el calendario a construir
corresponde al del mes en curso. Dentro de esta función, para acceder a los arrays y
variables globales definidas fuera de la misma se utiliza el array asociativo
$GLOBALS[]; de esta manera, lo primero que se hace es obtener el número de
mes asociado al mes cuyo nombre se ha recibido como argumento. Posteriormente
se calcula el día de la semana correspondiente al primer día de ese mes, y el
número total de días del mes. Para estas dos operaciones se utiliza de nuevo la
función date(), pero en este caso indicando como último argumento el instante
de tiempo correspondiente a las 0:00 del primer día del mes; este instante de
tiempo se genera con la función mktime().

En PHP, como ocurre en la cultura anglosajona, el primer día de la semana es el


domingo, y dicho día queda identificado con el número 0; es por ello que, para
considerar el domingo como último día de la semana, se asigna el valor 7
cuando sea 0.

Una vez establecidos todos los datos necesarios, la función crearCalendario()


procede a la creación del calendario mediante una tabla HTML generada
dinámicamente. Las celdas correspondientes a los fines de semana tendrán un
sombreado diferentes, y además, en el caso de que el calendario que se crea
corresponda al mes en curso, el día actual se mostrará en negrita.

Fichero Calendario.php

<?php
include("Datos.php");
crearCalendario($mesActualTr,$añoActual,true);
$mesAnt = "MesAnterior.php";
$mesSig = "MesSiguiente.php";
echo "<BR><A HREF=$mesAnt>Mes anterior</A> <BR>
<A HREF=$mesSig>Mes próximo</A>";
?>

Este fichero es el principal, diseña la página donde se muestra el calendario del


mes en curso junto con dos enlaces a los calendarios anterior y próximo,
respectivamente. Como puede observarse, lo primero que se realiza es la inclusión

265
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

del fichero Datos.php mediante la función include(), para posteriormente


efectuar la llamada a la función crearCalendario(), y crear los dos enlaces.

Fichero MesAnterior.php

<?php
include("Datos.php");
if($mesActual==1){
$aux = 11;
$año = $añoActual-1;
}
else{
$aux = $mesActual-2;
$año = $añoActual;
}
crearCalendario($meses[$aux], $año, false);
?>

Fichero MesSiguiente.php

<?php
include("Datos.php");
if($mesActual==12){
$aux = 0;
$año = $añoActual+1;
}
else{
$aux = $mesActual;
$año = $añoActual;
}
crearCalendario($meses[$aux], $año, false);
?>

Estos dos últimos ficheros cargan de nuevo todos los datos y lo único que realizan
es una modificación de las variables que identifican al mes en curso. Una vez
modificadas esas variables se procede a efectuar la llamada a la función de
creación del calendario.

266
FUNCIONES PREDEFINIDAS

9.4. FUNCIONES MATEMÁTICAS


El lenguaje PHP cuenta con una serie de constantes numéricas ya definidas y con
un conjunto de funciones que manipulan valores numéricos, tanto de tipo entero
como en coma flotante. La Tabla 9.4 muestra las constantes de carácter matemático
predefinidas en PHP más comúnmente conocidas.
Respecto a las funciones matemáticas, la Tabla 9.3 muestra algunas de las más utilizadas.

Función Descripción
abs(n) Obtiene el valor absoluto de un entero o en coma flotante.
round(n) Redondea a entero un número dado.
ceil(n) Obtiene el valor entero superior más próximo a n.
floor(n) Obtiene el valor entero inferior más próximo a n.
cos(n) Calcula el coseno de un ángulo.
sin(n) Calcula el seno de un ángulo
tan(n) Calcula la tangente de un ángulo.
exp(a) Calcula el valor ea.
log(n) Calcula el logaritmo neperiano de n.
min(n1,n2,...) Obtiene el menor valor de un número determinado de
min(array) argumentos numéricos o de los elementos de un array.
Si alguno de estos números es decimal, el resultado
también tendrá este formato.
max(n1,n2,…) Obtiene el mayor valor de un número determinado de
max(array) argumentos numéricos o de los elementos de un array.
Si alguno de estos números es decimal, el resultado
también tendrá este formato.
pow(a,b) Se calcula el valor de la potencia ab.
rand(mín,máx) Si no toman argumentos, estas funciones devuelven
mt_rand(mín,máx) un valor aleatorio entre 0 y RAND_MAX. En caso
contrario, se obtiene un número aleatorio entre mín y
máx. El valor RAND_MAX es una cota superior entera
definida por el sistema, que se puede obtener con una
llamada a la función mt_getrandmax().
sqrt(a) Raíz cuadrada de a.

Tabla 9.3 Funciones matemáticas

267
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Constantes numéricas Descripción


M_PI número Pi (3.14159…).
M_E número e (2.718281…).
M_PI_2 pi/2.
M_SQRT2 raíz cuadrada de 2.
M_SQRT3 raíz cuadrada de 3.
Tabla 9.4 Constantes predefinidas

268
PROGRAMACIÓN
ORIENTADA A
OBJETOS

10.1. INTRODUCCIÓN
Los dos elementos básicos de todo lenguaje de programación estructurada son las
variables y las funciones. Las primeras se utilizan para almacenar datos, y las
segundas realizan acciones sobre esos datos. En un esquema de programación
estructurada tradicional ambos elementos básicos se encuentran perfectamente
diferenciados, definiendo las variables por un lado y las funciones por otro.

Sin embargo, a la hora de programar se puede pensar en objetos como entidades


que maneja el programa y que funcionan de una determinada manera. Estos objetos
poseen determinadas características (variables) y con ellos se pueden realizar
diversas tareas (funciones). En un esquema de programación orientada a objetos,
las variables y las funciones no son considerados como elementos independientes
sino como componentes de una misma entidad: el objeto; tal como ocurre con los
objetos de la vida real.

269
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En la programación orientada a objetos, las funciones asociadas a cada objeto


reciben el nombre de métodos. Los métodos permitirán no solo realizar acciones
sobre los objetos sino también extraer información sobre sus variables, enviar
mensajes a otros objetos,...

Los objetos definidos son elementos dinámicos, en todo momento tienen un estado
(determinado por los valores de sus variables) y un comportamiento (determinado
por sus métodos).

Ejemplo 10.1:
Piénsese en la gestión de un cine; en un cine se maneja información sobre
películas, proyecciones, clientes,... En definitiva, se podría pensar en diferentes
objetos con diferentes características (variables) y diferentes acciones (métodos)
que pueden realizar cada uno:

— Cada objeto película tendrá asociadas cuatro variables que indicarán el título,
el director, la lista de actores y el año de producción. Además tendrá un
método que permitirá generar la ficha artística de la película (véase Figura
10.1).

— Cada objeto proyección tendrá asociadas tres variables que indicarán el día y la
hora de la proyección, y la película a proyectar. Un método del objeto permitirá
asignar una película a la proyección (véase Figura 10.2).

— Cada objeto cliente tendrá asociadas tres variables que indicarán el nombre y la
edad del cliente y la lista de proyecciones para las que ha adquirido una
entrada. Además de sus variables, un cliente también dispondrá de un método
que le permitirá adquirir una entrada para una proyección (véase Figura 10.3).

Además de los objetos anteriores, el cine en sí puede verse también como un


objeto:

— El objeto cine tendrá asociadas cinco variables que indicarán el día de la


semana que se considera día del espectador, la tarifa normal y la tarifa
reducida, y las listas de proyecciones disponibles y de clientes del cine. El
objeto cine también podrá realizar una serie de acciones como buscar los datos
de un cliente, calcular el importe de una localidad para un cliente y proyección
concretos, y añadir nuevas proyecciones y clientes (véase Figura 10.4).

270
PROGRAMACIÓN ORIENTADA A OBJETOS

PELÍCULA

VARIABLES: MÉTODO:
• Título • Generar ficha
• Director
• Actores
• Año

Figura 10.1 Estructura de un objeto Película

PROYECCIÓN

VARIABLES: MÉTODO:
• Día • Asignar película
• Hora
• Película

Figura 10.2 Estructura de un objeto Proyección

CLIENTE

VARIABLES: MÉTODO:
• Nombre • Adquirir entrada
• Edad
• Lista proyecciones

Figura 10.3 Estructura de un objeto Cliente

271
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

CINE

VARIABLES: MÉTODOS:
• Día del espectador • Buscar cliente
• Tarifa normal • Calcular importe
• Tarifa reducida • Crear proyección
• Proyecciones • Crear cliente
• Clientes

Figura 10.4 Estructura del objeto Cine

Como puede comprobarse en este esquema, un objeto puede convertirse a su vez en


variable de otro objeto, tal es el caso, por ejemplo, del objeto película asociado al
objeto proyección.

Por último, los objetos podrían disponer de métodos específicos para acceder a sus
variables, tanto para consultar como para cambiar sus valores. Además, los objetos
suelen disponer de métodos, denominados constructores, que son llamados cuando
se crea el objeto.

En las próximas secciones de este capítulo, este esquema organizativo de objetos se


traducirá al lenguaje PHP, presentando conceptos básicos de programación
orientada a objetos como son los de clases, objetos y variables de clase y herencia.

10.2. DEFINICIÓN DE UNA CLASE


Al igual que ocurre en la vida real, los objetos se agrupan en familias o clases de
objetos que comparten características comunes. Así por ejemplo, dos clientes
diferentes tendrán las mismas variables, aunque lógicamente con diferentes valores
para cada uno de ellos, y podrán realizar las mismas acciones; por tanto, serían dos
objetos de una misma clase.

La programación orientada a objetos se basa en definir clases, crear objetos de esas


clases y realizar acciones con ellos. La clase establecerá las características
(variables y métodos) que compartirán todos los objetos de la misma; en este
sentido la clase puede entenderse como un prototipo para los objetos.

272
PROGRAMACIÓN ORIENTADA A OBJETOS

La definición de una clase en PHP comienza con la palabra clave class y un


nombre elegido por el programador; su código completo se delimita entre llaves.
Dentro de ese cuerpo de la clase, las variables se declaran con la palabra var y los
métodos se definen como cualquier otra función en PHP.

class NombreClase {
var
variables de la clase

métodos
}

Ejemplo 10.2:
A continuación se presenta el esquema de las clases de objetos que fueron
presentados en el Ejemplo 10.1. En esta primera aproximación se incluye
únicamente la definición de las variables de cada clase y la declaración de los
métodos; posteriormente se añadirá la implementación completa de estos últimos.

class Pelicula {
var $titulo,
$director,
$actores,
$año;

// implementación de métodos
function generar_ficha() {

}
}

class Proyeccion {
var $dia_hora;
var $pelicula;

// implementación de métodos
function asignar_pelicula($p) {

}
}

class Cliente {
var $nombre;
var $edad;
var $lista_proyecciones;

273
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

// implementación de métodos
function adquirir_entrada($proy) {

}
}

class Cine {
var $dia_espectador,
$tarifa_normal,
$tarifa_reducida,
$lista_proyecciones,
$lista_clientes;

// implementación de métodos
function calcular_importe($c,$proy) {

function crear_proyeccion($t,$p) {

function crear_cliente($n,$e) {

function buscar_cliente($c) {

}
}

Obsérvese la manera de indicar la declaración de variables dentro de una clase.


Tras la palabra clave var, se puede optar por listar todas las variables seguidas de
una coma, con un punto y coma al final de la lista; o bien, por anteponer la palabra
clave antes de cada nueva variable, finalizando siempre en punto y coma.

En el caso de la clase Proyeccion, se ha optado por fusionar las


variables dia y hora en una sola variable de nombre dia_hora.
NOTA
Esta variable almacenará un instante de tiempo generado con la función
mktime(). A partir de este instante de tiempo se puede obtener,
mediante la función date(), cualquier información necesaria, como
la hora de la proyección, la fecha, el día de la semana,...

274
PROGRAMACIÓN ORIENTADA A OBJETOS

10.2.1. CONSTRUCTORES
Las clases definen el prototipo de los objetos, definiendo sus métodos y declarando
sus variables; pero, ¿cómo se inicializan estas variables? Entran aquí en juego dos
nuevos elementos: la variable $this y el constructor de la clase.

Un constructor es un tipo especial de método que se caracteriza por tener el mismo


nombre que la clase y que se utilizará posteriormente para crear los objetos. Este
método se ejecuta automáticamente, por lo que es aquí donde se pueden inicializar
las propiedades del objeto que interesa establecer en el momento de su creación.

La variable $this, en un contexto de programación orientada a objetos, siempre


hace referencia al objeto actual. A través de ella se puede acceder a las variables
particulares del objeto, utilizando la sintaxis:

$this -> nombre_variable

Ejemplo 10.3:
La creación de un objeto de la clase Pelicula exige el aportar la información
necesaria para ese objeto, en este caso concreto, esa información se traduce en los
valores para sus 4 variables. El constructor de la clase puede recibir como
argumentos esos cuatro valores y asignarlos a las respectivas variables del objeto.

function Pelicula($t,$d,$as,$a){
$this->titulo = $t;
$this->director = $d;
$this->actores = $as;
$this->año = $a;
}

Obsérvese cómo la sintaxis, para acceder a las variables del objeto, exige indicar el
nombre de la variable a continuación de -> pero sin el signo $.
Esta misma sintaxis puede ser utilizada dentro de cualquier otro método para
acceder a las variables del objeto. Por ejemplo, a continuación se incluye la
definición completa de la clase Pelicula, incluyendo el método que genera su
ficha artística:

class Pelicula {
var $titulo,
$director,
$actores,
$año;

275
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

// constructor
function Pelicula($t,$d,$as,$a){
$this->titulo = $t;
$this->director = $d;
$this->actores = $as;
$this->año = $a;
}

// implementación de métodos
function generar_ficha() {
print "<H3> $this->titulo ($this->año)</H3>";
print "Dirigida por $this->director y
protagonizada por:<BR>";
foreach($this->actores as $ac)
print "$ac <BR>";
}
}

De manera similar, se podrían definir constructores para las otras 3 clases


analizadas.

Se incluye a continuación el código completo de la clase Cliente, cuya


estructura se muestra en la Figura 10.3:

class Cliente {
var $nombre;
var $edad;
var $lista_proyecciones;

// constructor
function Cliente($n,$e){
$this->nombre = $n;
$this->edad = $e;
$this->lista_proyecciones = array();
}

// implementación de métodos
function adquirir_entrada($proy) {
array_push($this->lista_proyecciones,$proy);
}
}

Es posible que el constructor no reciba todos los valores iniciales para las variables
del objeto y que se disponga de métodos para realizar esa asignación
posteriormente, tal como ocurre en la clase Proyeccion:

276
PROGRAMACIÓN ORIENTADA A OBJETOS

class Proyeccion {
var $dia_hora;
var $pelicula;

// constructor
function Proyeccion($t){
$this->dia_hora = $t;
}

// implementación de métodos
function asignar_pelicula($p) {
$this->pelicula = $p;
}
}

Se puede optar por inicializar algunas variables con valores fijos desde el propio
constructor, por ejemplo, asignando valores por defecto para dichas variables. El
constructor de la clase Cine podría ser:

function Cine($d,$t=5,$tr=3.5){
$this->dia_espectador = $d;
$this->tarifa_normal = $t;
$this->tarifa_reducida = $tr;
$this->lista_proyecciones = array();
$this->lista_clientes = array();
}

10.3. CONSTRUCCIÓN DE OBJETOS


Una vez definidas las clases que intervienen en el programa llega el momento de
crear los objetos particulares. En la terminología de la programación orientada a
objetos estos reciben el nombre de ejemplares de la clase.

La creación de un objeto implica la llamada a un constructor de la clase mediante


el operador new. Si en la definición de una clase no ha sido definido ningún
constructor, entonces PHP utilizará un constructor por defecto; dicho constructor
no recibe ningún argumento.

La sintaxis de creación de un nuevo objeto de una clase es:

obj = new nombreClase(argumentos);

277
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El valor devuelto por el operador new debe ser asignado a una variable para poder
hacer referencia posteriormente a dicho objeto.

Ejemplo 10.4:
Se podría crear un nuevo objeto de la clase Pelicula con la sentencia:

$p = new Pelicula("El halcón maltés",


"J. Huston",
array("H. Bogart", "M. Astor"),
1941);

Como puede observarse el constructor recibe los cuatro argumentos necesarios para
inicializar las cuatro variables del objeto. La tercera de las variables recibirá como
valor un array con los nombres de los protagonistas de la película.

10.3.1. ACCESO A LAS VARIABLES Y MÉTODOS DEL


OBJETO
Tanto a las variables como a los métodos del objeto, se puede acceder utilizando el
operador -> aplicado sobre la variable que almacena el objeto. La sintaxis para
ello es:

Objeto -> variable


Objeto -> metodo(argumentos)

Ejemplo 10.5:
Dado el objeto $p creado en el Ejemplo 10.4, se podría efectuar una llamada

$p->generar_ficha();

El resultado obtenido sería:

El halcón maltés (1941)

Dirigida por J. Huston y protagonizada por:


H. Bogart
M. Astor

278
PROGRAMACIÓN ORIENTADA A OBJETOS

Ejemplo 10.6:
Para completar la definición de las clases del Ejemplo 10.1, se incluye a
continuación la definición de la clase Cine, con la implementación de todos sus
métodos.

class Cine {
var $dia_espectador,
$tarifa_normal,
$tarifa_reducida,
$lista_proyecciones,
$lista_clientes;

// constructor
function Cine($d,$t=5,$tr=3.5){
$this->dia_espectador = $d;
$this->tarifa_normal = $t;
$this->tarifa_reducida = $tr;
$this->lista_proyecciones = array();
$this->lista_clientes = array();
}

// implementación de métodos
function calcular_importe($c,$proy) {
// obtención del dia de la semana de la proyección
$dia_proy = date("w",$proy->dia_hora);
if(($dia_proy == $this->dia_espectador)||
($c->edad)<=15 || ($c->edad>=65))
$t=$this->tarifa_reducida;
else
$t=$this->tarifa_normal;
return $t;
}

function crear_proyeccion($t,$p) {
$proy = new Proyeccion($t);
$proy->asignar_pelicula($p);
array_push($this->lista_proyecciones,$proy);
}

function crear_cliente($n,$e) {
$cl = new Cliente($n,$e);
array_push($this->lista_clientes,$cl);
}

function buscar_cliente($n) {
// búsqueda del nombre en el array de clientes

279
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

foreach($this->lista_clientes as $cliente) {
if($cliente->nombre == $n)
return $cliente;
}
return FALSE;
}

Ejemplo 10.7:
Una vez definidas todas las clases del Ejemplo 10.1 en un fichero de nombre
clases.php, se encuentran listas para ser utilizadas en cualquier otro programa. A
continuación se incluye un sencillo programa que crea diferentes objetos de las
clases anteriores y realiza con ellos las acciones que permiten sus métodos.

include "clases.php";

// creación de un nuevo objeto Cine


// se asigna el miércoles (3) como día del espectador, y
// 6 y 4.5 como tarifas normal y reducida, respectivamente
$c = new Cine(3,6,4.5);

// creación de nuevos clientes con el método del objeto


$c->crear_cliente("Angel Antón",37);
$c->crear_cliente("Rosa Minguez",36);
$c->crear_cliente("Valeria Conde",7);

// creación de una película y una proyección de la misma


$p = new Pelicula("El halcón maltés",
"J. Huston",
array("H. Bogart", "M. Astor"),
1941);
$c->crear_proyeccion(mktime(16,0,0,12,23,2004),$p);

// Generación de un listado con las proyecciones


disponibles
print "<H2> Proyecciones disponibles </H2>";
foreach($c->lista_proyecciones as $pr) {
$dia = date("d/m/Y",$pr->dia_hora);
$hora = date("H:i",$pr->dia_hora);
$pr->pelicula->generar_ficha();
print "Dia: $dia <BR> Hora: $hora <BR>";
}

// Búsqueda de un cliente y cálculo del importe de su

280
PROGRAMACIÓN ORIENTADA A OBJETOS

// localidad para la primera proyección disponible


if($cl=$c->buscar_cliente("Valeria Conde")) {
print "El cliente tiene $cl->edad años";
$pr = $c->lista_proyecciones[0];
$precio = $c->calcular_importe($cl,$pr);
print " y el importe de su entrada es $precio";
}

10.4. HERENCIA
La programación orientada a objetos tiene por objetivo la estructuración de los
programas en clases; cada clase describe las características generales que un objeto
debe poseer. A partir de las clases definidas es posible también diseñar objetos
similares con nuevas particularidades; de esta forma surgen los conceptos de
subclases y herencia.

Al igual que ocurre con los objetos del mundo real, una clase de objetos puede ser
vista como una subclase de otra; de manera que hereda todas las propiedades
(variables y métodos) de la superclase. Sin embargo, la verdadera utilidad de las
subclases es el permitir a estas la definición de nuevas variables, la modificación de
los métodos heredados o la implementación de nuevos métodos.

Ejemplo 10.8:
Sobre el esquema de clases presentado en el Ejemplo 10.1 se podrían realizar
algunas modificaciones. En primer lugar se podrían definir varias subclases que
permitan clasificar las películas que el cine gestiona en función de su género
(Figura 10.5). Así por ejemplo, las comedias constituyen una subclase de películas;
lo que significa que toda comedia tiene las características generales de una
película, pero puede tener características propias de este género.

De la misma manera, se podría pensar en un tipo especial de clientes que recibirán


un tratamiento específico. Por ejemplo, se puede considerar el concepto de socio
como un cliente que participa en un programa de fidelidad por el cual obtiene
puntos a canjear por regalos. Surge así la necesidad de definir el socio como una
subclase de cliente pero incorporando nuevas variables y nuevos métodos.

281
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

PELÍCULA

POLICIACA COMEDIA MUSICAL

Figura 10.5 Subclases de la clase película

CLIENTE

VARIABLES: MÉTODO:
• Nombre • Adquirir entrada
• Edad
• Lista proyecciones

SOCIO

VARIABLES PROPIAS: MÉTODOS PROPIOS:


• Número de socio • Adquirir entrada (*)
• Puntos acumulados • Canjear regalo

Figura 10.6 Estructura de la clase socio, subclase de cliente

Como se aprecia en la Figura 10.6, la subclase Socio dispondrá de dos nuevas


variables no disponibles en un cliente general: una para almacenar un número de
socio y otra para almacenar en todo momento los puntos acumulados por el socio.
En lo que respecta a los métodos, se observa la aparición de uno nuevo (canjear
regalo) y la necesidad de redefinir el método heredado, ya que cuando un socio
adquiera una entrada, se deberá actualizar su saldo de puntos acumulados.

282
PROGRAMACIÓN ORIENTADA A OBJETOS

10.4.1. DEFINICIÓN DE SUBCLASES


Para la definición de subclases en PHP se utiliza la palabra extends seguida del
nombre de la clase de la que descienden (superclase). Dentro de la definición de la
subclase no es necesario volver a declarar todas las variables y métodos de la
superclase, ya que son automáticamente heredados.

La sintaxis general de la definición de subclases es:

class NombreSubclase extends NombreSuperclase {


var
variables de la subclase

métodos de la subclase
}

Ejemplo 10.9:
La definición de las subclases plateadas en el Ejemplo 10.8 serían:

class Policiaca extends Pelicula{

class Musical extends Pelicula{

class Comedia extends Pelicula{

En el caso de la subclase Socio, su definición podría ser la siguiente:

class Socio extends Cliente{

// variables propias de la subclase


var $num_socio,
$puntos;

// constructor
function Socio($n,$e,$num){
$this->nombre = $n;
$this->edad = $e;

283
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$this->lista_proyecciones = array();
$this->num_socio = $num;
$this->puntos = 0;
}

// implementación de métodos
function adquirir_entrada($proy) {
array_push($this->lista_proyecciones,$proy);
$this->puntos += 10;
}

function canjear_regalo(){
$p = $this->puntos;
if($p >= 100) {
print "¡Enhorabuena! ¡Le obsequiamos con
nuestro regalo sorpresa!";
$this->puntos -= 100;
}
else{
$aux = 100-$p;
print "Le faltan $aux puntos para conseguir
un premio";
}
}
}

Como puede observarse, los objetos de esta subclase tienen todas las características
de la clase general Cliente (nombre, edad y lista_proyecciones), pero
además poseen dos nuevos atributos: num_socio y puntos. Cuentan también
con el mismo método adquirir_entrada(), pero definido de nuevo,
adaptándose así a las características de la subclase; en este caso, cada vez que se
adquiera una entrada se incrementará en 10 unidades el valor de la variable
puntos. La subclase incluye también un nuevo método, canjear_regalo(),
que será propio de los objetos de esta nueva clase.

284
COOKIES

11.1. ¿QUÉ SON LAS COOKIES?


Las cookies constituyen un sencillo mecanismo para almacenar información en los
equipos cliente que visitan una página web. La información es enviada por el
servidor web y queda almacenada en el equipo del cliente, bien de forma temporal
en la memoria principal, o permanentemente en la memoria secundaria en forma de
ficheros de texto. La información almacenada en esos ficheros de texto puede ser
recuperada por el servidor web cuando el usuario visite de nuevo la página web u
otras páginas para las cuáles se haya establecido la visibilidad de la cookie.

Las cookies no fueron diseñadas para espiar o invadir la privacidad de los usuarios
de Internet, su principal objetivo es identificar al usuario y poder de esta manera
preparar páginas personalizadas. Son muy prácticas también para almacenar
información como el número de visitas, preferencias, estado de conexión y, en
general, información que sirva para realzar la navegación del cliente y permita
simular una conexión continua. Por ejemplo, gracias a las cookies el usuario podría
continuar la navegación por un sitio web en el último punto en el que lo dejó en su
última conexión.

Es de destacar que las cookies, como simples archivos de texto, no tienen la


posibilidad de realizar ningún tipo de acción sobre el equipo del cliente; es decir,

285
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

no pueden abrir ficheros del usuario, ejecutar programas en el equipo cliente,


establecer conexiones de red,... A pesar de ser inofensivas, el usuario puede, si así
lo desea, configurar su navegador web para que no acepte ningún tipo de cookie,
para que acepte únicamente las que proceden de determinados servidores o para
que pregunte al usuario antes de generar cualquier cookie.

11.2. GENERACIÓN DE COOKIES


Como se ha comentado, las cookies son generadas en el cliente pero por orden del
servidor; de manera que la generación de una cookie puede realizarse
perfectamente desde un programa PHP. En esta sección se verá cómo este proceso
es muy sencillo de realizar.

Es de destacar que cuando se realiza una transferencia HTTP entre un servidor y un


cliente, las cookies son incluidas en la cabecera HTTP, esto implica que cualquier
orden de generación de una cookie desde una página web debe ser dada antes de
cualquier comando HTML.

Para crear una cookie desde un programa PHP se utiliza la función


setcookie(). La sintaxis mínima de esta función es:

setcookie(nombre, valor)

y define una cookie con el nombre y valor indicados en los argumentos. En cierta
forma una cookie puede verse como una variable que tiene un identificador y un
valor asignado, de hecho, el nombre de la cookie se convertirá en nombre de una
variable PHP cuando la cookie sea transferida desde el cliente al servidor.

Recordar de nuevo que el script que incorpore la llamada a la función anterior debe
ser colocado delante de cualquier comando HTML.

La función setcookie() devuelve un valor numérico indicando si se produjo algún


fallo en el proceso. Si devuelve un valor distinto de cero significa que el proceso de
transferencia se realizó correctamente, aunque eso tampoco asegura que la cookie haya
sido creada en el equipo del cliente, ya que este podría no haberla aceptado.

El segundo de los argumentos de la función setcookie() es opcional, si no se


especifica ningún valor para la cookie lo que se estaría haciendo realmente es
borrar del cliente la cookie de nombre dado:

setcookie(nombre)

286
COOKIES

Además de este parámetro opcional, la función setcookie()tiene algunos


parámetros opcionales más, que permiten especificar, por ejemplo, una fecha de
expiración de la cookie, determinar la visibilidad de dicha cookie en el servidor
web, indicar un dominio en el que estará disponible, o indicar que la cookie solo
debe ser transferida bajo conexiones seguras HTTPS.

En concreto, la sintaxis completa de la función setcookie() es:

setcookie(string nombre, string valor, int expiracion, string


path, string dominio, int seguro)

Ejemplo 11.1:
Supóngase que se dispone de un formulario en el que se solicita al usuario que
escriba su nombre y que se desea que ese nombre pueda ser utilizado directamente
cuando el usuario visite otras páginas del servidor.

El código HTML de la página que define el formulario sería el siguiente:

<HTML>
<HEAD><TITLE>Registro</TITLE></HEAD>
<BODY>
<H1>Registro como usuario</H1>
Introduzca su nombre:
<FORM ACTION="cookie.php" METHOD="GET">
<INPUT TYPE="text" NAME="nombre"><BR>
<INPUT TYPE="submit" VALUE="Enviar">
</FORM>
</BODY>
</HTML>

Como puede apreciarse, la página dispone de un formulario con un campo de texto


llamado nombre y la acción a realizar al pulsar el botón de enviar será el envío de
los datos a una nueva página llamada cookie.php. Es en esta nueva página en la que
se generará la cookie, el código completo correspondiente es:

<?php
if (isset($nombre))
setcookie("nomusuario", $nombre);
?>
<HTML>
<HEAD><TITLE>Confirmación</TITLE></HEAD>
<BODY> Muchas gracias por registrarte.
</BODY>
</HTML>

287
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Obsérvese que el script PHP que tiene la definición de la cookie está colocado antes de
cualquier comando HTML, incluso antes del comando <HTML>. Además se utiliza la
función isset() para asegurar que la variable $nombre tiene un valor asignado
correctamente desde el formulario. En el caso de que esta variable tenga un valor
asignado se está generando una cookie de nombre nomusuario y con el valor
introducido por el usuario en el formulario previo.

También es posible definir varias cookies bajo un nombre común, es decir, definir
arrays de cookies. Para ello se utiliza la notación habitual de definición de arrays
en PHP.

Ejemplo 11.2:
Imagínese que se desea guardar en un array de cookies las últimas películas vistas
por cada cliente de Cinem@s, las cookies podrían ser generadas de la siguiente
manera:

setcookie( "peliculas[1]", "Mar adentro" );


setcookie( "peliculas[2]", "Peter Pan" );
setcookie( "peliculas[3]", "Shrek 2" );

En este caso, cuando se recupere el valor de estas tres cookies, se obtendrá una
variable de tipo array y de nombre $peliculas.

11.3. RECUPERACIÓN DE LOS VALORES DE


LAS COOKIES
Un vez que la cookie ha sido generada, esta permanece en el equipo del cliente y
será enviada al servidor cuando se realice una nueva carga de una página del
servidor para la que la cookie sea visible.

Cualquier cookie enviada al servidor desde el cliente, automáticamente se


convertirá en una variable PHP con nombre igual al nombre de la cookie pero
precedida del signo $.

Ejemplo 11.3:
Supóngase que el cliente que se registró en el formulario anterior, y para el que se
ha generado una cookie con su nombre, visita ahora una nueva página del servidor;

288
COOKIES

esta nueva página tendrá acceso a una variable $nomusuario con la que podrá
preparar un contenido personalizado:

<HTML>
<HEAD><TITLE>Cartelera</TITLE></HEAD>
<BODY>
<H1> Nuestra cartelera </H1>
<?php
if (isset($nomusuario))
echo "$nomusuario, nuestros estrenos para ti
son:";
else
echo "Por favor, regístrese";
?>
<TABLE>
.............
.............
.............
</TABLE>
</BODY>
</HTML>

En este caso el uso de la función isset() permite asegurarse de que la cookie se


ha recibido correctamente desde el cliente, en caso de que no se reciba esa cookie
se muestra un mensaje solicitando al cliente que se registre.

Ejemplo 11.4:
En este nuevo ejemplo los procesos de generación y de recuperación de la cookie
tienen lugar en la misma página. Imagínese, que interesa en todo momento conocer
la fecha y hora del último acceso de cada cliente a la página; esto podría realizarse
fácilmente con ayuda de una cookie que se almacene en cada cliente. El código
completo de la página sería:

<?php
$v = date("d/m/Y \a \l\a\s H:i");
setcookie("visita", $v, time()+30*24*3600);
?>
<HTML>
<HEAD><TITLE>Página de inicio</TITLE></HEAD>
<BODY>
<H1>Bienvenido a nuestra página</H1>
<?php
if (isset($visita))
echo "La última vez que nos visitaste fue el $visita";

289
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

?>
....................................
....................................
</BODY>
</HTML>

Como puede verse, en primer lugar se genera una cookie con la fecha y hora de
acceso; este script está colocado antes de cualquier otro código. En el segundo
script se utiliza esa cookie para escribir en la página el momento de ese último
acceso.

Obsérvese igualmente, que en la generación de la cookie anterior se ha utilizado un


nuevo parámetro opcional de la función setcookie(), el parámetro que
determina la fecha de expiración de la cookie. En la próxima sección se explicará
con detalle el funcionamiento de este nuevo parámetro.

Cuando un cliente accede a una página, el servidor solicita los valores de todas las
cookies antes de realizar cualquier otra operación, una vez recibidos esos valores
comienza a procesar la página. Este hecho hace que la cookie generada en el
primer script no será visible hasta la siguiente carga de la página, ya que en primer
lugar el servidor recibe las cookies generadas y posteriormente actualiza su valor
para la siguiente carga.

PHP dispone de una variable global de tipo array en la que siempre se encuentran
almacenadas todas las cookies que el servidor ha recibido del cliente, dicho array
es $HTTP_COOKIE_VARS y se trata de un array asociativo en el que el índice de
cada elemento es el nombre de una cookie y el valor almacenado en el array el
valor de dicha cookie.

Ejemplo 11.5:
Si se ha definido una cookie de la siguiente manera:

setcookie("micookie", "Mar adentro");

se podrá acceder a su valor con cualquiera de las dos sintaxis siguientes:

$micookie

$HTTP_COOKIE_VARS["micookie"]

290
COOKIES

Utilizando la estructura iterativa foreach resulta muy sencillo generar en la


página un listado con los nombres y valores de todas las cookies visibles en cada
instante.

foreach($HTTP_COOKIE_VARS as $c) {
echo "$c <BR>";
}

Otra posibilidad para recorrer todas las cookies definidas sería:

while (list($n,$v)=each($HTTP_COOKIE_VARS)) {
echo "$n = $v <BR>";
}

A partir de la versión PHP 4.1.0 también se dispone del array de cookies definidas
en otra variable global de nombre $_COOKIE.

11.4. COOKIES DE SESIÓN Y COOKIES


PERMANENTES
Cuando se utiliza la sintaxis mínima para generar una cookie, es decir, la sintaxis
en la que únicamente se indica el nombre y el valor, la cookie solo estará definida
durante la sesión; cuando el usuario cierre su navegador, desaparecerá. En estos
casos la cookie, mientras dura la sesión, estará almacenada en la memoria principal
del equipo cliente.

Si se desea que la cookie permanezca en el equipo del usuario cuando este cierre la
sesión, deberá indicarse en su construcción un parámetro adicional con un periodo
de expiración. En este caso la cookie quedará almacenada en un fichero de texto en
el equipo cliente hasta que expire el periodo establecido, momento en el que
automáticamente desaparecerá.

setcookie(nombre,valor,expiracion)

El parámetro de expiración de la cookie debe indicarse sumando a la función


time() el número de segundos que se desea que permanezca la cookie en el
equipo del usuario. A continuación pueden verse algunos ejemplos de cookies con
diferentes periodos de expiración:

— Cookie con un periodo de expiración de 60 segundos:


setcookie("Cookie1","Valor1",time() + 60);

291
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— Cookie con un periodo de expiración de 1 hora:


setcookie("Cookie2","Valor2",time() + 3600);

— Cookie con un periodo de expiración de 30 días:


setcookie("Cookie3","Valor3",time() + 30*24*3600);

Para borrar una cookie que tiene establecido un valor con periodo de expiración
antes de que dicho periodo finalice, debe utilizarse la sintáxis:

setcookie("NombreCookie", "", time());

Ejemplo 11.6:
En este ejemplo se utiliza una cookie para almacenar en el equipo cliente el
instante de tiempo correspondiente al último acceso a la página. El programa
comprobará si han transcurrido más de 7 días desde ese último acceso y en caso
afirmativo mostrará un mensaje avisando de ese hecho.

<?php
$ahora = time();
setcookie("ultima", $ahora, $ahora + 30*24*3600);
if(isset($ultima) and ($ahora - $ultima > 7*24*3600))
echo "Hace más de una semana que no nos
visitabas"
?>
<HTML>
<HEAD><TITLE>Página de inicio</TITLE></HEAD>
<BODY>
<H1>Bienvenido a nuestra página</H1>
....................................
....................................
....................................
</BODY>
</HTML>

En el script se utiliza la función time() para obtener el instante de tiempo actual,


ese valor se almacena temporalmente en una variable y se genera con ella la cookie
a la que se le da el nombre ultima. Esta cookie tendrá una validez de 30 días. Por
lo tanto, en caso de que transcurra ese plazo sin recibir una nueva visita del
usuario, la cookie se borrará automáticamente. Tras definir la cookie, en el
programa se pregunta si la variable $ultima se encuentra definida. Conviene
recordar que la generación de la cookie se produce con anterioridad a la lectura de
todas las cookies definidas, por tanto, cuando se leen esas cookies la variable
$ultima tomará el valor correspondiente a la anterior carga de la página.

292
COOKIES

Finalmente, en la estructura condicional se compara el valor de las variables


$ahora y $ultima que guardan los instantes de tiempo actual y del último
acceso, respectivamente. Si la diferencia entre ambas es mayor que 7 días
(7*24*3600 segundos) se mostrará el mensaje en la página.

Ejemplo 11.7:
En este nuevo programa se utilizará una cookie para generar un contador de
accesos individuales de cada usuario. El número de accesos acumulados por el
usuario será almacenado en una cookie de nombre nvis.

<?php
if(isset($nvis)) {
$nvis++;
setcookie("nvis", $nvis, time() + 30*24*3600);
} else {
setcookie("nvis", 1, time() + 30*24*3600);
$nvis=1;
}
?>
<HTML>
<HEAD><TITLE>Página de inicio</TITLE></HEAD>
<BODY>
<H1>Bienvenido a nuestra página</H1>
<?php
echo "Esta es tu visita nº $nvis";
?>
....................................
....................................
</BODY>
</HTML>

En este caso el script inicial pregunta en primer lugar si la variable $nvis se


encuentra definida, dicho de otra modo, si la cookie ya se definió en un acceso
previo. En caso afirmativo, se incrementa en una unidad el valor de esa variable y
se redefine la cookie para el siguiente acceso. En el caso de variable no definida, es
decir, primer acceso, se le asignará el valor 1 y se definirá la cookie. En ambos
casos, la cookie generada permanecerá en el equipo cliente 30 días. Finalmente,
obsérvese cómo en el cuerpo del documento HTML se encuentra un nuevo script
PHP que utiliza el valor de la variable $nvis para generar en todo momento un
mensaje indicando cuántas veces ha accedido el usuario a la página.

293
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

11.5. VISIBILIDAD DE LAS COOKIES EN EL


SITIO WEB
Por defecto, si una cookie ha sido generada desde una página del sitio web, su
valor podrá ser "visto" desde cualquier otra página del mismo directorio o
subdirectorios en el que reside la página inicial. Si se desea cambiar esta visibilidad
puede utilizarse un nuevo parámetro opcional en la definición de la cookie,
indicando la ruta concreta en el servidor a partir de la cual la cookie es visible.

A continuación se presentan dos ejemplos concretos:

— Cookie visible en todas las páginas alojadas en el servidor:


setcookie("miCookie","1",time()+60,"/");

— Cookie visible en las páginas alojadas a partir del directorio sub:


setcookie("miCookie","1",time()+60,"/sub/");

294
MANEJO DE
FICHEROS

12.1. MECANISMOS DE ALMACENAMIENTO


DE DATOS
El almacenamiento de información suele ser una de las necesidades básicas de
cualquier aplicación web. En muchas ocasiones esa información puede ser
almacenada en formato de texto, para lo cual se dispone de diferentes alternativas.
La primera es la estudiada en el capítulo anterior: las cookies. En este caso se opta
por descentralizar esa información, de manera que cada equipo cliente guarda en
ficheros de texto propios la información correspondiente.

En la mayoría de ocasiones el uso de las cookies no es suficiente. Puede ocurrir que


se desee tener siempre disponible la información de todos los clientes o que esa
información requiera tratamientos más complejos. En definitiva, lo que se trata es
de poder almacenar la información no en los clientes sino en el propio servidor.

Una primera alternativa es el uso de aplicaciones gestoras de bases de datos, tales


como MySQL. En estos casos se aprovecha las funcionalidades propias de esas
aplicaciones, se optimiza la gestión de los datos, la realización de búsquedas, la

295
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

generación de informes,... En los próximos capítulos se analizará cómo desde


cualquier programa PHP se puede establecer la conexión a una base de datos
MySQL y realizar todas estas operaciones.

Sin embargo, en ocasiones, el uso de simples ficheros de texto que se almacenen en


el servidor puede cubrir las necesidades de almacenamiento de datos de
aplicaciones web. Esto es precisamente lo que se estudiará en el presente capítulo.
Por supuesto, aunque las bases de datos ofrecen unas prestaciones mucho mayores,
en algunos casos el uso de ficheros puede tener algunas ventajas:

— Su uso resulta más sencillo.


— No es necesario el conocimiento de lenguajes de manipulación de datos.
— No requieren de la instalación de aplicaciones adicionales.
— No todos los proveedores de acceso y alojamiento de páginas web permiten
alojar páginas con acceso a bases de datos.

12.2. OPERACIONES DE MANIPULACIÓN DE


FICHEROS
El uso de ficheros de texto en los programas PHP implica la utilización de una
serie de operaciones básicas. La primera de esas operaciones es la apertura; una
vez abierto se realizarán las correspondientes operaciones de lectura/escritura, y
finalmente se procederá al cierre del fichero.

12.2.1. APERTURA Y CIERRE DE FICHEROS


Para abrir un fichero de texto desde un programa PHP se utiliza la función
fopen(). Como argumentos mínimos esta función recibe el nombre del fichero y
una cadena de caracteres que indicará el modo de apertura:

fopen(Nombrefichero, ModoApertura)

El nombre del fichero se indicará con la ruta relativa de acceso desde la página que
incorpora el script.

La función fopen() devuelve un número entero que actúa de identificador o


puntero al fichero y que se utilizará en todas las operaciones posteriores sobre él. Si
el número devuelto es 0 se entenderá que el proceso de apertura no ha podido
realizarse satisfactoriamente (fichero no existente, falta de permisos para la
apertura, daños en el fichero,...).

296
MANEJO DE FICHEROS

Respecto al modo de apertura del fichero, existen diferentes opciones dependiendo


de la cadena que se utilice como segundo argumento de la función. La Tabla 12.1
muestra esta opciones.

'r' Solo lectura. Puntero al inicio.


'r+' Lectura/escritura. Puntero al inicio.
'w' Solo escritura. Crea el fichero si no existe. Borra el contenido previo
del fichero.
'w+' Lectura/escritura. Crea el fichero si no existe Borra el contenido
previo.
'a' Solo escritura. Añade nuevos datos al final del fichero. Lo crea si no
existe.
'a+' Lectura/escritura. Añade nuevos datos al final del fichero. Lo crea si no
existe.
Tabla 12.1 Modos de apertura de un fichero

Ejemplo 12.1:
Si el fichero es abierto con la siguiente sentencia:

$f = fopen("Datos.txt", "r");

sobre el fichero Datos.txt solo se permitirán operaciones de lectura.

En cambio, una sentencia como la siguiente:

$f = fopen("Pruebas/comentarios.txt", "a");

abre el fichero comentarios.txt que se encuentra en el directorio Pruebas,


subdirectorio del directorio actual, para realizar sobre él solo operaciones de
escritura, creándole si no existe o añadiendo nuevos datos al final si ya existe.

Una vez abierto un fichero se realizarán sobre él las operaciones de lectura y/o
escritura y cuando ya no se utilice se debe proceder a cerrarlo. Para el cierre del
fichero existe una nueva función que recibe como argumento el identificador de
fichero que se genera en la operación de apertura. Esta función es:

fclose(idfichero)

De esta manera, la estructura básica de todo programa que trabaje con ficheros
sería:

297
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$f = fopen("mifichero.txt", "a");
..........................
..........................
fclose($f);

12.2.2. OPERACIONES DE LECTURA DE DATOS


PHP dispone de un catálogo bastante amplio de funciones de lectura y escritura de
datos. En estas próximas secciones se presentarán algunas de las más utilizadas,
comenzando en primer lugar por analizar las operaciones que permiten leer los
datos almacenados en ficheros.

La primera función que se puede utilizar para la lectura de un fichero de texto es la


función fgets() que permite efectuar una lectura línea a línea del contenido del
fichero.

fgets(idfichero)

El parámetro de la función debe ser el identificador de un fichero abierto


previamente con permiso de lectura. En cada llamada a la función una línea
completa es leída y el apuntador que señala la posición de lectura del fichero
avanza hasta la siguiente línea.

Para saber si el apuntador interno del fichero ha alcanzado el final se puede utilizar
la función booleana feof().

Ejemplo 12.2:
El siguiente programa realiza una lectura línea a línea del contenido de un fichero
de texto y lo escribe en la propia página web:

<?php
$f = fopen ("datos.txt","r");
while(!feof($f)){
$linea=fgets($f);
print $linea."<BR>";
}
fclose($f);
?>

Como puede comprobarse, la lectura se realiza mediante un bucle que finaliza


cuando el fin del fichero sea alcanzado.

298
MANEJO DE FICHEROS

La función fgets() puede recibir opcionalmente un segundo argumento que


indique un número máximo de caracteres a leer:

fgets(idfichero, n+1)

Con esta sintaxis la función leería, a partir del apuntador interno del fichero, n
caracteres o hasta alcanzar un fin de línea, lo que antes ocurra.

Para la lectura de un número de caracteres predeterminado PHP dispone también


de una nueva función:

fread(idfichero, n)

Esta función lee n caracteres del fichero o hasta alcanzar el fin del fichero (lo que
antes ocurra).

Si se desea saber el número de caracteres que contiene el fichero puede usarse la


función:

filesize(nombrefichero)

Ejemplo 12.3:
Si se desea transferir el contenido completo del fichero a una variable en un
programa PHP se podrían realizar las siguientes operaciones:

<?php
$fnom = "/ficheros/mifichero.txt";
$f = fopen($fnom, "r");
$contenido = fread($f, filesize($fnom));
fclose($fd);
?>

Para una lectura completa del contenido del fichero en una sola operación PHP
dispone también de la función file(). Una ventaja de esta función es que no
necesita realizar la apertura previa del fichero con fopen() ni el cierre con
fclose(). La función devuelve directamente una array de cadenas de caracteres
con cada una de las líneas del fichero.

299
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 12.4:
El siguiente programa utiliza la función file() para hacer una lectura completa
de un fichero en una sola operación, y posteriormente recorre el array resultante
para mostrar su contenido en la página:

<?php
$contenido = file('datos.txt');
foreach($contenido as $linea) {
print $linea;
print "<BR>";
}
?>

Finalmente, dentro de las funciones de lectura básicas puede citarse la función


fgetc() que permite una lectura carácter a carácter.

fgetc(idfichero)

Ejemplo 12.5:
El siguiente programa realiza una lectura completa del fichero y copia en la página
únicamente aquellos caracteres que ocupan posiciones pares dentro del fichero.

<?php
$f = fopen("mifichero.txt","r");
$nc = 0;
while(!feof($f)){
$c = fgetc($f);
$nc++;
if ($nc % 2 == 0)
print $c;
}
fclose($f);
?>

12.2.3. LECTURA CON FORMATO


Una de las funciones de lectura de ficheros más completa es la función
fscanf(), que permite leer datos de acuerdo a una especificación de formato. La
principal ventaja de esta función es el poder asignar valores a varias variables
simultáneamente en una única operación de lectura.

La función fscanf() tiene dos sintaxis diferentes:

300
MANEJO DE FICHEROS

fscanf(idfichero,formato)

fscanf(idfichero,formato,variables)

En la primera debe indicarse el identificador del fichero abierto para la lectura y


una cadena de caracteres indicando el patrón o formato de lectura. Los datos leídos
por la función serán devueltos por la función en un array.

En la segunda de las sintaxis posibles, además del identificador y la cadena de


formato se pueden indicar una lista de variables pasadas por referencia para que la
función almacene en ellas los datos leídos.

Las cadenas de formato de lectura incluyen una serie de codificaciones que señalan
el tipo de dato a leer. En concreto, los códigos de formato son los que se muestran
en la siguiente tabla:

%b Número entero en binario


%c Carácter
%d Número entero en base 10
%u Número entero sin signo
%f Número decimal
%o Número entero en octal (base 8)
%s Cadena de caracteres
%x o %X Número entero hexadecimal (base 16)
Tabla 12.2 Códigos de formato de lectura

Ejemplo 12.6:
Supóngase que Cinem@s dispone de un fichero de texto en el que guarda
información sobre sus clientes registrados; en concreto, el fichero contendrá el
nombre de cada cliente, su edad y el gasto total realizado en el último mes. El
contenido de este fichero podría ser:

Luis López Sánchez 18 76.4


Ana Antón Boo 21 50.2
Pedro Marcos Díez 24 82.5
Maria Martín Grau 33 12.7
Mónica Abad García 43 45.8
Jesús Bernal Cos 22 52.1

Como puede apreciarse este fichero está constituido por diferentes líneas en las que
se muestra para cada cliente su nombre, su edad y el gasto total separados por

301
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

tabulaciones. La lectura de los datos necesita conocer esta estructura para poder
leer en cada operación de lectura los tres datos de un cliente.

El programa PHP que realiza la lectura del fichero anterior y genera una lista
HTML a partir del contenido del mismo es:

<?php
$f = fopen("clientes.txt","r");
print "<UL>";
while ($datos = fscanf($f, "%s\t%d\t%f")) {
list($nombre, $edad, $gasto) = $datos;
print "<LI> $nombre de $edad años ha realizado " .
" un gasto total de $gasto euros. <BR>";
}
print "</UL>";
fclose($f);
?>

El programa anterior lo primero que realiza es la apertura del fichero con permiso de
lectura. A continuación genera la etiqueta HTML de inicio de lista y comienza el
bucle de lectura. En cada una de las iteraciones del bucle se realiza la llamada a la
función fscanf() para que lea, en este orden, una cadena de caracteres, un
tabulador, un número entero, otro tabulador y un número en coma flotante (cadena de
formato "%s\t%d\t%f"). Los tres valores leídos serán almacenados en el array de
nombre $datos. Cuando se alcance el final del fichero, y por tanto no existan más
datos a leer, la función fscanf() devolverá un valor booleano falso y por tanto el
bucle de lectura finalizará.

Dentro del cuerpo del bucle se utiliza la función list() para asignar valores a
tres variables ($nombre, $edad y $gasto) a partir de los tres valores que han
sido almacenados en el array $datos. Con esos tres valores de las variables se
genera el correspondiente ítem de la lista.

En concreto, el resultado del programa anterior sería una lista como la siguiente:

• Luis López Sánchez de 18 años ha realizado un gasto total de 76.4 euros.


• Ana Antón Boo de 21 años ha realizado un gasto total de 50.2 euros.
• Pedro Marcos Díez de 24 años ha realizado un gasto total de 82.5 euros.
• Maria Martín Grau de 33 años ha realizado un gasto total de 12.7 euros.
• Mónica Abad García de 43 años ha realizado un gasto total de 45.8 euros.
• Jesús Bernal Cos de 22 años ha realizado un gasto total de 52.1 euros.

302
MANEJO DE FICHEROS

La segunda de las sintaxis de la función fscanf() permitía indicar en su lista de


argumentos las variables en las que se desea que se almacenen directamente los
valores leídos. Estas variables deben ser pasadas por referencia, lo que significa
que deben ir precedidas del signo &.

Ejemplo 12.7:
Utilizando esta sintaxis alternativa, el programa del Ejemplo 12.6 podría escribirse
de la siguiente manera:

<?php
$f = fopen ("datos.txt","r");
print "<UL>";
while(!feof($f)){
$linea=fscanf($f,"%s\t%d\t%f",&$nombre,&$edad,&$gasto);
print "<LI> $nombre de $edad años ha realizado " .
" un gasto total de $gasto euros. <BR>";
}
print "</UL>";
fclose($f);
?>

12.2.4. OPERACIONES DE ESCRITURA DE DATOS


PHP dispone igualmente de funciones que permiten generar ficheros de texto o
escribir nuevos datos en ficheros ya existentes. Por supuesto, para poder utilizar
estas funciones es preciso que el fichero sea abierto con permiso de escritura, ya
que de otro modo se generaría un error.

La función que permite escribir cadenas de caracteres en un fichero de texto es


fwrite(), que admite dos sintaxis diferentes:

fwrite(idfichero, cadena)
fwrite(idfichero, cadena, numCaracteres)

En ambos caso se deben indicar en primer lugar el identificador del fichero de


destino y la cadena de caracteres a escribir. La segunda de las sintaxis recibe un
tercer parámetro que representa el número máximo de caracteres a escribir; en este
caso, si la cadena supera ese número será truncada. La función fwrite() dispone
de un alias o función sinónima que tiene exactamente la misma sintaxis y el mismo
uso, se trata de la función fputs().

303
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 12.8:
Programa que genera un fichero de texto con los 100 primeros números pares:

<?php
$f = fopen("NumerosPares.txt","a");
for($i=1;$i<100;$i++) {
fwrite($f,2*$i."\t");
}
fclose($f);
?>
Ejemplo 12.9:
Utilizando las funcionalidades de lectura y escritura de ficheros en PHP se podría
crear en una página un sencillo contador de accesos. Bastaría con generar un
fichero de texto cuyo contenido inicial sea el valor 0 e incluir el siguiente programa
en la página correspondiente:

<?php
$f = fopen("contador.txt","r+");
$c = fgets($f);
$c++;
rewind($f);
fwrite($f,$c);
fclose($f);
print "Número de visitas de esta página: $c";
?>

El programa anterior abre el fichero contador.txt con permisos de lectura y


escritura, lee su contenido, almacenándolo en la variable $c, incrementa el valor de
esa variable en una unidad, reinicia el puntero del fichero al inicio del mismo
(función rewind()) y escribe el nuevo valor sobre el fichero borrando el anterior.
Con el valor de la variable muestra además un mensaje en la página indicando el
número total de accesos.

Otra sencilla utilidad de los ficheros podría ser la creación de un registro de


comentarios realizados por los visitantes de una página. En lugar de guardar
todos los comentarios sobre una base de datos se podría optar por añadirlos a
un fichero de texto.

Para comenzar se debería diseñar un formulario HTML a través del cual el usuario
hará sus comentarios. El formulario puede estar formado por una simple área de
texto y un botón de envío.

304
MANEJO DE FICHEROS

El aspecto final del formulario podría ser el que se muestra en la Figura 12.1 y su
código:

<html>
<head><title>Comentarios</title></head>
<body>
Por favor, ayúdenos a mejorar. <br>
Cualquier comentario que quiera realizar sobre nuestra
empresa nos será de utilidad
<form action="observaciones.php">
<textarea name="ob" rows=4 cols=30 >
</textarea>
<input type="submit" value="Enviar comentario">
</form>
</body>
</html>

Figura 12.1 Formulario de envío de comentarios

Cuando el usuario pulse sobre el botón de envío, su comentario será transferido en


una variable $ob a la página observaciones.php donde se encontrará el programa
que se encarga de escribirlo en el fichero. Este programa se incluye a continuación:

<?php
$f=fopen("Comentarios.txt","a");
fputs($f,"-------------------\n");
$fecha = date("d/m/Y");
fputs($f,"Fecha: $fecha \n");

305
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

fputs($f,"Comentario: \n$ob \n");


fclose($f);
print "Cinem@s le agradece su comentario";
?>

El fichero de texto generado tendrá una estructura como la que sigue:

-------------------
Fecha: 12/10/2004
Comentario:
Deberían hacer un esfuerzo por mejorar la limpieza de los
aseos
-------------------
Fecha: 14/10/2004
Comentario:
La verdad es que todo ha estado perfecto. Enhorabuena!!!

12.2.5. OTRAS FUNCIONES DE MANIPULACIÓN DE


FICHEROS
Existen otras funciones de manipulación de ficheros que pueden resultar útiles. Por
ejemplo, si se desea realizar una copia de un fichero puede usarse la función
copy(), cuya sintaxis es:

copy(nombreOrigen, nombreDestino)

Los argumentos que recibe esta función son los nombres del fichero de origen y el
de destino. En el caso que estos se encuentren en un directorio diferente al del
documento base (el que contiene el programa PHP) deberán indicarse los nombres
de los ficheros con sus respectivas rutas relativas. Cuando el fichero destino ya
existe, la operación de copiado borrará el fichero existente.

La función copy() devolverá un valor booleano indicando si la operación se


realizó satisfactoriamente.

Ejemplo 12.10:
Para realizar una copia de seguridad de un fichero cuyo nombre se encuentre en la
variable $nfichero, se podría utilizar la sentencia:

if (copy($nfichero, $nfichero.'.bak')) {
print ("Copia de seguridad realizada correctamente");
} else {

306
MANEJO DE FICHEROS

print ("Fallo en la copia de seguridad");


}

Si en lugar de hacer una copia del fichero lo que se desea es simplemente


cambiarle el nombre, podría utilizarse la función rename():

rename(nombreAntiguo, nombreNuevo)

De nuevo, la función devuelve un valor booleano indicando la realización


satisfactoria o no de la operación.

La operación de eliminación de un fichero de texto se puede realizar igualmente


desde un programa PHP. Para ello se dispone de la función unlink():

unlink(nombreFichero)

Las operaciones de manipulación de ficheros provocan errores cuando se tratan de


aplicar sobre ficheros que no existen, por ello puede ser interesante asegurarse
antes de la existencia de los mismos utilizando la función booleana
file_exists():

file_exists(nombreFichero)

12.3. ENVÍO DE FICHEROS A TRAVÉS DE


FORMULARIOS HTML
Para finalizar este capítulo destinado a presentar las funciones básicas de
manipulación de ficheros en PHP, se hace en esta sección una presentación de los
mecanismos del lenguaje HTML para el envío de todo tipo de archivos a través de
formularios y cómo los archivos enviados por los usuarios pueden ser recogidos
por los programas PHP.

El diseño de un formulario que permita el envío de ficheros exige el incluir en el


mismo un campo de tipo file e incluir en el comando de definición del formulario el
parámetro ENCTYPE indicando al formulario que se transferirán datos en archivos.

Ejemplo 12.11:
El siguiente formulario incluye uno de estos campos al que se le ha dado el nombre
fichero:
<FORM ENCTYPE="multipart/form-data"

307
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ACTION="RecibirFichero.php" METHOD=POST>
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="10000">
Fichero: <INPUT NAME="fichero" TYPE="file">
<INPUT TYPE="submit" VALUE="Enviar">
</FORM>

Como puede apreciarse, además del campo de tipo file, el formulario incluye un
campo oculto que permite indicar el tamaño máximo de los ficheros que se
permitirá al usuario enviar (MAX_FILE_SIZE).

El aspecto del formulario anterior sería el siguiente:

Cuando el usuario envía el fichero a través del formulario, se reciben en el


programa de destino (RecibirFichero.php en este caso) una serie de variables que
permitirán guardar el fichero enviado en el servidor:

— $fichero fichero temporal generado en el servidor


— $fichero_name nombre original del fichero
— $fichero_size tamaño del fichero
— $fichero_type tipo de fichero

El nombre de estas variables viene determinado por el nombre del correspondiente


campo del formulario HTML. En el caso del formulario anterior este campo tenía
precisamente como nombre fichero.

Al recibir los datos del formulario se genera en el servidor un fichero temporal


($fichero) que si se desea conservar es preciso renombrar con la función
rename(). Este proceso se podría realizar con el siguiente script:

<?php
print "Fichero recibido";
rename($fichero,$fichero_name);
?>

308
BASES DE DATOS
RELACIONALES Y EL
LENGUAJE SQL

13.1. INTRODUCCIÓN
Las bases de datos constituyen hoy en día los elementos clave sobre los que se
apoyan los sistemas de información de empresas e instituciones. Una base de datos
podría definirse como una colección de datos interrelacionados que son
almacenados en un soporte informático. Algunas razones que justifican su uso son
su capacidad para almacenar grandes volúmenes de información, la optimización
de su gestión, la facilidad para realizar consultas y la exactitud, rapidez y fiabilidad
en su administración.

Aunque en ocasiones son términos que se confunden, a la hora de hablar de las


bases de datos debe distinguirse lo que es propiamente la información almacenada
(datos, restricciones y relaciones) y el conjunto de programas que actúan de
intermediarios entre la información y el usuario (SGBD: Sistema Gestor de Bases
de Datos). En este libro se mostrará uno de los sistemas gestores de bases de datos
más populares: MySQL.

309
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Por supuesto, en el desarrollo de aplicaciones web las bases de datos desempeñan


un papel esencial. Muchas de las páginas web a las que accedemos habitualmente
se generan como resultado de una consulta a una base de datos, poniendo de
manifiesto su carácter dinámico. El objetivo final que persigue este libro es generar
aplicaciones web dinámicas mediante el uso del lenguaje PHP, una parte
importante de ese dinamismo se conseguirá a través de la conectividad a bases de
datos. Es por ello que en estos tres próximos capítulos se presentan los
fundamentos de las bases de datos relacionales y el uso del sistema gestor MySQL,
al igual que la sintaxis básica del lenguaje de consulta SQL.

13.2. DISEÑO DE BASES DE DATOS

13.2.1. MODELO RELACIONAL


Para la generación de bases de datos se utiliza habitualmente el denominado
"modelo relacional". Este modelo se basa en representar los datos mediante tablas
con diferentes atributos a modo de columnas. La existencia de atributos comunes
en las tablas permite establecer relaciones entre ellas.

Ejemplo 13.1:
Un banco podría almacenar la información sobre sus clientes y los saldos en sus
cuentas bancarias mediante dos simples tablas:

Clientes Nombre DNI Nº cuenta Cuentas Nº cuenta Saldo


Luis López 73456123 1001 1001 12.523€
Ana Sánchez 56712765 1002 1002 5.650€
Antonio Briz 22871274 1002 1003 24.758€
Antonio Briz 22871274 1003 1004 2.651€
Sara Salas 12567234 1004

Cada una de las filas de las tablas se suele denominar tupla o registro, y a su vez
está formada por una serie de valores cuyo tipo coincide con el del correspondiente
atributo.

En este caso, el atributo común entre las dos tablas (Nº cuenta) es el que permite
relacionar los clientes con sus cuentas. Además, lo normal es que cada tabla tenga
un atributo o conjunto de atributos cuyo valor identifique de forma única a los
registros, este atributo es el que se denomina clave. En el caso de la tabla de

310
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

clientes, el atributo DNI es una clave, ya que es imposible que dos clientes distintos
tengan el mismo DNI.
En la definición de una base de datos relacional se debe indicar claramente la
estructura de cada tabla, con los nombres y tipos de cada uno de sus atributos, así
como las diferentes claves y otras restricciones sobre los mismos.

El ejemplo anterior ilustra una situación bastante simplificada que, por supuesto,
tiene algunos inconvenientes que podrían ser superados con una mejor elección de
tablas. Por ejemplo, con el diseño anterior, cuando un cliente tiene más de una
cuenta, tal como ocurre en este caso, se duplican sus datos. La utilización de una
tabla intermedia que sirva de enlace entre los DNI y los números de cuenta evitaría
este problema. En definitiva, el correcto diseño de una base de datos no es algo
trivial y requiere una cuidadosa planificación. A este respecto existe una teoría
bastante desarrollada sobre el diseño de bases de datos para evitar las redundancias
e inconsistencias: la teoría de la normalización. No es el objetivo de este libro
profundizar en aspectos de diseño de bases de datos, aquel lector que esté
interesado en estos temas puede acudir a la amplia bibliografía específica.

13.2.2. DIAGRAMAS ENTIDAD/RELACIÓN


Los diseños de bases de datos suelen apoyarse en diagramas a través de los cuales
se tratan de visualizar las diferentes entidades que intervienen, las relaciones entre
ellas y el tipo de estas relaciones. Estos gráficos son de ayuda para decidir las
distintas tablas que deben ser utilizadas en la base de datos.

Existe una amplia variedad de herramientas, pertenecientes a la categoría de las


denominadas herramientas CASE (Computer Added Software Engineering), que
permiten realizar estos gráficos y al mismo tiempo generar la base de datos
propiamente dicha. En la próxima sección se utilizará precisamente una de estas
herramientas para generar una base de datos que servirá para desarrollar en torno a
ella toda una aplicación web.

13.3. UN EJEMPLO ILUSTRATIVO: CINEM@S


Supóngase que la empresa Cinem@s, cuyo sitio web se comenzó a desarrollar en el
Capítulo 3, está interesada en desarrollar un sistema para la consulta de la cartelera y
compra de entradas a través de Internet. Parece evidente que en este caso necesitará
disponer de una base de datos con toda la información relativa a las diferentes
proyecciones de cada sala y generar a partir de ella las páginas web de su portal.
Haciendo uso de PHP y MySQL se podrá diseñar no solo un sistema de consulta de

311
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

cartelera actualizada, sino también un sistema de consulta de horarios, búsquedas de


películas, consulta de disponibilidades de salas, compra de entradas,...
En esta sección se presentará la estructura de la base de datos a crear, para en los
capítulos posteriores analizar la forma de administrar esa base de datos con
MySQL, y llegar a efectuar operaciones de actualización y consulta desde las
páginas del propio sitio web. Una vez presentada la estructura, se hará un rápido
repaso a las sentencias básicas del lenguaje de definición y manipulación de datos
SQL.

Para comenzar es preciso identificar las entidades que intervienen en el problema


planteado, en este caso, estas podrían ser:

1. Las películas.
2. Las salas disponibles.
3. Las proyecciones.
4. Las entradas.
5. Los clientes.

Cada una de las entidades se caracterizará por unos atributos, así cada película
tiene un título, un director, una lista de actores, un género, un año de realización,...
A cada atributo se le asignará un tipo de datos concreto, así por ejemplo, el título
de una película puede ser tratado como una cadena de un máximo de 50 caracteres,
o el año como un número entero.

Una vez establecidos los atributos de cada entidad, el siguiente paso es definir las
relaciones entre las tablas o entidades. La existencia de una relación se concretará
en la inclusión como atributo en una tabla de la clave de la tabla relacionada. La
Figura 13.1 ilustra el modelo concreto de la base de datos que desarrollará,
incluyendo las entidades con sus atributos y tipos respectivos, y sus relaciones.

La Figura 13.1 ha sido generada mediante la herramienta CASEstudio


(http://www.casestudio.com). Con esta herramienta Case se pueden
diseñar bases de datos y crear diagramas Entidad/Relación soportando
NOTA más de 20 diferentes tipos de gestores de bases de datos, por ejemplo
Oracle, MySQL, MSSQL, Interbase, SybaseASE y otros sistemas de
bases de datos. Además del diagrama entidad/relación, CASEstudio
permitirá generar de forma automática el código SQL que construye
toda la base de datos.

312
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Figura 13.1 Diagrama entidad/relación para la base de datos de Cinem@s

El tipo de relaciones que se aprecian en el diagrama entidad/relación corresponden


a lo que se suele denominar relaciones de uno a varios, por ejemplo, la relación
entre los clientes y las entradas establece que un cliente puede comprar todas las
entradas que desee, pero una entrada puede ser adquirida solo por un único cliente.

Los atributos que en cada tabla aparecen señalados con las siglas PK (Primary
Key) corresponden a las claves de cada una de ellas. En cambio, los señalados con
FK (Foreign Key) corresponden a atributos que son claves en otras tablas (claves
foráneas) y sirven para relacionar los registros de una tabla con los de la
subordinada.

Los atributos que tendrá cada una de las entidades consideradas son descritos en detalle
en la Tabla 13.1 (entidad Películas), Tabla 13.2 (entidad Proyecciones), Tabla 13.3
(entidad Salas), Tabla 13.4 (entidad Entradas) y Tabla 13.5 (entidad Clientes).

313
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ENTIDAD PELÍCULAS
Nombre de atributo Tipo de datos Descripción
IDPELICULA Valor numérico que actuará de
Número entero
identificador de cada película
TITULO Cadena de caracteres Título de la película
ACTORES Listado de actores de la película que se
Cadena de caracteres
presentarán separados por comas
PRODUCCION Productor, o productores, en su caso, de
Cadena de caracteres
la película
DIRECCION Cadena de caracteres Director o directores de la película
GUION Cadena de caracteres Guionista o guionistas de la película
ANNO Número entero Año de realización de la película
DURACION Número entero Duración de la película en minutos
NACIONALIDAD Cadena de caracteres Nacionalidad de la película
Género de la película elegido entre una
GENERO Cadena de caracteres serie de opciones predeterminadas:
drama, comedia, acción....
Opción que establece restricciones de
EDAD_RESTRICCION Cadena de caracteres edad para los espectadores: apta, mayores
de 7, mayores de 13, mayores de 18
SINOPSIS Cadena de caracteres Breve resumen de la película
CARTELERA Imagen del cartel promocional de la
Imagen
película
Tabla 13.1 Atributos de la entidad Películas

ENTIDAD PROYECCIONES
Nombre de atributo Tipo de datos Descripción
IDPROY Valor numérico que actuará de
Número entero
identificador de cada proyección
IDPELICULA Valor numérico que identifica la
Número entero
película que se proyectará
NUM_SALA Número de la sala en donde se
Número entero
proyectará la película
HORA Hora Hora de inicio de la proyección
FECHA Fecha Fecha de la proyección
Indica si la proyección tiene o no una
TARIFA_REDUCIDA Lógico(verdadero/falso) tarifa reducida, por ejemplo, sesiones
matinales, proyecciones especiales,...
ESTRENO Indica si la proyección es emitida como
Lógico(verdadero/falso)
estreno o no
Tabla 13.2 Atributos de la entidad Proyecciones

314
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

ENTIDAD SALAS
Nombre de atributo Tipo de datos Descripción
NUM_SALA Valor numérico identificativo de cada
Número entero
sala
AFORO Número entero Número total de asientos de la sala.
NUM_FILAS Número entero Número total de filas de la sala
Cadena de caracteres que permitirá
OBSERVACIONES Cadena de caracteres almacenar cualquier tipo de observación
sobre la sala
Tabla 13.3 Atributos de la entidad Salas
ENTIDAD ENTRADAS
Nombre de atributo Tipo de datos Descripción
NUM_ENTRADA Valor numérico que actuará de
Número entero
identificador de cada entrada
IDPROY Valor numérico que identifica la
Número entero
proyección correspondiente
FILA Número entero Número de fila de la entrada
NUM_ASIENTO Número entero Número de asiento de la entrada
NUM_CLIENTE Valor numérico que identifica al cliente
Número entero
que compra la entrada

RECOGIDA Indica si la entrada ha sido recogida o


Lógico(verdadero/falso)
no por el cliente

Tabla 13.4 Atributos de la entidad Entradas


ENTIDAD CLIENTES
Nombre de atributo Tipo de datos Descripción

NUM_CLIENTE Valor de tipo numérico que actuará de


Número entero
identificación del cliente.
NOMBRE Cadena de caracteres Nombre del cliente
DIRECCION Cadena de caracteres Dirección postal del cliente
FECHANAC Fecha Indica la fecha de nacimiento del cliente
TELEF Cadena de caracteres Teléfono del cliente.
EMAIL Cadena de caracteres Dirección de e-mail del cliente
Valor numérico que almacenará el
PUNTOS_ACUM número total de puntos que va
Número entero
acumulando el espectador por la compra
de entradas
Indica una clave secreta que el cliente
CLAVE Cadena de caracteres tendrá que utilizar para realizar cualquier
operación de compra de entradas
Tabla 13.5 Atributos de la entidad Clientes

315
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En las próximas secciones se verá la forma en la que la base de datos diseñada


puede ser implementada en un sistema gestor como MySQL, para ello será preciso
estudiar previamente, y de forma breve, las sentencias básicas del lenguaje SQL.

13.4. EL LENGUAJE SQL

13.4.1. INTRODUCCIÓN
SQL es un lenguaje de definición y manipulación de datos para bases de datos
relacionales. Es un lenguaje de definición porque permite definir la estructura de
las tablas que componen la base de datos, y de manipulación porque permite
efectuar consultas y realizar operaciones como inserción, borrado y actualización
de los datos que contiene.

El lenguaje SQL tiene sus orígenes en el lenguaje SEQUEL (Structured English


QUEry Language) desarrollado por IBM, un lenguaje para la especificación de las
características de las bases de datos que adoptaban el modelo relacional. En 1979
aparece el primer SGBD basado en SQL: ORACLE. Rápidamente comenzaron a
aparecer en el mercado múltiples productos de bases de datos basados en SQL:
SQL/DS, DB2, SYBASE, INTERBASE, INFORMIX y otros. El amplio desarrollo
del lenguaje hizo necesario un proceso de estandarización para conseguir que el
SQL soportado por los distintos sistemas tuviera una sintaxis común.

Las características destacables de este lenguaje son:


— Posee una firme base teórica.
— Gran capacidad expresiva.
— Flexibilidad.
— Sus sentencias permiten manejar conjuntos de registros.
— Tiene una estructura simple.
— Alta productividad en la codificación (con una sola sentencia pueden
efectuarse consultas complejas).
— SQL no es un lenguaje de programación (su código no necesita
compilarse).

SQL puede usarse de dos maneras:

316
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

— Interactivamente, escribiendo directamente las sentencias y obteniendo


automáticamente el resultado. Es decir, como lenguaje autocontenido.
— Como lenguaje embebido en un lenguaje de programación anfitrión (4GL,
Cobol, Fortran, C, Basic,...). De esta forma SQL se complementa con la
capacidad expresiva, lógica y de cálculo del lenguaje anfitrión. Este uso
está reservado para los usuarios programadores.

En este libro se utilizará el SQL embebido dentro de programas PHP y también se


hará un uso interactivo a través de la línea de comandos de MySQL.

13.4.2. SENTENCIAS DE DEFINICIÓN DE DATOS

Creación de la base de datos


Las sentencias SQL de definición de datos permiten crear la base de datos y los
diferentes objetos que la componen, como por ejemplo, tablas, vistas, índices, etc.
La sentencia utilizada para la creación de objetos es CREATE.

La creación de un objeto requiere la asignación de un nombre que lo identifique


una vez creado, cualquier referencia posterior a él hace uso de ese identificador.
Los identificadores en SQL deben estar formados por letras, dígitos o signos de
subrayado, pero siempre comenzando por una letra y, por supuesto, sin coincidir
con ninguna de las palabras reservadas del lenguaje.

El primer objeto a crear es la propia base de datos, para ello se utilizará el siguiente
comando:

CREATE DATABASE nombre_base_de_datos

Donde nombre_base_de_datos es el identificador escogido para referenciar


a la base de datos que se está creando.

Ejemplo 13.2:
Para crear la base de datos de la empresa Cinem@s que se utilizará a lo largo de los
próximos capítulos, la sentencia es la siguiente:

CREATE DATABASE CINEMAS;

317
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Todo objeto creado con la sentencia CREATE puede ser modificado con la
sentencia ALTER o destruido con la sentencia DROP, de manera que, si se quisiera
destruir la bases de datos anterior, la sentencia a utilizar sería:

DROP DATABASE CINEMAS;

El lenguaje SQL no distingue el uso de mayúsculas y minúsculas. En este


NOTA
libro se utilizará como convenio las mayúsculas para escribir todas las
sentencias SQL, de esta manera serán más fácilmente identificables.

Creación de tablas
Una vez creada la base de datos, el paso siguiente es la creación de la estructura de
cada una de sus tablas.

La sintaxis más simple de la sentencia de creación de tablas es la siguiente:

CREATE TABLE nombre_tabla (atrib1 dominio1,


atrib2 dominio2,
...............
...............
...............
atribN dominioN)

donde:

nombre_tabla es el identificador utilizado para referirse a la tabla.


atribX es el nombre de un atributo de la tabla.
dominioX es el dominio en el que puede tomar valores el atributo
correspondiente.

Respecto a los dominios de los atributos, SQL incorpora un conjunto de dominios


básicos, permitiendo definir atributos de tipo cadena de caracteres, de tipo
numérico, de fecha y hora,...

Además de indicar el dominio de cada atributo, a la hora de definir las tablas


pueden señalarse igualmente diferentes características de los mismos, como por
ejemplo si no se permitirán valores nulos para ese atributo, si el valor debe ser
único, valores por defecto,...

318
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Ejemplo 13.3:
El código SQL que crea la tabla de la base de datos Cinem@s correspondiente a la
entidad Clientes sería:

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL,
DIRECCION VARCHAR(50),
FECHANAC DATE,
TELEF CHAR(9),
EMAIL CHAR(30),
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0,
CLAVE CHAR(6) NOT NULL,
PRIMARY KEY (NUM_CLIENTE));

En el código anterior puede observarse cómo cada atributo tiene asociado un tipo
de dato; por ejemplo, el atributo NOMBRE será una cadena de un máximo de 40
caracteres (VARCHAR(40)), el atributo NUM_CLIENTE tendrá un valor numérico
de tipo entero en un rango pequeño (SMALLINT), o la fecha de nacimiento tendrá
un valor de tipo fecha (DATE). En el capítulo destinado al estudio del sistema
gestor MySQL se presentarán con detalle todos los tipos de datos admitidos.

En la definición de la tabla CLIENTES se observa igualmente cómo alguno de los


atributos tienen a continuación de su tipo las palabras NOT NULL; se trata de
palabras reservadas del lenguaje SQL que indican que el correspondiente atributo
no puede tomar valores nulos, es decir, todos los registros que sean incluidos en la
tabla deberán tener obligatoriamente un valor para ese atributo. Por ejemplo, en la
tabla CLIENTES, tal como está definida, los únicos atributos que obligatoriamente
deben tener un valor son: NUM_CLIENTE, NOMBRE, PUNTOS_ACUM y CLAVE,
de manera que a la hora de dar de alta un nuevo cliente no sería necesario dar su
dirección de correo electrónico o teléfono, por ejemplo.

Sobre el atributo NUM_CLIENTE de la tabla CLIENTES se deben hacer dos


observaciones adicionales. Por un lado, en la última línea de la definición de la
tabla se establece como clave de la tabla (PRIMARY KEY) precisamente ese
atributo; de esta manera el número de cliente identificará a cada cliente. Además de
eso, en la definición del atributo se ha utilizado la palabra AUTO_INCREMENT
para indicar que el valor de ese atributo en cada registro se generará de forma
automática de manera incremental.

Finalmente, la palabra DEFAULT se utiliza para dar valores por defecto a


determinado atributo, de manera que si al crear un registro no se da valor a ese

319
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

atributo este tomará el valor por defecto. Tal como se aprecia en la definición de la
tabla CLIENTES, el único atributo que tiene valor por defecto es PUNTOS_ACUM,
siendo este valor 0; esto provoca que cuando se produzca el alta de un nuevo
cliente, su saldo de puntos acumulados sea 0, a no ser que se dé otro valor.

La sentencia CREATE crea la estructura de la tabla pero no su contenido, es decir,


sus registros. Estos deberán ser añadidos posteriormente mediante la instrucción
INSERT. Esta sentencia INSERT podrá ser usada de forma interactiva o bien
dentro de un programa que se encargue de leer los datos a insertar, por ejemplo de
un fichero existente creado al efecto.

Ejemplo 13.4:
A continuación se incluye el código SQL completo de generación de todas las
tablas de la base de datos CINEMAS:

CREATE TABLE PELICULAS (


IDPELICULA SMALLINT NOT NULL AUTO_INCREMENT,
TITULO CHAR(50) NOT NULL,
ACTORES MEDIUMTEXT,
PRODUCCION MEDIUMTEXT,
DIRECCION MEDIUMTEXT,
GUION VARCHAR(40),
ANNO SMALLINT,
DURACION SMALLINT NOT NULL,
NACIONALIDAD VARCHAR(25),
GENERO ENUM('infantil','comedia','drama',
'acción','terror','erótica'),
EDAD_RESTRICCION ENUM('apta','mayores 7',
'mayores 13','mayores 18'),
SINOPSIS LONGTEXT,
CARTELERA BLOB,
PRIMARY KEY (IDPELICULA));

CREATE TABLE SALAS (


NUM_SALA SMALLINT NOT NULL,
AFORO SMALLINT NOT NULL,
NUM_FILAS SMALLINT NOT NULL,
OBSERVACIONES LONGTEXT,
PRIMARY KEY (NUM_SALA));

CREATE TABLE PROYECCIONES (


IDPROY SMALLINT NOT NULL AUTO_INCREMENT,
IDPELICULA SMALLINT NOT NULL,
NUM_SALA SMALLINT NOT NULL,

320
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

HORA TIME NOT NULL,


FECHA DATE NOT NULL,
TARIFA_REDUCIDA BOOL,
ESTRENO BOOL,
PRIMARY KEY (IDPROY));

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,
IDPROY SMALLINT NOT NULL ,
FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA));

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL,
DIRECCION VARCHAR(50),
FECHANAC DATE,
TELEF CHAR(9),
EMAIL CHAR(30),
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0,
CLAVE CHAR(6) NOT NULL,
PRIMARY KEY (NUM_CLIENTE));

Para mejorar la legibilidad, las sentencias SQL pueden partirse en


NOTA
tantas líneas como se desee y utilizar todos los espacios en blanco extra
que se quiera.

Modificación de tablas
Una vez creada una tabla, es posible su modificación utilizando la sentencia
ALTER.

Ejemplo 13.5:
A continuación se incluyen algunos ejemplos de usos de la sentencia ALTER para
modificar la tabla CLIENTES:

321
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

⎯ Cambio del nombre de la tabla CLIENTES:

ALTER TABLE CLIENTES RENAME TABLA_CLIENTES;

⎯ Cambio del nombre de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES CHANGE FECHANAC FNACIMIENTO DATE;

⎯ Cambio del tipo de dato de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES CHANGE CLAVE CLAVE VARCHAR(10);

⎯ Añadir un nuevo atributo a la tabla CLIENTES:

ALTER TABLE CLIENTES ADD E_CIVIL ENUM('soltero','casado',


'otros');

⎯ Eliminación de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES DROP E_CIVIL;

Creación de índices
Otro de los aspectos a considerar a la hora de construir las tablas de la base de
datos es la posibilidad de definir índices. Un índice es un archivo estructurado que
facilita el acceso a los datos en las operaciones de búsqueda. Los índices se deben
crear sobre aquellos atributos que suelen ser utilizados con frecuencia en las
búsquedas. Normalmente los sistemas gestores crean automáticamente un índice
sobre los atributos declarados como claves, y el programador puede optar por
añadir nuevos índices, pero siempre con precaución de no abusar de su uso, ya que
si se tienen demasiados índices la gestión de los datos se hace más costosa.

Los índices son creados, como cualquier elemento, con la sentencia CREATE,
aunque con una sintaxis diferente.

Ejemplo 13.6:
A continuación se incluyen dos ejemplos de creación de índices, uno sobre el
atributo FECHA de la tabla PROYECCIONES y otro sobre el atributo TITULO de
la tabla PELICULAS:

322
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

CREATE INDEX FECHA_IDX ON PROYECCIONES(FECHA);


CREATE INDEX TITULO_IDX ON PELICULAS(TITULO);

También es posible utilizar la sentencia ALTER para añadir un índice a una tabla
creada previamente; por ejemplo:

ALTER TABLE CLIENTES ADD INDEX (NOMBRE);

Claves ajenas: relaciones entre tablas


En la definición de tablas se pueden definir claves ajenas (FOREIGN KEY), es
decir, atributos que son claves primarias de otras tablas, de esta manera ambas
tablas quedan relacionadas. La forma de hacerlo es incluir en la definición de la
tabla una instrucción con la siguiente sintaxis:

FOREIGN KEY (atributo) REFERENCES Tabla_enlazada


(atributo)

Ejemplo 13.7:
En la tabla de PROYECCIONES se incluyó un atributo (IDPELICULA) que hacía
referencia a otro atributo, en este caso del mismo nombre, de la tabla PELICULAS.
En principio, si no se definen claves ajenas podría darse la situación de existir una
proyección con un código de película inexistente en la tabla de películas, con la
correspondiente inconsistencia. La forma de evitar este problema es definir
precisamente en la tabla de proyecciones el correspondiente atributo como una
clave ajena que referencia a la tabla de películas. Como la tabla ya ha sido creada,
esta modificación se puede realizar mediante la sentencia ALTER:

ALTER TABLE PROYECCIONES ADD FOREIGN KEY (IDPELICULA)


REFERENCES PELICULAS (IDPELICULA);

Otra posibilidad es definir las claves ajenas de cada tabla de la misma manera en la
que se definen las claves primarias en la propia definición de la tabla.

Ejemplo 13.8:
La tabla de ENTRADAS podría haber sido definida incluyendo dos claves ajenas,
una referenciando a las proyecciones y otra a los clientes:

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,

323
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

IDPROY SMALLINT NOT NULL ,


FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA),
FOREIGN KEY (IDPROY) REFERENCES PROYECCIONES (IDPROY),
FOREIGN KEY (NUM_CLIENTE) REFERENCES CLIENTES
(NUM_CLIENTE) );

Cuando se produce una operación de modificación o borrado de los datos de una


tabla que se encuentra relacionada con otra, puede ser necesario que se produzca
una actualización en cascada de la tabla relacionada.

Ejemplo 13.9:
Si una película es dada de baja en la tabla PELICULAS, entonces se deberían
eliminar de la tabla de PROYECCIONES todos aquellos registros que hacían
referencia a esa película. La forma en la que se indica esta necesidad de borrado en
cascada es:

ALTER TABLE PROYECCIONES ADD FOREIGN KEY (IDPELICULA)


REFERENCES PELICULAS (IDPELICULA)
ON DELETE CASCADE ON UPDATE CASCADE;

En otros casos puede ser interesante que no se borren los registros relacionados y
que simplemente a los campos que han quedado con un valor no existente les sean
asignados el valor NULL, o incluso, que se queden con el valor inicial a pesar de su
inconsistencia. Para hacer esto, en la sentencia anterior debería cambiarse la
palabra CASCADE por SET NULL, en el primer caso, o NO ACTION, en el
segundo.

La forma en la que se trabaja con claves ajenas en MySQL es un tanto


NOTA
especial, por lo que se analizará con más detalle cuando se estudie la
integridad referencial en el capítulo dedicado al sistema gestor MySQL.

13.4.3. LA SENTENCIA INSERT


Una vez creadas la base de datos y sus tablas, el siguiente paso es añadir los datos,
ya que toda tabla generada con CREATE estará vacía.

324
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

La sentencia INSERT permite añadir una o varias filas (registros) a una tabla. En
la práctica, para insertar datos en una base de datos se utilizan programas de
entrada orientados a formularios o rutinas que importan los datos desde ficheros o
documentos, realizando procesos iterativos de lectura de datos. Uno de los
objetivos finales que persigue este libro es poder realizar esas operaciones de
inserción desde una página web, para ello será preciso utilizar las sentencias SQL
en programas PHP que a su vez estarán integrados en documentos HTML.

La sintaxis básica de la sentencia INSERT es la siguiente:

INSERT INTO nombre_tabla VALUES (lista_de_valores)

Con esta sintaxis, deben ser introducidos tantos valores como atributos de la tabla;
además, los valores deben darse en el mismo orden en el que se encuentren
definidos los respectivos atributos. Por supuesto, los valores introducidos deben
coincidir con el tipo del correspondiente atributo.

SQL admite un valor especial, el valor NULL, que indica que el correspondiente
atributo está vacío en el registro insertado. Únicamente pueden utilizarse estos
valores nulos sobre atributos que no tengan en su declaración la cláusula NOT
NULL.

Debe aclararse también que las filas de una tabla no están ordenadas, por lo que no
es posible insertar una fila "al comienzo" o "al final" o "entre dos filas" de la tabla.

Ejemplo 13.10:
A continuación se muestran dos ejemplos de inserción de registros en la tabla
SALAS y en la tabla CLIENTES:

INSERT INTO SALAS


VALUES (1, 300, 15, 'Zona para minusválidos');

Esta sentencia insertaría una nueva sala, cuyo número correspondería al 1, con
capacidad para 300 personas, distribuidas en 15 filas y se incluiría en el campo de
observaciones el hecho de tener una zona reservada para minusválidos.

INSERT INTO CLIENTES


VALUES (147, 'Luis Medina Ríos',
'Los Laureles, 129 – 39005 Santander',
'1965-2-21', '942323135',
'medinal@mimail.com', 0, 'lmr65b');

325
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Esta sentencia inserta un nuevo cliente con número de identificación 147, de


nombre "Luis Medina Ríos", con la dirección indicada, nacido el 21 de febrero de
1965, siendo su teléfono 942323135, su dirección de correo electrónico
medinal@mimail.com, con un saldo de puntos inicial de 0 y con clave de
operaciones 'lmr65b'.

En SQL las cadenas de caracteres deben darse entre comillas simples.


Las fechas y horas también son dadas entre comillas y en principio se
NOTA pueden utilizar diferentes formatos. Al analizar el sistema MySQL se
indicarán estos formatos.

En la última inserción realizada en la tabla CLIENTES se puede observar cómo, a


pesar de que el atributo NUM_CLIENTE había sido definido como autoincremental
y el atributo PUNTOS_ACUM tenía un valor por defecto de 0, al insertar el registro
se asignaron también valores para esos dos atributos.

Surge, a la vista de esta situación, la necesidad de disponer de una sintaxis


adicional de la sentencia INSERT que permita insertar valores solo para
determinados atributos. En este caso, a la hora de insertar el registro se deberán
indicar los nombres de los atributos, sin ser necesario que el orden de los valores a
incluir y el de los atributos en la tabla coincidan. La sintaxis de esta variante es:

INSERT INTO nombre_tabla (lista_atributos)


VALUES (lista_valores)

Ejemplo 13.11:
Se podría insertar un nuevo cliente en la tabla con la sentencia:

INSERT INTO CLIENTES (NOMBRE, FECHANAC, EMAIL, CLAVE)


VALUES ('Andrea Fuentes Dávila', '1970-3-31',
'afd@tumail.com', 'and349');

Como puede observarse, en este caso no se dan valores para todos los atributos de
la tabla. En concreto, el atributo NUM_CLIENTE al no tener valor y haber sido
declarado como autoincremental, tomará automáticamente como valor el número
siguiente al valor más alto que se encuentre almacenado en la columna
NUM_CLIENTE de la tabla hasta ese momento. El atributo PUNTOS_ACUM, al no
habérsele dado ningún valor y tener definido uno por defecto, tomará
automáticamente este último (0 en este caso). Al resto de atributos a los que no se

326
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

les ha dado valor (DIRECCION y TELEFONO) se les asignará automáticamente el


valor especial NULL, siempre y cuando el correspondiente atributo admita ese
valor.

Ejemplo 13.12:
Se incluye a continuación una sentencia que permitiría dar de alta una nueva sala:

INSERT INTO SALAS (AFORO, NUM_FILAS, NUM_SALA)


VALUES (400, 20, 3);

Como se aprecia, no se dan valores a todos los atributos (faltaría el atributo


OBSERVACIONES) y además el orden en el que se dan los valores no coincide con
el orden de los atributos en la tabla.

Otra de las posibilidades de inserción de datos es la utilización de la conocida


como "sentencia de inserción multifila". Esta sentencia permite añadir múltiples
filas a una tabla en una sola sentencia. En este caso los valores para las nuevas filas
no son especificados explícitamente, sino que se utiliza una consulta (sentencia
SELECT) para obtener esos valores. Su sintaxis es:

INSERT INTO nombre_tabla (lista_atributos)


Consulta_SELECT

La sentencia INSERT multifila proporciona un modo eficiente y compacto de


copiar datos.

Ejemplo 13.13:
Si se dispone de una tabla adicional PELICULAS_TERROR para guardar en ella
todas las películas del género de terror con una estructura totalmente similar a la de
la tabla PELICULAS, estas podrían insertarse con una sentencia como la que
sigue:

INSERT INTO PELICULAS_TERROR


SELECT * FROM PELICULAS WHERE GENERO = 'terror';

En este caso, el uso del signo "*" es una forma de indicar todos los atributos de la
tabla.

327
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

13.4.4. LA SENTENCIA DELETE


Por supuesto, todo registro almacenado en una tabla puede ser eliminado en
cualquier momento. La sentencia que permite eliminar una o varias filas de una
tabla es DELETE, cuya sintaxis es:

DELETE FROM nombre_tabla WHERE condición

Esta sentencia elimina de la tabla indicada todas las filas que cumplan la condición
señalada. Si se suprime la cláusula WHERE, se borrarán todas las filas de la tabla,
pero no la tabla; recuérdese que la instrucción que destruye completamente la tabla
(datos y estructura) es DROP TABLE.

Las filas no pueden borrarse parcialmente, es decir, no pueden suprimirse valores


concretos de una fila.

Ejemplo 13.14:
Las sentencias de eliminación de registros serían:

⎯ Eliminación del cliente número 1456:

DELETE FROM CLIENTES WHERE NUM_CLIENTE = 1456;

⎯ Eliminación de las entradas de las primeras 5 filas para la proyección número 231:

DELETE FROM ENTRADAS WHERE FILA <= 5 AND IDPROY = 231;

Las sentencias DELETE con condiciones simples permiten seleccionar las filas a
suprimir basándose únicamente en los propios contenidos de las filas. Sin embargo,
también es posible efectuar la selección de las filas a suprimir en base a los datos
contenidos en otras tablas.

Ejemplo 13.15:
Si se desea eliminar todas las proyecciones de la película Refugio en el paraíso, se
podría utilizar la sentencia:

DELETE FROM PROYECCIONES WHERE


IDPELICULA = (SELECT IDPELICULA FROM PELICULAS WHERE
TITULO = 'Refugio en el paraíso');

328
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

13.4.5. LA SENTENCIA UPDATE


La sentencia UPDATE permite modificar los valores de los atributos de uno o
varios registros almacenados en la tabla. La sintaxis de la sentencia es:

UPDATE nombre_tabla SET lista_asignaciones WHERE condición

La parte final de la sentencia, la cláusula WHERE es opcional; en caso de no


indicarse, la actualización afectaría a todos los registros de la tabla.

En una misma sentencia se pueden actualizar los valores de varios atributos, indicando las
asignaciones separadas por comas.

Ejemplo 13.16:
Sentencias de actualización de registros serían:

⎯ Reducción del aforo de todas las salas en un 10%:

UPDATE SALAS SET AFORO = AFORO * 0.9;

⎯ Otorgar 100 puntos extra a todos los clientes que tengan un saldo de puntos
acumulados menor que 500:

UPDATE CLIENTES SET PUNTOS_ACUM = PUNTOS_ACUM + 100


WHERE PUNTOS_ACUM < 500;

⎯ Modificar el aforo y el número de filas de la sala número 7:

UPDATE SALAS SET AFORO = 500, FILAS = 25


WHERE NUM_SALA = 7;

Al igual que ocurría con la sentencia DELETE, también es posible efectuar la


selección de las filas a actualizar en base a los datos contenidos en otras tablas.

Ejemplo 13.17:
Se desea establecer tarifa reducida para todas las proyecciones de películas rodadas
antes de 1990, la sintaxis de la sentencia sería:

UPDATE PROYECCIONES SET TARIFA_REDUCIDA = 1


WHERE IDPELICULA =

329
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

(SELECT IDPELICULA FROM PELICULAS WHERE ANNO <


1990);

El tipo booleano o lógico no es uno de los tipos estándar de SQL; en el


caso de MySQL, se dispone del tipo BOOL que realmente es un sinónimo
del tipo TINYINT(1) que permite almacenar un número entero de 1 bit (0
NOTA ó 1). El valor 1 puede identificarse con el valor lógico "verdadero" y el
valor 0 con "falso".

13.4.6. LA SENTENCIA SELECT


Las consultas son la base del SQL, mediante ellas se extrae información de las
diferentes tablas de la base de datos, mostrándola en una estructura tabular.

Toda consulta en SQL se realiza con la sentencia SELECT. Esta es sin duda la
sentencia más poderosa y completa con la que cuenta el lenguaje SQL. Su sintaxis
completa es:

SELECT [Cuantificador_de_conjunto] items


FROM Nombre_de_tabla
[WHERE Condición_de_búsqueda]
[GROUP BY Columna_de_agrupación]
[HAVING Condición_de_búsqueda]
[ORDER BY Especificación_de_ordenación]

Todos los fragmentos que en esta sintaxis aparecen encerrados entre corchetes son
opcionales.

La sentencia SELECT consta de varias partes diferentes:

— Cláusula SELECT: en ella se indican los datos a recuperar en la consulta.


Los items indicados deben ir separados por comas y pueden ser:
o Un nombre de columna (atributo) de una tabla.
o Un asterisco (*), que es equivalente a especificar los nombres de
todas las columnas de la tabla.
o Una constante, indicando que el mismo valor constante va a
aparecer en todas las filas de los resultados de la consulta.
o Una expresión SQL, cuyo valor será calculado a partir de los
valores de los atributos.

— El cuantificador de conjunto es opcional, puede ser:

330
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

o ALL (opción por defecto): indica que en el resultado de la consulta


deben mostrarse todas las filas, incluyendo las repetidas.
o DISTINCT: indica que en el resultado de la consulta no deben
mostrarse las filas repetidas.

— Cláusula FROM: en ella se indican, separadas por comas, las tablas que
contienen los datos que se desean recuperar en la consulta.

— Cláusula WHERE: permite indicar una condición de búsqueda.

— Cláusula GROUP BY: permite obtener consultas resumen en las que todas
las filas similares son agrupadas y se genera una fila resumen para cada
grupo.

— Cláusula HAVING: permite indicar condiciones o filtros a verificar por los


diferentes grupos producidos por la cláusula GROUP BY.

— Cláusula ORDER BY: señala el modo de ordenación de los resultados de


la consulta. Si se omite, los resultados no aparecen ordenados.

Proyecciones de una tabla


Las únicas cláusulas obligatorias son SELECT y FROM. Con esta sintaxis mínima
se pueden generar las consultas más sencillas en SQL, las proyecciones de una
tabla, es decir, aquellas que solicitan columnas de datos de una única tabla en la
base de datos.

La sintaxis mínima es:

SELECT lista_columnas FROM nombre_de_tabla

Ejemplo 13.18:
Si se quisiera recuperar todos los registros de la tabla PELICULAS, se debería
utilizar la sentencia:

SELECT * FROM PELICULAS;

En cambio, si lo único que interesa es obtener un listado con los títulos y


nacionalidades de las películas, la sentencia a utilizar sería:

SELECT TITULO, NACIONALIDAD FROM PELICULAS;

331
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Una consulta SQL puede incluir columnas calculadas cuyos valores se obtienen a
partir de los valores de los datos almacenados.

Ejemplo 13.19:
Se desea listar las salas disminuyendo el aforo en un 10%, la sentencia para ello sería:

SELECT NUM_SALA, AFORO * 0.9 FROM SALAS;

En estas consultas con campos calculados pueden utilizarse diferentes funciones de


SQL además de las propias de cada gestor de bases de datos. Por ejemplo, existen
funciones para tratamiento de fechas y horas, para tratamiento de cadenas de
caracteres,...

Eliminación de duplicados
Si una consulta incluye la clave primaria de una tabla en su lista de selección,
entonces cada fila de resultados será única; en cambio, si no se incluye la clave en
la lista de selección pueden aparecer filas duplicadas en el resultado. Se pueden
eliminar las filas duplicadas en la consulta insertando la palabra clave DISTINCT
en la sentencia SELECT justo antes de la lista de selección.

Ejemplo 13.20:
Al seleccionar todos los directores de las películas de la tabla PELICULAS pueden
aparecer algunos de ellos duplicados (los que han dirigido varias películas), por
tanto habría dos opciones para esta consulta:

⎯ Listar todos los directores de películas aunque se produzca duplicidad de


información:

SELECT DIRECTOR FROM PELICULAS;

⎯ Listar todos los directores de películas, sin duplicidad:

SELECT DISTINCT DIRECTOR FROM PELICULAS;

Consultas con condiciones de selección


Para especificar condiciones de selección en las consultas se utiliza la cláusula
WHERE. En este caso el resultado de la consulta estará formado por todas las filas
que cumplan la condición de búsqueda especificada.

332
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Ejemplo 13.21:
Algunas consultas con condiciones de selección serían:

⎯ Obtener los títulos de todas las películas de una duración inferior a 120
minutos:

SELECT TITULO FROM PELICULAS WHERE DURACION < 120;

⎯ Obtener un listado con las direcciones de correo electrónico de todos los


clientes que tengan 1.000 puntos acumulados:

SELECT EMAIL FROM CLIENTES WHERE PUNTOS_ACUM = 1000;

⎯ Seleccionar las entradas para la proyección de número de identificación 341 y


que correspondan a filas comprendidas entre la 10 y la 14:

SELECT * FROM ENTRADAS WHERE IDPROY = 341


AND FILA BETWEEN 10 AND 14;

⎯ Obtener los títulos de todas las películas de nacionalidad española, francesa o


italiana:

SELECT TITULO FROM PELICULAS WHERE


NACIONALIDAD IN ('española','francesa','italiana');

⎯ Generar un listado con los títulos y directores de todas las películas en las que
participe Antonio Banderas:

SELECT TITULO,DIRECCION FROM PELICULAS WHERE


ACTORES LIKE '%Banderas%';

Como se puede apreciar en estos ejemplos, el lenguaje SQL tiene una sintaxis muy
similar al lenguaje natural, y ofrece una gran capacidad expresiva para generar
consultas.

Ordenación de los resultados de una consulta


Para ordenar los resultados de una consulta se utiliza la cláusula ORDER BY
seguida de una lista de especificaciones de ordenación separadas por comas. La
primera especificación de ordenación es la principal y las otras serán utilizadas en
caso de igualdad de valor en la primera. Cada especificación de ordenación está
dada por el nombre de un atributo seguido de una de las palabras siguientes:

333
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ASC Indica orden ascendente.


DESC Indica orden descendente.

En caso de no indicar el tipo de orden, por defecto se entiende que es ascendente.

Ejemplo 13.22:
Se desea generar un listado de clientes en orden decreciente según el atributo de
puntos acumulados y en orden creciente según el nombre, la sentencia sería:

SELECT * FROM CLIENTES ORDER BY PUNTOS_ACUM DESC,NOMBRE


ASC;

Consultas multitabla
SQL permite también recuperar datos procedentes de diferentes tablas mediante
una única sentencia SELECT, esto es lo que se conoce como "composición".

Ejemplo 13.23:
A continuación se presentan algunos sencillos ejemplos de consultas multitabla:

⎯ Se desea saber todas las fechas en las que se proyecta la película El Señor de
los Anillos:

SELECT FECHA FROM PELICULAS,PROYECCIONES WHERE


TITULO = 'El Señor de los Anillos' AND
PELICULAS.IDPELICULA = PROYECCIONES.IDPELICULA;

En este caso, la consulta utiliza dos tablas y es preciso en la condición de


selección indicar la igualdad entre los dos atributos comunes a las dos tablas.

⎯ Se desea un listado con los nombres de todos los clientes que hayan adquirido
alguna entrada para ver la película El Señor de los Anillos:

SELECT NOMBRE FROM


PELICULAS,PROYECCIONES,ENTRADAS,CLIENTES
WHERE
TITULO = 'El Señor de los Anillos' AND
PELICULAS.IDPELICULA = PROYECCIONES.IDPELICULA
AND
PROYECCIONES.IDPROY = ENTRADAS.IDPROY AND
ENTRADAS.NUM_CLIENTE = CLIENTES.NUM_CLIENTE;

334
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Al intervenir en las consultas anteriores columnas o atributos con el


mismo nombre, aunque en tablas diferentes, es necesario utilizar los
nombres cualificados, es decir, precedidos de los nombres de las tablas
NOTA a las que pertenecen.

Aún cuando no exista conflicto de nombres, también es posible utilizar


los nombres cualificados y evitar ambigüedades.

Consultas resumen
SQL permite resumir los datos mediante un conjunto de funciones denominadas
funciones de columna. Algunas de ellas son:

SUM() Calcula la suma total de los valores de una columna.


AVG() Calcula el valor promedio de una columna.
MIN() Encuentra el valor más pequeño de una columna.
MAX() Encuentra el valor más grande de una columna.
COUNT() Cuenta el número de valores de una columna.

Ejemplo 13.24:
A continuación se muestran ejemplos de consultas resumen:

⎯ Cálculo de la duración media de todas las películas del género comedia:


SELECT AVG(DURACION) FROM PELICULAS
WHERE GENERO = 'comedia';

⎯ Obtención de la capacidad de aforo de la sala más grande:

SELECT MAX(AFORO) FROM SALAS;

⎯ Cálculo de la suma de los puntos acumulados por los clientes número 321, 543,
287 y 721:

SELECT SUM(PUNTOS_ACUM) FROM CLIENTES


WHERE NUM_CLIENTE IN (321,543,287,721);

⎯ Obtener el número total de películas de nacionalidad española:

SELECT COUNT(*) FROM PELICULAS


WHERE NACIONALIDAD = 'española';

335
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Consultas agrupadas
Las consultas agrupadas o resumen producen una única fila de resultados a modo
de "totales"; sin embargo, en ocasiones es interesante obtener resúmenes parciales
o agrupados por categorías. Esto se consigue con la cláusula GROUP BY.

Ejemplo 13.25:
Dos ejemplos de consultas agrupadas serían las siguientes:

⎯ Obtener para cada género de películas, la duración máxima:

SELECT MAX(DURACION) FROM PELICULAS GROUP BY GENERO;

⎯ Contar el número de entradas compradas por cada cliente:

SELECT NOMBRE, COUNT(NUM_ENTRADA) FROM CLIENTES,ENTRADAS


WHERE CLIENTES.NUM_CLIENTE = ENTRADAS.NUM_CLIENTE
GROUP BY NOMBRE;

Condiciones de búsqueda de grupos


De la misma manera que en las consultas agrupadas la cláusula WHERE puede ser
utilizada para rechazar filas individuales, la cláusula HAVING puede emplearse
para rechazar grupos de filas.

El formato de la cláusula HAVING es similar a la cláusula WHERE y permite indicar


una condición de búsqueda para grupos. A diferencia de lo que ocurría en la
cláusula WHERE, sí es posible utilizar funciones de columna en la condición de la
cláusula HAVING.

Ejemplo 13.26:
Se desea obtener el nombre de todos los clientes que hayan adquirido 20 o más
entradas; la forma de conseguirlo sería utilizando la sentencia:

SELECT NOMBRE, COUNT(NUM_ENTRADA) FROM CLIENTES,ENTRADAS


WHERE CLIENTES.NUM_CLIENTE = ENTRADAS.NUM_CLIENTE
GROUP BY NOMBRE
HAVING COUNT(NUM_ENTRADA) >= 20;

336
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

En principio la cláusula HAVING está pensada para su utilización conjunta con la


cláusula GROUP BY; sin embargo, también es posible utilizar HAVING sin GROUP
BY, en este caso SQL considera el conjunto entero de resultados como un único
grupo y le aplica la condición de selección de HAVING.

337
EL SISTEMA GESTOR
DE BASES DE DATOS
MYSQL

14.1. ¿QUÉ ES MySQL?


MySQL es un sistema de administración de bases de datos relacionales rápido,
sólido y flexible. Es ideal para crear bases de datos con acceso desde páginas web
dinámicas, para la creación de sistemas de transacciones on-line o para cualquier
otra solución profesional que implique almacenar datos, teniendo la posibilidad de
realizar múltiples y rápidas consultas.

MySQL ofrece varias ventajas respecto a otros sistemas gestores de bases de datos:
— Tiene licencia pública, permitiendo no solo la utilización del programa sino
también la consulta y modificación de su código fuente. Resulta por tanto fácil
de personalizar y adaptar a las necesidades concretas.
— El programa está desarrollado en C y C++, lo que facilita su integración en
otras aplicaciones desarrolladas igualmente en esos lenguajes.
— Puede ser descargado gratuitamente de Internet (http://www.mysql.com)
haciendo uso de su licencia GPL.

339
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— Para aquellos que deseen que sus desarrollos basados en MySQL no sean
"código abierto" existe también una licencia comercial.
— MySQL utiliza el lenguaje SQL (Structured Query Languaje – Lenguaje de
Consulta Estructurado) que es el lenguaje de consulta más usado y
estandarizado para acceder a bases de datos relacionales. Soporta la sintaxis
estándar del lenguaje SQL para la realización de consultas de manipulación,
creación y de selección de datos.
— Es un sistema cliente/servidor, permitiendo trabajar como servidor
multiusuario y de subprocesamiento múltiple, es decir, cada vez que se
establece una conexión con el servidor, el programa servidor crea un
subproceso para manejar la solicitud del cliente, controlando el acceso
simultáneo de un gran número de usuarios a los datos y asegurando el acceso
solo a usuarios autorizados.
— MySQL dispone de un sistema sencillo de ayuda en línea, y de un monitor que
permite realizar todas las operaciones desde la línea de comandos del sistema,
sin necesitar ningún tipo de interfaze de usuario gráfica. Esto facilita la
administración remota del sistema utilizando telnet.
— Es portable, es decir, puede ser llevado a cualquier plataforma informática.
MySQL está disponible en más de veinte plataformas diferentes incluyendo las
distribuciones más usadas de Linux, sistema operativo Mac X, UNIX y
Microsoft Windows.
— Es posible encontrar gran cantidad de software desarrollado sobre MySQL o
que soporte MySQL. En concreto, son de destacar diferentes aplicaciones open
source para la administración de las bases de datos a través de un servidor web.

Todas estas características han hecho de MySQL uno de los sistemas gestores de
bases de datos más utilizado en la actualidad, no solo por pequeñas empresas sino
también por algunas grandes corporaciones, como puedan ser: Yahoo! Finance,
Google, CISCO, MP3.com, Motorola, NASA, Silicon Graphics, Texas
Instruments,... A mediados de 2004 se estimaba que existían más de 5 millones de
instalaciones activas del programa.

14.2. UTILIZACIÓN DE MySQL

14.2.1. ARRANQUE DEL SERVIDOR MySQL


MySQL dispone de dos programas principales: el servidor o motor y el cliente o
monitor MySQL. El primero de ellos se encarga de estar a la espera de posibles

340
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

peticiones recibidas de los clientes; mientras que el segundo es el encargado de


actuar de interfaz con el usuario.
Para comenzar a utilizar el sistema MySQL lo primero que se debe hacer es
arrancar su programa servidor. Este programa se ejecutará en un segundo plano
como un proceso o servicio, no tiene una interfaz de usuario y su único propósito
es estar a la espera de que alguien se conecte a él y le envíe una solicitud.

La forma de arrancar el servidor MySQL es ejecutar el programa mysqld desde la


línea de comandos del sistema. Este programa puede encontrarse dentro del
subdirectorio bin del directorio mysql. En el caso de Windows, la sentencia de
arranque del servidor es:

C:\mysql\bin> mysqld

Para comprobar si el servidor se ha arrancado correctamente puede usarse el


comando mysqlshow. Si el motor se ha iniciado, este comando mostrará un
listado con las bases de datos disponibles en ese momento.

C:\mysql\bin> mysqlshow
+-------------+
| Databases |
+-------------+
| mysql |
| test |
+-------------+

Al instalar MySQL, se crean dos bases de datos: mysql y test. La primera


contendrá información necesaria para el sistema (usuarios registrados, privilegios,...) y
la base de datos test es una base de datos vacía disponible para hacer pruebas sobre
ella. El usuario podrá generar posteriormente cuantas bases de datos desee.

Si se desea detener el servidor de MySQL la sentencia a utilizar sería:

C:\mysql\bin> mysqladmin shutdown

Por supuesto, una vez detenido el servidor no se podrá realizar ninguna operación
sobre las bases de datos.

Si se desea que el servidor se arranque automáticamente, en Windows


2000/XP puede usarse el Panel de Control de Herramientas
NOTA
Administrativas, en concreto, el apartado de servicios.

341
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

14.2.2. INICIO DEL MONITOR DE MYSQL


El programa cliente de MySQL, también conocido como monitor de MySQL, es
una internaz que permite a un usuario conectarse al servidor MySQL para realizar
operaciones sobre las bases de datos. Este monitor funciona a través de la línea de
comandos del sistema y aunque este hecho parezca un tanto arcaico, facilita
notablemente la administración del sistema de forma remota, por ejemplo, a través
de conexiones telnet.

Para poder arrancar el monitor de MySQL es preciso disponer de un usuario


autorizado. En MySQL todo usuario queda identificado por un nombre de usuario,
una contraseña y un servidor desde el que se realiza la conexión. Conviene aclarar
este último extremo, ya que el establecimiento de la conexión al servidor de
MySQL puede realizarse desde el propio equipo en el que está instalado MySQL
(localhost) o desde un equipo remoto.

Al instalar MySQL se crean automáticamente cuatro cuentas de usuario:


— Dos cuentas de usuario de nombre root y contraseña vacía, con todo tipo de
privilegios sobre las bases de datos. Existen dos cuentas de usuario root
porque en una de ellas se autoriza el acceso desde el mismo equipo en el que
está instalado el servidor de MySQL (localhost) y en la otra el acceso se
permite desde cualquier otro servidor (%).
— Dos cuentas de usuario invitado con nombre de usuario y contraseña vacías. De
nuevo existen dos cuentas de invitado, una para las conexiones desde el
localhost y otra para las conexiones desde otros servidores (%). Estas cuentas
permiten a cualquier usuario establecer una conexión con el servidor MySQL.
En principio estos usuarios únicamente tendrían acceso a la base de datos
test o cualquier base de datos cuyo nombre comience por 'test_', pero no
podrán realizar operaciones de tipo administrativo sobre el sistema. Sin
embargo, debe advertirse que en la versión Windows de MySQL los usuarios
invitados que se conecten desde el propio servidor localhost tendrán plenos
privilegios sobre todas las bases de datos.

Por supuesto, para garantizar la seguridad y privacidad de las bases de datos una de
las primeras operaciones que debería hacerse es el establecimiento de contraseñas
para los usuarios, sobre todo para el usuario root, ya que al tener contraseña vacía
cualquier persona podría acceder con todos los privilegios. Igualmente, en el caso
de trabajar sobre Windows, se recomienda eliminar la cuenta de usuario invitado
con privilegios de superusuario.

342
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Más adelante se explicará la forma de realizar estos cambios, de momento se usará


una de las cuentas de usuario por defecto para entrar por primera vez en el monitor
de MySQL.

Para arrancar el monitor de MySQL debe escribirse en la línea de comandos del


sistema la instrucción:

C:\mysql\bin> mysql –p

si se desea acceder con la cuenta de usuario invitado, o la instrucción:

C:\mysql\bin> mysql –u root –p

si se desea acceder con la cuenta de usuario root. En cualquiera de los dos casos,
el sistema solicitaría la introducción del password, que cómo se ha comentado,
inicialmente es vacío.

Enter password:

Tras introducir ese password vacío se entraría en el monitor de MySQL,


apareciendo un mensaje de bienvenida como el siguiente:

Welcome to the MySQL monitor. Commands end with ; or \g.


Your MySQL connection id is 12 to server version:4.0.18-nt

Type 'help;' or '\h' for help. Type 'c\' to clear the


buffer.

Mysql>

La Figura 14.1 ilustra el proceso de arranque del servidor de MySQL,


comprobación de la correcta ejecución del mismo e inicio del monitor de MySQL
con el usuario root de contraseña vacía.

En general, la sintaxis para acceder al monitor con un usuario registrado es:

C:\mysql\bin> mysql –h nombreservidor –u nombreusuario –p

Opcionalmente se puede incluso añadir al final de la sentencia el nombre de la base


de datos con la que se desea trabajar. El modificador –h se utiliza para especificar
el equipo donde se encuentra el servidor MySQL, si es que es diferente del equipo
desde el que se establece la conexión, -u permite indicar el nombre del usuario y –
p hace que se solicite a continuación el password.

343
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 14.1 Arranque del servidor de MySQL desde la línea de comandos del sistema

14.3. EJECUCIÓN DE SENTENCIAS SQL


Una vez dentro del monitor de MySQL el símbolo o prompt del sistema cambia,
pasando a ser:

mysql>

A través de la línea de comandos del monitor de MySQL se podrán escribir


directamente sentencias en el lenguaje SQL que serán dirigidas al servidor.

Cuando se desee salir del monitor de MySQL y regresar a la línea de comandos del
sistema, se tendría que ejecutar la sentencia:

mysql> EXIT
o
mysql> QUIT

Dentro del monitor todas las sentencias SQL que se ejecuten deberán
finalizar con un signo de punto y coma, las sentencias pueden ocupar
varias líneas y el uso de letras mayúsculas o minúsculas es indiferente.
NOTA

Una vez dentro del monitor de MySQL, se pueden ejecutar directamente sentencias
SQL de manera interactiva.

344
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Ejemplo 14.1:
Como primera orden se podría solicitar un listado de las bases de datos disponibles:

mysql> show databases;


+----------+
| Database |
+----------+
| mysql |
| test |
+----------+
2 rows in set (0.01 sec)

Ejemplo 14.2:
También se podría ejecutar una sencilla consulta de selección para solicitar al
servidor que muestre la fecha actual y la versión de MySQL que se encuentra
instalada:

mysql> SELECT CURRENT_DATE, VERSION();


+--------------+-----------+
| CURRENT_DATE | VERSION() |
+--------------+-----------+
| 2004-03-25 | 4.0.18-nt |
+--------------+-----------+
1 row in set (0.61 sec)

Ejemplo 14.3:
Es posible realizar sencillas operaciones matemáticas:

mysql> SELECT COS(EXP(2/3)), (3+5)*4;


+---------------+---------+
| COS(EXP(2/3)) | (3+5)*4 |
+---------------+---------+
| -0.368075 | 32 |
+---------------+---------+
1 row in set (0.11 sec)

Ejemplo 14.4:
También se puede solicitar que se muestre el usuario y la base de datos actual:

mysql> SELECT USER(),DATABASE();


+----------------+------------+
| USER() | DATABASE() |
+----------------+------------+
| root@localhost | |
+----------------+------------+
1 row in set (0.00 sec)

345
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Como se aprecia en esta última consulta, los usuarios quedan identificados por un
nombre formado por el nombre de usuario y la identificación del servidor desde el
que se conectan separados por el signo '@'. En el caso de que el servidor desde el
que se conecta sea el mismo que el servidor en el que se encuentra instalado
MySQL, esta identificación se limita al nombre localhost.

También se aprecia en la consulta anterior que la base de datos actual aparece


vacía. MySQL puede tener muchas bases de datos, pero para poder utilizar una de
ellas debe ser seleccionada previamente. La sentencia para realizar esta operación
es USE.

Ejemplo 14.5:
Si se desea usar la base de datos mysql (una de las dos bases de datos creadas por
defecto), la sentencia sería:

mysql> USE MYSQL;


Database changed

Una vez seleccionada la base de datos con la que se desea trabajar, todas las
operaciones posteriores irán dirigidas a ella, a no ser que explícitamente se seleccione
una nueva base de datos. Si se realiza de nuevo la selección de la base de datos actual
se podría apreciar cómo ahora sí que aparece el nombre de la correspondiente base de
datos

mysql> SELECT DATABASE();


+------------+
| DATABASE() |
+------------+
| mysql |
+------------+
1 row in set (0.00 sec)

14.4. GESTIÓN DE USUARIOS

14.4.1. LA TABLA USER

La base de datos mysql consta de 6 tablas. Entre ellas destaca la tabla user, en
la que se incluyen todos los usuarios registrados por el sistema. Esta tabla contiene
no solo la información sobre los nombres, contraseñas y servidores de los usuarios,

346
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

sino también un gran número de campos para establecer los diferentes privilegios
de cada usuario; por ejemplo, si los usuarios pueden crear nuevas bases de datos,
realizar operaciones de actualización, inserción, borrado,...

Ejemplo 14.6:
Si se desea consultar las tablas de la base de datos mysql se podría utilizar la
siguiente instrucción:

mysql> SHOW TABLES;


+-----------------+
| Tables_in_mysql |
+-----------------+
| columns_priv |
| db |
| func |
| host |
| tables_priv |
| user |
+-----------------+
6 rows in set (0.42 sec)

Cuando se desea ver una descripción completa de la estructura de una tabla puede
usarse la instrucción DESCRIBE o SHOW COLUMNS.

Ejemplo 14.7:
Para mostrar la estructura de la tabla user, se podría utilizar cualquiera de las dos
sentencias siguientes:

mysql> DESCRIBE USER;

mysql> SHOW COLUMNS FROM USER;

En ambos casos, en la consola aparecería una descripción de los campos de la


tabla, indicando el nombre de cada atributo, el tipo y otras características como la
aceptación de valores nulos o valores por defecto para el atributo. En concreto, los
campos que componen la tabla user son los que se muestran en la Tabla 14.1.

De todos los atributos de la tabla user, los tres primeros (host, user y
password) identifican a cada usuario y los restantes establecen sus privilegios.
Por ejemplo, el atributo Insert_priv puede tomar el valor 'N' (no) o el valor
'Y' (yes), siendo el primero el valor por defecto, y determina si el usuario tiene o

347
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

no privilegios para insertar datos en las tablas. El control de privilegios en MySQL


es bastante completo, permitiendo incluso establecer privilegios individuales para
cada tabla de cada base de datos; en el próximo capítulo se explicará con más
detalle la gestión de privilegios de usuarios.

Campo Tipo Atributos Nulo Def.


Host varchar(60) BINARY No
User varchar(16) BINARY No
password varchar(16) No
Select_priv enum('N', 'Y') No N
Insert_priv enum('N', 'Y') No N
Update_priv enum('N', 'Y') No N
Delete_priv enum('N', 'Y') No N
Create_priv enum('N', 'Y') No N
Drop_priv enum('N', 'Y') No N
Reload_priv enum('N', 'Y') No N
Shutdown_priv enum('N', 'Y') No N
Process_priv enum('N', 'Y') No N
File_priv enum('N', 'Y') No N
Grant_priv enum('N', 'Y') No N
References_priv enum('N', 'Y') No N
Index_priv enum('N', 'Y') No N
Alter_priv enum('N', 'Y') No N
Show_db_priv enum('N', 'Y') No N
Super_priv enum('N', 'Y') No N
Create_tmp_table_priv enum('N', 'Y') No N
Lock_tables_priv enum('N', 'Y') No N
Execute_priv enum('N', 'Y') No N
Repl_slave_priv enum('N', 'Y') No N
Repl_client_priv enum('N', 'Y') No N
ssl_type enum('','ANY','X509', No
'SPECIFIED')
ssl_cipher blob BINARY No
x509_issuer blob BINARY No
x509_subject blob BINARY No
max_questions int(11) No 0
max_updates int(11) UNSIGNED No 0
max_connections int(11) UNSIGNED No 0

Tabla 14.1 Campos de la tabla user

348
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Ejemplo 14.8:
Si se desea obtener un listado con los nombres de usuario, contraseñas y servidores de
todos los usuarios registrados, se podría realizar una simple consulta de selección:

mysql> SELECT USER,PASSWORD,HOST FROM USER;


+------+----------+-----------+
| USER | PASSWORD | HOST |
+------+----------+-----------+
| root | | localhost |
| root | | % |
| | | localhost |
| | | % |
+------+----------+-----------+
4 rows in set (0.00 sec)

En este momento pueden observarse los cuatro usuarios definidos por defecto, los
dos superusuarios root y los dos usuarios invitados.

14.4.2. ELIMINACIÓN DE USUARIOS


Como se ha recomendado anteriormente, una de las primeras operaciones a realizar
debería ser la supresión de los usuarios invitados (los que tienen nombre de usuario
vacío). La supresión de un usuario implica la eliminación del correspondiente
registro de la tabla user; por tanto, debería usarse la sentencia DELETE.

Ejemplo 14.9:
La eliminación de los usuarios de nombre vacío se haría de la siguiente manera:

mysql> DELETE FROM user WHERE user='';


Query OK, 2 rows affected (0.16 sec)

Una vez realizada la eliminación, se puede repetir la consulta de selección de usuarios


para comprobar que realmente los dos usuarios invitados han sido eliminados:

mysql> SELECT user,password,host FROM user;


+------+----------+-----------+
| user | password | host |
+------+----------+-----------+
| root | | localhost |
| root | | % |
+------+----------+-----------+
2 rows in set (0.00 sec)

349
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Sin embargo, se puede comprobar que si se sale del monitor (sentencia EXIT) y se
vuelve a entrar con usuario invitado (mysql –p), el sistema permitiría aún el
acceso. La razón es que para que los cambios de usuario tengan efecto, el servidor
MySQL debe reiniciarse. La forma de reiniciar el servidor es mediante la ejecución
del programa mysqladmin con la opción reload desde fuera del monitor
MySQL. A continuación se observa esta secuencia de operaciones:

mysql> exit
Bye

C:\mysql\bin>mysqladmin reload

C:\mysql\bin>mysql -p
Enter password:
ERROR 1045: Access denied for user: 'ODBC@localhost'
(Using password: NO)

C:\mysql\bin>mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 22 to server version: 4.0.18-
nt

Type 'help;' or '\h' for help. Type '\c' to clear the


buffer.

Como puede observarse, una vez eliminados los usuarios invitados y reiniciado el
servidor, la única posibilidad sería entrar con el usuario root.

14.4.3. ESTABLECIMIENTO DE CONTRASEÑAS PARA


LOS USUARIOS
Otra de las operaciones que conviene realizar cuanto antes es el establecimiento de
una contraseña para el usuario root, ya que este usuario viene por defecto con
una contraseña vacía que evidentemente no ofrece ningún tipo de seguridad. Los
passwords se pueden asignar de varias maneras, una primera forma es utilizar la
sentencia SET PASSWORD.

Ejemplo 14.10:
Si se desea establecer como password la cadena 'miclave' para el usuario root
cuando se conecte desde el propio servidor local, la sentencia sería:

350
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> SET PASSWORD FOR 'root'@'localhost' =


-> PASSWORD('miclave');

La función PASSWORD() permite encriptar el password antes de guardarlo en la


tabla. Aunque su uso no es obligado, sí que resulta recomendable ya que de esta
manera si un usuario tiene acceso a la tabla user no podrá ver el password real al
hacer una consulta de selección.

Una vez realizada la operación de asignación de contraseña, se podría solicitar de


nuevo el listado de los usuarios registrados:

mysql> SELECT user,password,host FROM user;


+------+------------------+-----------+
| user | password | host |
+------+------------------+-----------+
| root | 0ff1bdab147337f1 | localhost |
| root | | % |
+------+------------------+-----------+
2 rows in set (0.04 sec)

Como puede comprobarse el usuario root conectándose desde el localhost


tiene asignado un password, aunque el valor real de ese password no se muestra en
el resultado de la consulta.

La contraseña anterior también podría ser establecida usando la sentencia UPDATE


para modificar directamente la tabla user:

mysql> UPDATE user SET password = PASSWORD('miclave')


-> WHERE user = 'root';

En este ultimo caso se está asignando la contraseña al mismo tiempo para los dos
usuarios root (el que se conecta desde el servidor local y el que lo hace desde
cualquier otro servidor).

Cuando se modifica directamente la tabla user, para que los cambios tengan
efecto inmediato, debe decirse al sistema que vuelva a leer todas las tablas de
privilegios, de otra manera, los cambios no tendrían efecto hasta que se reinicie el
servidor MySQL. Esto se realiza con la sentencia:

mysql> FLUSH PRIVILEGES;

Finalmente, también es posible asignar contraseñas con el programa mysqladmin


desde fuera del monitor MySQL.

351
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Para que cualquier cambio relativo a usuarios y sus privilegios tenga efecto, es
necesario ejecutar la sentencia FLUSH PRIVILEGES o reiniciar el servidor
MySQL desde fuera del monitor. Esto último puede hacerse usando el programa
mysqladmin:

C:\mysql\bin> mysqladmin reload

Una vez establecida la contraseña del usuario root, se debería entrar de nuevo en
el monitor con la sentencia:

C:\mysql\bin> mysql –u root -p

El monitor solicitará el nuevo password para entrar.

También es posible entrar en el monitor directamente introduciendo la contraseña


sin esperar a que el programa la solicite:

C:\mysql\bin> mysql –u root -pmiclave

En este caso la contraseña se indica a continuación del parámetro –p, sin dejar
ningún espacio entre ambos. Además si la contraseña contiene espacios en blanco o
caracteres especiales, esta debería darse entre comillas dobles.

Esta forma de indicar la contraseña no es recomendable por ser un método


sumamente inseguro de proporcionar la contraseña; ya que un usuario podría ver
los comandos que se están ejecutando en el sistema y en esos comandos aparecería
esta contraseña.

Por último, conviene aclarar que si a continuación del parámetro –p se coloca un


espacio, lo que sigue se interpreta como la base de datos sobre la que se desea
trabajar. Por ejemplo, la sentencia siguiente permitiría entrar en el monitor y
seleccionar directamente la base de datos mysql:

C:\mysql\bin> mysql –u root –p mysql

14.4.4. CREACIÓN DE NUEVOS USUARIOS


La creación de un nuevo usuario no es más que la inclusión de un nuevo registro en
la tabla user. En principio, no es necesario asignar explícitamente valores para
todos los campos de esa tabla, ya que todos ellos tienen valores por defecto.

352
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Ejemplo 14.11:
Con la sentencia:

mysql> INSERT INTO user (Host , User , password)


-> VALUES ('localhost', 'operador',
PASSWORD('snoopy'));

se crea un nuevo usuario que se podrá conectar desde el propio servidor local, con
nombre de usuario operador y contraseña snoopy. Este usuario tendrá los
privilegios establecidos por defecto, estos privilegios solo le permiten el uso de la
tabla test.

A continuación puede verse cómo efectivamente este nuevo usuario tendrá un


acceso a MySQL limitado.

C:\mysql\bin>mysql -u operador -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 48 to server version: 4.0.18-
nt

Type 'help;' or '\h' for help. Type '\c' to clear the


buffer.

mysql> show databases;


+----------+
| Database |
+----------+
| test |
+----------+
1 row in set (0.00 sec)

Ejemplo 14.12:
Si se desea crear un nuevo usuario que tenga permisos solo para seleccionar e
insertar nuevos registros y que pueda conectarse desde cualquier servidor, la
sentencia de inserción debería ser:

mysql> INSERT INTO user (Host , User , password,


-> Select_priv , Insert_priv)
-> VALUES ('%', 'mantenimiento', PASSWORD('mickey'),
-> 'Y', 'Y');

353
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Con estos privilegios el usuario mantenimiento podría ver los datos almacenados
en cualquier tabla de cualquier base de datos y podría insertar nuevos registros e
incluso crear nuevas tablas para insertar registros en ellos. Lo que no podría hacer
son operaciones de modificación de datos, eliminación de registros, creación de
nuevas bases de datos,...

MySQL admite una gestión de privilegios de usuario bastante completa. Más


adelante en este libro se analizarán algunas herramientas de gestión de MySQL que
permiten realizar las labores de administración de usuarios de una manera mucho
más cómoda.

14.5. BASES DE DATOS Y TABLAS EN MySQL


MySQL viene provisto por defecto de dos bases de datos, la primera tiene un uso
puramente administrativo y la segunda es una base de datos para la realización de
pruebas. Por supuesto, todo usuario con los privilegios adecuados puede crear
nuevas bases de datos. La creación implica el uso de la instrucción CREATE
DATABASE.

Ejemplo 14.13:
Para ilustrar el proceso completo de creación de la base de datos se tomará como
referencia la base de datos de los multicines Cinem@s que ya fue diseñada en el
capítulo anterior. El primer paso, por supuesto, es arrancar el monitor MySQL con
un usuario que tenga los privilegios necesarios. En este caso se utilizará el
superusuario root:

C:\mysql\bin>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 48 to server version: 4.0.18-
nt

Type 'help;' or '\h' for help. Type '\c' to clear the


buffer.

Una vez dentro, se debe crear la base de datos, utilizando para ello la sentencia
CREATE:

mysql> CREATE DATABASE cinemas;


Query OK, 1 row affected (0.00 sec)

354
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Una vez creada, debe usarse la sentencia USE para seleccionarla como base de
datos activa.

mysql> USE cinemas;


Database changed

Una vez creada la base de datos, lo siguiente es la creación de las tablas que la
compondrán. La creación de esas tablas se realiza con la correspondiente
instrucción SQL. Por ejemplo, una de las tablas de la base de datos de Cinem@s es
la que permitirá guardar la información de todos los clientes; en concreto, la
creación de esta tabla se haría de la siguiente manera:

mysql> CREATE TABLE CLIENTES (

-> NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,

-> NOMBRE VARCHAR(40) NOT NULL,

-> DIRECCION VARCHAR(50),

-> FECHANAC DATE,

-> TELEF CHAR(9),

-> EMAIL CHAR(30),

-> PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0,

-> CLAVE CHAR(6) NOT NULL,

-> PRIMARY KEY (NUM_CLIENTE));

Query OK, 0 rows affected (0.52 sec)

Se puede comprobar la correcta creación de la tabla solicitando a MySQL que


muestre las tablas de la base de datos:

mysql> SHOW TABLES;


+-------------------+
| Tables_in_cinemas |
+-------------------+
| clientes |
+-------------------+
2 rows in set (0.00 sec)

355
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Incluso se puede utilizar la sentencia DESCRIBE para solicitar a MySQL que


muestre la estructura de la tabla recién creada:
mysql> DESCRIBE clientes;
+-------------+-------------+------+-----+---------+-------+--------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+--------+
| NUM_CLIENTE | smallint(6) | | PRI | NULL auto_increment |
| NOMBRE | varchar(40) | | | | |
| DIRECCION | varchar(50) | YES | | NULL | |
| FECHANAC | date | YES | | NULL | |
| TELEF | varchar(9) | YES | | NULL | |
| EMAIL | varchar(30) | YES | | NULL | |
| PUNTOS_ACUM | smallint(6) | | | 0 | |
| CLAVE | varchar(6) | | | | |
+-------------+-------------+------+-----+---------+----------------+
8 rows in set (0.69 sec)

14.6. TIPOS DE DATOS


En la creación de una tabla debe indicarse un tipo de datos para cada uno de los
atributos que la componen, en esta sección se analizarán los diferentes tipos de
datos soportados por MySQL.

Cada uno de los tipos tiene asociado un espacio de almacenamiento en memoria


del cual a su vez depende el rango admisible de valores que puede tomar el dato.

Es responsabilidad del administrador de la base datos hacer un buen diseño de la


misma, en particular eligiendo adecuadamente los tipos de datos de cada uno de los
atributos de la tabla. Con esta elección debe buscarse la optimización del espacio
de memoria y la eficiencia y rapidez en la consulta de los datos.

Los diferentes tipos de datos pueden ser clasificados en varios grupos o categorías:
numéricos, cadena de caracteres, fecha y hora, conjuntos y enumeraciones,...

14.6.1. TIPOS NUMÉRICOS

Los tipos numéricos pueden, a su vez, ser de dos tipos: enteros y de coma flotante o
decimales. En ambos casos, existen diferentes opciones que permiten trabajar con
números en diferentes rangos.

356
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Tipos Enteros
Nombre Rango Almacenamiento Descripción
TINYINT -128 a 127 1 byte Entero pequeño
BIT 0o1 1 bit Entero 0 o 1
BOOL 0o1 1 bit Entero 0 o 1
SMALLINT -32768 a 32767 2 bytes Entero pequeño
MEDIUMINT -8388608 a 8388607 3 bytes Entero mediano
INT -2147483648 a 2147483647 4 bytes Entero normal
INTEGER -2147483648 a 2147483647 4 bytes Sinónimo de INT

BIGINT -9223372036854775808 a
8 bytes Entero grande
9223372036854775807
Tabla 14.2 Tipos de datos numéricos enteros

Como puede apreciarse en la Tabla 14.2, existen varias posibilidades para trabajar
con tipos enteros, la elección concreta dependerá de lo que realmente se
almacenará en ese argumento; por ejemplo, si se desea definir un argumento para
guardar edades de personas, no parecería muy lógico utilizar el tipo INTEGER por
el enorme desperdicio de espacio en memoria que implicaría.

A la hora de definir un argumento de tipo entero se puede utilizar el argumento


UNSIGNED (sin signo) para impedir que dicho argumento acepte valores con signo
negativo, es decir, solo se podrán utilizar números positivos. El uso de este atributo
además permite duplicar el tamaño del número más grande que puede ser
almacenado; por ejemplo, el rango de valores del tipo TINYINT comprende todos
los números entre –128 y 127, en cambio, el rango de UNSIGNED TINYINT
variará entre 0 y 255.

Salvo en los tipos BIT y BOOL, en el resto de tipos de enteros se puede especificar
entre paréntesis el número máximo de dígitos con el que se mostrará el
correspondiente número. El valor máximo de este parámetro es 255.

Relacionado con esto, el argumento ZEROFILL utilizado para los valores


numéricos, completa con ceros a la izquierda los valores hasta alcanzar esa
longitud máxima. Si se le asigna a un atributo el modificador ZEROFILL
automáticamente se le asignará UNSIGNED.

357
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 14.14:
Si se define un atributo:

NUM_SALA SMALLINT(4) ZEROFILL,

los números de las salas serán mostrados todos ellos con cuatro dígitos,
completando a la izquierda con ceros si fuese necesario.

Tipos numéricos en coma flotante


Básicamente hay dos tipos numéricos en coma flotante: FLOAT y DOUBLE; la
diferencia entre ellos está en el número de bytes que se utilizan para almacenar los
números; en el tipo FLOAT se utilizan cuatro bytes y en el DOUBLE el doble, es
decir, 8 bytes. Además de estos dos tipos básicos, existen una serie de tipos
"sinónimos" que tienen un comportamiento idéntico a ellos. Los tipos numéricos en
coma flotante admitidos por MySQL son los que se muestran en la Tabla 14.3.

Nombre Rango Almacenamiento Descripción

FLOAT ±1.175494351E-38 a Coma flotante de precisión


4 bytes
±3.402823466E+38 única.

DOUBLE ±1.797693134862315E+308 Coma flotante de precisión


8 bytes
a ±2.2507385850720E-308 única.

PRECISION
REAL Sinónimos de double

DECIMAL Número de coma flotante


NUMERIC Un byte para cada
almacenado como cadena de
DEC dígito del número
caracteres

Tabla 14.3 Tipos de datos numéricos en coma flotante

A la hora de definir atributos de tipo numérico en coma flotante también es posible


especificar el número de lugares decimales y el número de dígitos totales con los
que los números serán visualizados. Para hacerlo se deben colocar entre paréntesis
a continuación del nombre del tipo, y separados por coma, la longitud total de
visualización del número y el número máximo de dígitos decimales.

358
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Ejemplo 14.15:
Si se define el atributo PRECIO de la siguiente manera:

PRECIO FLOAT(5,2) ZEROFILL,

Los valores serán visualizados con un máximo de 5 dígitos, dos de ellos


correspondientes a la parte decimal. Conviene indicar que se permitiría almacenar
números con un dígito más siempre que sean positivos.

14.6.2. TIPOS CADENA DE CARACTERES


Para almacenar datos de tipo cadena de caracteres, MySQL incorpora varios tipos
de datos diferentes, que podrían ser clasificados en dos grupos. Por un lado se
encuentran los tipos CHAR y VARCHAR, pensados para almacenar cadenas de
pequeña longitud. La única diferencia entre ambos es que las cadenas de tipo CHAR
se consideran de longitud fija y las VARCHAR de longitud variable; esto significa
que, por ejemplo, cuando en una cadena de longitud fija se incluye un dato con
menos caracteres que los previstos, la cadena se completa con espacios en blanco
hasta alcanzar su longitud. Cuando las cadenas, en cambio, tienen mayor longitud
que la admitida por el tipo de datos, los caracteres de la derecha se eliminan.

En ambos casos, a la hora de definir un atributo con tipo CHAR o VARCHAR, debe
indicarse entre paréntesis la longitud máxima que admitirá. La longitud máxima
posible para esta cadena es, en cualquier caso, de 255 caracteres.

Ejemplo 14.16:
La forma de declarar un atributo NOMBRE para almacenar cadenas de longitud
variable de 20 caracteres como máximo sería:

NOMBRE VARCHAR(20)

La principal ventaja de las cadenas de longitud fija respecto a las de longitud


variable es que las primeras se procesan con mayor rapidez; pero en cambio son
menos eficientes en el uso de memoria. Por ejemplo, si se almacena una cadena
con 3 caracteres en un campo de tipo CHAR(10) se estarían usando 10 bytes (uno
por cada carácter de la cadena más los 7 espacios en blanco que se añadirían) para
guardar ese dato. En cambio, esa misma cadena en un tipo de dato VARCHAR(10)
requeriría 4 bytes (3 para los caracteres y un byte adicional que sirve para
identificar el fin de la cadena).

359
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

MySQL no admite en la construcción de una tabla mezclar el uso de


cadenas de longitud fija y variable. Cuando el usuario defina una tabla
en la que aparezca, simultáneamente tipos CHAR y VARCHAR,
NOTA automáticamente todos serán convertidos a tipo VARCHAR. La única
excepción a esta regla se produce cuando se definen tipos VARCHAR de
4 o menos caracteres, en este caso serán convertidas a CHAR.

Por defecto, MySQL no distingue el uso de mayúsculas y minúsculas en las


cadenas de caracteres, de manera que, por ejemplo, las cadenas 'Shrek' y
'SHREK' son consideradas iguales a efectos de comparaciones en búsquedas,
ordenaciones o cualquier otra operación. Si se desea que sí que se distingan las
letras mayúsculas de las minúsculas, se puede indicar delante del tipo el atributo
BINARY.

Ejemplo 14.17:
La declaración:

COD BINARY VARCHAR(5)

define un atributo que almacenará cadenas de un máximo de 5 caracteres y


diferenciando mayúsculas de minúsculas.

El otro grupo de tipos de datos para almacenar cadenas de caracteres lo constituyen


los tipos TEXT y BLOB, pensados para almacenar grandes cantidades de caracteres.
Los atributos de tipo BLOB (binary large object, objeto binario grande) permiten
además almacenar cualquier tipo de fichero, como por ejemplo imágenes, sonidos,
documentos, programas,...

La diferencia entre un texto guardado en un dato TEXT o BLOB es que en el primer


caso no se diferencian mayúsculas de minúsculas, mientras que en un dato de tipo
BLOB sí que se produce tal diferenciación, lo que afecta a las operaciones de
comparación y ordenación.

Existen diferentes variaciones de los tipos TEXT y BLOB que afectan únicamente a
las longitudes máximas de las cadenas que admiten. En la Tabla 14.4 se incluyen
estas versiones junto con los otros tipos de cadenas analizados.

360
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Longitud máxima
Nombre Almacenamiento Descripción
de caracteres
CHAR 1 1 bytes Un carácter.

CHAR(N) Cadena de longitud fija de N


255 N bytes
caracteres.

VARCHAR(N) Cadena de longitud variable de


255 N+1 bytes
N caracteres.

TINYTEXT Cadenas u objetos binarios de


TINYBLOB 255 L+1 bytes
tamaño pequeño

TEXT Cadenas u objetos binarios de


BLOB 65.535 L+2 bytes
tamaño normal

MEDIUMTEXT 16.777.215 Cadenas u objetos binarios de


MEDIUMBLOB L+3 bytes
(1,6 MB) tamaño mediano

LONGTEXT 4.294.967.295 Cadenas u objetos binarios de


LONGBLOB L+4 bytes
(4,2 GB) tamaño grande

Tabla 14.4 Tipos de cadenas de caracteres

14.6.3. TIPOS ENUM Y SET


Los tipos ENUM permiten definir atributos cuyos valores estén necesariamente en
una lista de valores predeterminados. A la hora de definir el atributo, los valores
deben ser dados entre paréntesis y separados por comas. El número máximo de
valores que admite MySQL es 65.535. Cuando se incorpore un nuevo registro a la
base de datos, para el valor del atributo de tipo ENUM se deberá elegir
necesariamente uno de los de la lista o utilizar el valor especial NULL.

Los tipos SET, en cambio, definen igualmente una lista de valores


predeterminados, pero se podría asignar al correspondiente campo ninguno, uno o
varios de esos valores. Cuando se inserte el registro, los valores de la lista deberán
ser introducidos dentro de una cadena entrecomillada y separados por comas. El
número máximo de elementos que admite MySQL para los conjuntos (SET) es 64.

361
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 14.18:
A continuación se definen dos atributos, uno de tipo ENUM y otro SET:

SESION ENUM('matinal','tarde','noche')

PROY SET('L','M','X','J','V','S','D')

Debe destacarse que los tipos ENUM y SET son visualizados como si
fuesen cadenas de caracteres, pero internamente son tratados y
almacenados como valores numéricos. Cada valor predeterminado tiene
asociado el valor numérico correspondiente a su posición en la lista que
define el atributo. El hecho de que estos tipos de datos sean tratados
NOTA como números hace que su tratamiento sea mucho más rápido y eficaz
que el de las cadenas de caracteres.

14.6.4. TIPOS FECHA/HORA


Para el tratamiento de datos que hagan referencia a instantes de tiempo (fechas y horas)
MySQL también dispone de varios tipos de datos. Todos los valores correspondientes a
fechas y horas deben ser dados como cadenas de caracteres, es decir, entrecomillados,
aunque también es posible dar esos datos como valores numéricos.
Conviene advertir que MySQL utiliza un formato para las fechas en el cual en
primer lugar se indica el año, después el mes y finalmente el día. Para las horas el
formato es el habitual (horas:minutos:segundos). Es de destacar la gran
flexibilidad de MySQL en el momento de introducir una fecha.

Ejemplo 14.19:
Para MySQL cualquiera de las cadenas siguientes correspondería a la misma fecha:
el 31 de marzo de 1997:

'1997/3/31'
'1997-3-31'
19970331

Respecto a las horas, necesariamente debe usarse el signo ':' como separador o
bien indicar los dígitos correspondientes a las horas, minutos y segundos seguidos,
sin ningún separador. Por ejemplo, las 17 horas 5 minutos y 20 segundos se puede
expresar como:

'17:5:20'
170520

362
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

MySQL no comprueba si una fecha es válida en el momento de la


inserción de los datos, solo hace dos simples comprobaciones: que el
mes esté comprendido entre 0 y 12 y el día esté comprendido entre 0 y
NOTA
31. Esto hace que MySQL considere como fecha válida, por ejemplo,
'2005-2-31' (31 de febrero de 2005).

En la Tabla 14.5 se puede observar la variedad de tipos de fecha-hora que MySQL


soporta.

Tamaño de
Nombre Rango Descripción
almacenamiento
1000-01-01 Almacena una fecha con el
DATE 3 bytes
9999-12-31 formato YYYY-MM-DD
3 bytes
-838:59:59 Almacena una hora con el
TIME
838:59:59 formato HH:MM:SS
8 bytes
1000-01-01 00:00:00 Almacena una fecha y una hora
DATETIME con el formato
9999-12-31 23:59:59
YYYY-MM-DD HH:MM:SS

TIMESTAMP Instante de tiempo, combinación


1970-01-01 00:00:00
TIMESTAMP(M) 4 bytes de fecha y hora según diferentes
2037-01-01 00:00:00
formatos
Almacena un año con dos dígitos
YEAR(2) 70-69 (de 1970 a 2069) 1 byte (p.e. 97 corresponde a 1997)

YEAR Almacena un año con cuatro


YEAR(4) 1901 - 2155 1 byte
dígitos

Tabla 14.5 Tipos de dato fecha-hora

El tipo TIMESTAMP resulta especialmente útil ya que si una tabla dispone de un


atributo con este tipo, en él se almacenará de forma automática el "instante de
tiempo" (fecha y hora) en el que se realizó la inserción o última actualización del
correspondiente registro.

El formato en el que son almacenados los instantes de tiempo depende del valor del
parámetro que se haya colocado entre paréntesis en la definición del
correspondiente atributo. La Tabla 14.6 muestra los diferentes formatos asociados a
los diferentes parámetros.

363
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Tipo especificado Formato


TIMESTAMP AAAAMMDDHHMMSS

TIMESTAMP(14) AAAAMMDDHHMMSS

TIMESTAMP(12) AAMMDDHHMMSS

TIMESTAMP(8) AAAAMMDD

TIMESTAMP(6) AAMMDD

TIMESTAMP(4) AAMM

TIMESTAMP(2) AA

Tabla 14.6 Formato de tipos TIMESTAMP

14.7. INTEGRIDAD REFERENCIAL EN MYSQL


MySQL soporta diferentes tipos de tablas: MyISAM, ISAM, HEAP, BDB, InnoDB.
En todas ellas el motor de MySQL admite el uso de la sintaxis para definir
integridad referencial, pero en algunos de los tipos anteriores la integridad
referencial no se encuentra actualmente implementada y por tanto el uso de esa
sintaxis no produce efecto alguno. El primer tipo de tabla que realmente permite
trabajar con restricciones de integridad referencial es el InnoDB, estando previsto
que próximamente también sea implementado para las tablas MyISAM.

A partir de la versión 4.0 de MySQL el soporte para tablas InnoDB es incluido en


la instalación básica del sistema. Para asegurarse de que el servidor MySQL sobre
el que se está trabajando soporta este tipo de tablas, podría consultarse el valor de
la variable have_innodb tal como se muestra a continuación:

mysql> show variables like 'have_innodb';


+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_innodb | YES |
+---------------+-------+
1 row in set (0.03 sec)

364
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

La integridad referencial está íntimamente relacionada con los conceptos de claves


primarias y claves foráneas; las primeras son las que permiten identificar los
registros de una tabla y las segundas permiten relacionar un registro con otro
registro de otra tabla diferente. Por ejemplo, en la tabla de PROYECCIONES se
hace referencia al número de una sala y el identificador de una película, de manera
que la tabla proyecciones contendrá dos claves foráneas una que la relaciona con la
tabla SALAS y otra que la relaciona con la tabla PELICULAS. La integridad
referencial exige que cuando un registro haga referencia a otro registro relacionado
este último debe existir en la tabla relacionada; de esta forma se impide, por
ejemplo, añadir proyecciones que referencien a salas o películas que no existan en
las respectivas tablas.

En las primeras versiones de MySQL no se incluía ningún tipo de control de


integridad referencial, pasando la responsabilidad de evitar situaciones de
inconsistencia (por ejemplo usar números de sala inexistentes) al programador y a la
aplicación que se utilice para gestionar la base de datos. Esta era una de las razones
por las que para muchos programadores MySQL no era apropiado para proyectos de
cierta envergadura. Con las nuevas funcionalidades de las últimas versiones de
MySQL esta reticencia está siendo superada.

14.7.1. DEFINICIÓN DE CLAVES FORÁNEAS


Para que un atributo sea considerado como clave foránea debe ser explícitamente
definido como tal en la sentencia de creación de la tabla. Ya se ha comentado que,
aunque la sintaxis es aceptada en todos los tipos de tablas, fueron las tablas InnoDB
las primeras en las que realmente esta funcionalidad se encuentra implementada.
En concreto, las tablas InnoDB permiten la definición de claves foráneas desde la
versión MySQL 3.23.43.

Para trabajar con claves foráneas es necesario que las dos tablas relacionadas sean
ambas definidas del tipo InnoDB, para ello se colocará al final de la tabla la
cláusula:

TYPE = INNODB

A continuación debe usarse la sintaxis:

FOREIGN KEY(campo) REFERENCES tabla_relacionada

365
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

para indicar el campo de la tabla primaria que se encuentra asociado con la clave
de la tabla relacionada. Por supuesto, ambos campos relacionados deben tener
asociado el mismo tipo de datos.

Finalmente es obligatorio crear un índice sobre el campo que ha sido declarado


como clave foránea. La creación de este índice se hace con la cláusula INDEX.

Ejemplo 14.20:
A continuación se muestra el código completo de creación de la base de datos
Cinem@s haciendo uso de la integridad referencial:

CREATE DATABASE CINEMAS;


USE CINEMAS;

CREATE TABLE PELICULAS (


IDPELICULA SMALLINT NOT NULL AUTO_INCREMENT,
TITULO CHAR(50) NOT NULL ,
ACTORES MEDIUMTEXT ,
PRODUCCION MEDIUMTEXT ,
DIRECCION MEDIUMTEXT ,
GUION VARCHAR(40) ,
ANNO SMALLINT ,
DURACION SMALLINT NOT NULL ,
NACIONALIDAD VARCHAR(25) ,
GENERO ENUM('infantil','comedia','drama','acción',
'terror','erótica') ,
EDAD_RESTRICCION ENUM('apta','mayores 7',
'mayores 13','mayores 18') ,
SINOPSIS LONGTEXT ,
CARTELERA BLOB ,
PRIMARY KEY (IDPELICULA)) TYPE = INNODB;

CREATE TABLE SALAS (


NUM_SALA SMALLINT NOT NULL ,
AFORO SMALLINT NOT NULL ,
NUM_FILAS SMALLINT NOT NULL ,
OBSERVACIONES LONGTEXT ,
PRIMARY KEY (NUM_SALA)) TYPE = INNODB;

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL ,
DIRECCION VARCHAR(50) ,
FECHANAC DATE ,
TELEF CHAR(9) ,

366
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

EMAIL CHAR(30) ,
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0 ,
CLAVE CHAR(6) NOT NULL ,
PRIMARY KEY (NUM_CLIENTE)) TYPE = INNODB;

CREATE TABLE PROYECCIONES (


IDPROY SMALLINT NOT NULL AUTO_INCREMENT,
IDPELICULA SMALLINT NOT NULL ,
NUM_SALA SMALLINT NOT NULL ,
HORA TIME NOT NULL ,
FECHA DATE NOT NULL ,
TARIFA_REDUCIDA BOOL ,
ESTRENO BOOL ,
PRIMARY KEY (IDPROY),
INDEX (IDPELICULA),
FOREIGN KEY (IDPELICULA) REFERENCES PELICULAS
(IDPELICULA),
INDEX (NUM_SALA),
FOREIGN KEY (NUM_SALA) REFERENCES SALAS (NUM_SALA)
) TYPE = INNODB;

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,
IDPROY SMALLINT NOT NULL ,
FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA),
INDEX (IDPROY),
FOREIGN KEY (IDPROY) REFERENCES PROYECCIONES (IDPROY),
INDEX (NUM_CLIENTE),
FOREIGN KEY (NUM_CLIENTE) REFERENCES CLIENTES
(NUM_CLIENTE)
) TYPE = INNODB;

Como puede observarse, todas las tablas han sido definidas del tipo InnoDB, y en
las tablas PROYECCIONES y ENTRADAS se definen dos claves foráneas en cada
una con sus respectivos índices.

Otra posibilidad para crear la base de datos con las restricciones de integridad
referencial es añadir las claves foráneas y los índices después de crear todas las
tablas haciendo uso en este caso de la sentencia ALTER TABLE. El código
completo correspondiente a esta alternativa se muestra a continuación:

CREATE DATABASE CINEMAS;

367
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

USE CINEMAS;

CREATE TABLE PELICULAS (


IDPELICULA SMALLINT NOT NULL AUTO_INCREMENT,
TITULO CHAR(50) NOT NULL ,
ACTORES MEDIUMTEXT ,
PRODUCCION MEDIUMTEXT ,
DIRECCION MEDIUMTEXT ,
GUION VARCHAR(40) ,
ANNO SMALLINT ,
DURACION SMALLINT NOT NULL ,
NACIONALIDAD VARCHAR(25) ,
GENERO ENUM('infantil','comedia','drama','acción',
'terror','erótica') ,
EDAD_RESTRICCION ENUM('apta','mayores 7',
'mayores 13','mayores 18') ,
SINOPSIS LONGTEXT ,
CARTELERA BLOB ,
PRIMARY KEY (IDPELICULA)) TYPE = INNODB;

CREATE TABLE SALAS (


NUM_SALA SMALLINT NOT NULL ,
AFORO SMALLINT NOT NULL ,
NUM_FILAS SMALLINT NOT NULL ,
OBSERVACIONES LONGTEXT ,
PRIMARY KEY (NUM_SALA)) TYPE = INNODB;

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL ,
DIRECCION VARCHAR(50) ,
FECHANAC DATE ,
TELEF CHAR(9) ,
EMAIL CHAR(30) ,
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0 ,
CLAVE CHAR(6) NOT NULL ,
PRIMARY KEY (NUM_CLIENTE)) TYPE = INNODB;

CREATE TABLE PROYECCIONES (


IDPROY SMALLINT NOT NULL AUTO_INCREMENT,
IDPELICULA SMALLINT NOT NULL ,
NUM_SALA SMALLINT NOT NULL ,
HORA TIME NOT NULL ,
FECHA DATE NOT NULL ,
TARIFA_REDUCIDA BOOL ,
ESTRENO BOOL ,
PRIMARY KEY (IDPROY)) TYPE = INNODB;

368
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,
IDPROY SMALLINT NOT NULL ,
FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA)) TYPE = INNODB;

ALTER TABLE PROYECCIONES ADD


INDEX IX_SE_PROYECTA (IDPELICULA);
ALTER TABLE PROYECCIONES ADD FOREIGN KEY (IDPELICULA)
REFERENCES PELICULAS (IDPELICULA);
ALTER TABLE PROYECCIONES ADD INDEX IX_PROYECTA (NUM_SALA);
ALTER TABLE PROYECCIONES ADD FOREIGN KEY (NUM_SALA)
REFERENCES SALAS (NUM_SALA);
ALTER TABLE ENTRADAS ADD INDEX IX_TIENE (IDPROY);
ALTER TABLE ENTRADAS ADD FOREIGN KEY (IDPROY)
REFERENCES PROYECCIONES (IDPROY);
ALTER TABLE ENTRADAS ADD INDEX IX_COMPRA (NUM_CLIENTE);
ALTER TABLE ENTRADAS ADD FOREIGN KEY (NUM_CLIENTE)
REFERENCES CLIENTES (NUM_CLIENTE);

La creación de la base de datos anterior desde el monitor de MySQL puede resultar


un tanto engorrosa; con objeto de facilitar la ejecución de sentencias SQL, MySQL
admite la posibilidad de ejecutar todas las sentencias que se encuentren en un
fichero de texto con la extensión .sql. La forma de hacerlo es usar el comando
SOURCE dentro del monitor, indicando a continuación el nombre del fichero con
su ruta de acceso.

Ejemplo 14.21:
Suponiendo que el fichero con las instrucciones de creación de las tablas se llama
cinemas.sql y que se encuentra en el directorio raíz, la creación de la base de
datos se podría hacer de la manera siguiente:

mysql> SOURCE c:/cinemas.sql;


Query OK, 1 row affected (0.10 sec)
Database changed
Query OK, 0 rows affected (0.78 sec)
Query OK, 0 rows affected (0.13 sec)
Query OK, 0 rows affected (0.23 sec)
Query OK, 0 rows affected (0.34 sec)
Query OK, 0 rows affected (0.15 sec)

369
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Desde dentro del monitor de MySQL es posible dar la orden de


ejecución de las sentencias que se encuentren incluidas en un fichero
externo usando el comando SOURCE que se acaba de ver. También es
posible ejecutar ese fichero externo desde la línea de comandos del
NOTA sistema al mismo tiempo que se entra en el monitor, la manera de
hacerlo es entrar en el servidor con la orden:

mysql –u usuario -p <C:\fichero.sql

En el caso de producirse algún error relativo a la integridad referencial, el monitor


de MySQL mostraría un mensaje como el siguiente:
ERROR 1005: Can't create table '.\cinemas\proyecciones.frm'
(errno: 150)
ERROR 1005: Can't create table '.\cinemas\entradas.frm' (errno:
150)

Por ejemplo, estos mensajes aparecerían si se tratan de crear las claves foráneas sin
crear los correspondientes índices.

Si no se produce ningún error, se puede comprobar que las cinco tablas de la base
de datos habrán sido generadas correctamente:

mysql> show tables;


+-------------------+
| Tables_in_cinemas |
+-------------------+
| clientes |
| entradas |
| peliculas |
| proyecciones |
| salas |
+-------------------+
5 rows in set (0.00 sec)

Cuando se crea una tabla con una clave foránea MySQL asigna internamente un ID
que hará referencia a la restricción que establece sobre la tabla. Para conocer estos
ID se puede utilizar la instrucción SHOW CREATE TABLE.

A continuación se muestra a continuación la aplicación de esta sentencia sobre la


tabla PROYECCIONES.

370
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> SHOW CREATE TABLE PROYECCIONES;

+--------------+--------------------------------------------------------+

| Table | Create Table |

+--------------+--------------------------------------------------------+

| PROYECCIONES | CREATE TABLE `proyecciones` ( |

| | `IDPROY` smallint(6) NOT NULL auto_increment, |

| | `IDPELICULA` smallint(6) NOT NULL default '0', |

| | `NUM_SALA` smallint(6) NOT NULL default '0', |

| | `HORA` time NOT NULL default '00:00:00', |

| | `FECHA` date NOT NULL default '0000-00-00', |

| | `TARIFA_REDUCIDA` tinyint(1) default NULL, |

| | `ESTRENO` tinyint(1) default NULL, |

| | PRIMARY KEY (`IDPROY`), |

| | KEY `IX_SE_PROYECTA` (`IDPELICULA`), |

| | KEY `IX_PROYECTA` (`NUM_SALA`), |

| | CONSTRAINT `proyecciones_ibfk_2` |

| | FOREIGN KEY (`NUM_SALA`) |

| | REFERENCES `salas` (`NUM_SALA`), |

| | CONSTRAINT `proyecciones_ibfk_1` |

| | FOREIGN KEY (`IDPELICULA`) |

| | REFERENCES `peliculas` (`IDPELICULA`) |

| | ) TYPE=InnoDB |

+--------------+--------------------------------------------------------+

1 row in set (0.13 sec)

Como se puede apreciar la clave foránea NUM_SALA de la tabla PROYECCIONES


quedará identificada como proyecciones_ibfk_2 y la clave foránea
IDPELICULA como proyecciones_ibfk_1. Estos identificadores se utilizan

371
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

por ejemplo para eliminar la correspondiente clave foránea con la sentencia ALTER
TABLE. Por ejemplo, si se quisiese suprimir la clave foránea NUM_SALA se podría
ejecutar la sentencia:

ALTER TABLE PROYECCIONES


DROP FOREIGN KEY proyecciones_ibfk_1;

14.7.2. INSERCIÓN DE REGISTROS EN TABLAS


RELACIONADAS
Para comprender el funcionamiento de la integridad referencial, se podrían incluir
en las tablas de la base de datos recién creada los primeros registros.

Ejemplo 14.22:
En primer lugar se insertará una película y dos salas en las respectivas tablas:

mysql> INSERT INTO PELICULAS(IDPELICULA,TITULO,ANNO)


-> VALUES(1,'Buscando a Nemo',2003);
Query OK, 1 row affected (0.50 sec)
mysql> INSERT INTO SALAS(NUM_SALA,AFORO,NUM_FILAS)
-> VALUES (1,240,12);
Query OK, 1 row affected (0.55 sec)

mysql> INSERT INTO SALAS(NUM_SALA,AFORO,NUM_FILAS)


-> VALUES (2,180,10);
Query OK, 1 row affected (0.04 sec)

Una vez incluida la película, cuyo identificador es 1, y las salas, con identificadores
1 y 2 respectivamente, es posible, por ejemplo, dar de alta una nueva proyección de
la película 1 en la sala 2 para las 16:30 del día 16 de mayo de 2004; esta
proyección tendrá como identificador el número 1:

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(1,1,2,'16:30:00','2004-5-16');
Query OK, 1 row affected (0.09 sec)

En cambio, si se trata de insertar una nueva proyección que referencie a una sala
inexistente (sala 3) o una película inexistente (película 50), se produce una
violación de las restricciones de integridad referencial, MySQL detecta esa
violación, no incluye el registro y muestra un mensaje de error.

372
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(2,1,3,'16:30:00','2004-5-17');
ERROR 1216: Cannot add or update a child row: a foreign
key constraint fails

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(3,50,1,'20:15:00','2004-5-21');
ERROR 1216: Cannot add or update a child row: a foreign
key constraint fails

14.7.3. ELIMINACIÓN DE REGISTROS EN TABLAS


RELACIONADAS
Se pueden producir también violaciones de integridad referencial en las
operaciones de borrado.

Ejemplo 14.23:
MySQL no permitiría borrar la película 1 ni la sala 2 porque existen
proyecciones relacionadas que quedarían huérfanas en caso de producirse el
borrado. En cambio sí es posible borrar la sala 1 ya que no tiene ninguna
proyección relacionada.

mysql> DELETE FROM PELICULAS WHERE IDPELICULA=1;


ERROR 1217: Cannot delete or update a parent row: a
foreign key constraint fails

mysql> DELETE FROM SALAS WHERE NUM_SALA=1;


Query OK, 1 row affected (0.11 sec)

mysql> DELETE FROM SALAS WHERE NUM_SALA=2;


ERROR 1217: Cannot delete or update a parent row: a
foreign key constraint fails

Para poder borrar los registros correspondientes a la película 1 y sala 2 deberían


borrarse previamente el registro que lo relaciona en la tabla de proyecciones.

mysql> DELETE FROM PROYECCIONES WHERE IDPROY=1;


Query OK, 1 row affected (0.12 sec)

mysql> DELETE FROM PELICULAS WHERE IDPELICULA=1;


Query OK, 1 row affected (0.15 sec)

373
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

mysql> DELETE FROM SALAS WHERE NUM_SALA=2;


Query OK, 1 row affected (0.09 sec)

En el ejemplo anterior se ha visto cómo cuando se utilizan claves foráneas no es


posible eliminar un registro si previamente no se eliminan los registros
relacionados. Sin embargo, la definición de claves foráneas permite que estos
procesos de eliminación encadenados se produzcan de manera automática, esto es
lo que se denomina eliminación en cascada, o bien se realicen otro tipo de
operaciones automatizadas. En concreto, son cinco las opciones de borrado que se
pueden utilizar a la hora de definir la clave foránea:

⎯ ON DELETE RESTRICT: esta es la opción por defecto e impide


cualquier operación de borrado mientras existan registros relacionados.
o Ejemplo: no se podrá borrar una película mientras existan
proyecciones de la misma.

⎯ ON DELETE NO ACTION: produce el mismo efecto que la opción


anterior, es decir, se restringe la eliminación.

⎯ ON DELETE SET DEFAULT: al eliminar un registro, a los registros


relacionados con él se les asignará automáticamente el valor que haya sido
definido por defecto para la clave foránea (esta opción no está actualmente
disponible en MySQL).

⎯ ON DELETE SET NULL: al eliminar un registro, a los registros


relacionados con él se les asignará automáticamente el valor NULL para la
clave foránea, siempre que esta haya sido definida permitiendo este valor.
o Ejemplo: al borrar una película se pondrá el valor NULL en el
atributo IDPELICULA de todas las proyecciones relacionadas
(para que esto sea posible se tendría que eliminar la opción NOT
NULL que aparece en la definición del atributo IDPELICULA de
la tabla PROYECCIONES).

⎯ ON DELETE CASCADE: los registros serán eliminados en cascada.


o Ejemplo: al borrar una película se borrarán todas las
proyecciones de la misma.

Ejemplo 14.24:
Si se quisiera que los procesos de borrado se produjeran en cascada en la tabla de
proyecciones, lo primero que se debería hacer es modificar la definición de sus dos

374
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

claves foráneas para incluir la opción ON DELETE CASCADE. Estas


modificaciones se pueden realizar con la sentencia ALTER TABLE:

mysql> ALTER TABLE PROYECCIONES ADD FOREIGN


KEY(IDPELICULA)
-> REFERENCES PELICULAS(IDPELICULA) ON DELETE CASCADE;
Query OK, 0 rows affected (0.72 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE PROYECCIONES ADD FOREIGN KEY(NUM_SALA)


-> REFERENCES SALAS(NUM_SALA) ON DELETE CASCADE;
Query OK, 0 rows affected (0.72 sec)
Records: 0 Duplicates: 0 Warnings: 0

De esta forma, a partir de ahora cada vez que se suprima una película o una sala,
automáticamente se eliminarán todas las proyecciones de esa película o que tengan
lugar en esa sala.

Para comprobar el correcto funcionamiento de estas opciones se incluyen a


continuación unas series de registros en las tres tablas implicadas. En primer lugar
se insertan 4 películas:

mysql> INSERT INTO PELICULAS(IDPELICULA,TITULO)


-> VALUES (10,"Piratas del Caribe");
Query OK, 1 row affected (0.59 sec)

mysql> INSERT INTO PELICULAS(IDPELICULA,TITULO)


-> VALUES (11,"La ventana secreta");
Query OK, 1 row affected (0.59 sec)

mysql> INSERT INTO PELICULAS(IDPELICULA,TITULO)


-> VALUES (12,"Cuando menos te lo esperas");
Query OK, 1 row affected (0.11 sec)

mysql> INSERT INTO PELICULAS(IDPELICULA,TITULO)


-> VALUES (13,"La mala educación");
Query OK, 1 row affected (0.15 sec)

A continuación se insertan los registros correspondientes a 3 salas:

mysql> INSERT INTO SALAS(NUM_SALA,AFORO,NUM_FILAS)


-> VALUES(1,180,10);
Query OK, 1 row affected (0.55 sec)
mysql> INSERT INTO SALAS(NUM_SALA,AFORO,NUM_FILAS)
-> VALUES(2,120,12);
Query OK, 1 row affected (0.05 sec)

375
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

mysql> INSERT INTO SALAS(NUM_SALA,AFORO,NUM_FILAS)


-> VALUES(3,90,10);
Query OK, 1 row affected (0.10 sec)

Finalmente, se añaden registros correspondientes a las proyecciones:

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(1,10,2,'16:15','2004-7-23');
Query OK, 1 row affected (0.12 sec)

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(2,10,3,'20:30','2004-7-24');
Query OK, 1 row affected (0.09 sec)

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(3,11,3,'20:30','2004-7-25');
Query OK, 1 row affected (0.05 sec)

mysql> INSERT INTO PROYECCIONES(IDPROY,IDPELICULA,


-> NUM_SALA,HORA,FECHA)
-> VALUES(4,12,1,'21:00','2004-7-25');
Query OK, 1 row affected (0.11 sec)

Con tres sencillas consultas de selección se podría consultar el contenido de las tres
tablas en este momento.

mysql> SELECT IDPELICULA,TITULO FROM PELICULAS;


+------------+----------------------------+
| IDPELICULA | TITULO |
+------------+----------------------------+
| 10 | Piratas del Caribe |
| 11 | La ventana secreta |
| 12 | Cuando menos te lo esperas |
| 13 | La mala educación |
+------------+----------------------------+
4 rows in set (0.15 sec)

376
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> SELECT * FROM SALAS;


+----------+-------+-----------+---------------+
| NUM_SALA | AFORO | NUM_FILAS | OBSERVACIONES |
+----------+-------+-----------+---------------+
| 1 | 180 | 10 | NULL |
| 2 | 120 | 12 | NULL |
| 3 | 90 | 10 | NULL |
+----------+-------+-----------+---------------+
3 rows in set (0.00 sec)

mysql> SELECT IDPROY,IDPELICULA,NUM_SALA,HORA,FECHA


-> FROM PROYECCIONES;
+--------+------------+----------+----------+------------+
| IDPROY | IDPELICULA | NUM_SALA | HORA | FECHA |
+--------+------------+----------+----------+------------+
| 1 | 10 | 2 | 16:15:00 | 2004-07-23 |
| 2 | 10 | 3 | 20:30:00 | 2004-07-24 |
| 3 | 11 | 3 | 20:30:00 | 2004-07-25 |
| 4 | 12 | 1 | 21:00:00 | 2004-07-25 |
+--------+------------+----------+----------+------------+
4 rows in set (0.00 sec)

Por ejemplo, se desea eliminar la película Piratas del Caribe (cuyo identificador es
10); la sentencia sería:

mysql> DELETE FROM PELICULAS WHERE


-> TITULO='Piratas del Caribe';
Query OK, 1 row affected (0.54 sec)

Como puede apreciarse, el servidor de MySQL en este caso acepta la operación de


borrado y automáticamente borra esa película y las proyecciones número 1 y 2
(proyecciones que se encontraban relacionadas con la película 10). Esto puede
comprobarse volviendo a ejecutar la consulta de selección sobre la tabla de
PROYECCIONES.

mysql> SELECT IDPROY,IDPELICULA,NUM_SALA,HORA,FECHA


-> FROM PROYECCIONES;
+--------+------------+----------+----------+------------+
| IDPROY | IDPELICULA | NUM_SALA | HORA | FECHA |
+--------+------------+----------+----------+------------+
| 3 | 11 | 3 | 20:30:00 | 2004-07-25 |
| 4 | 12 | 1 | 21:00:00 | 2004-07-25 |
+--------+------------+----------+----------+------------+
2 rows in set (0.00 sec)

377
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

De la misma manera se puede borrar la sala número 3 y las proyecciones asociadas


(en este caso la proyección 3).

mysql> DELETE FROM SALAS WHERE NUM_SALA=3;


Query OK, 1 row affected (0.46 sec)

mysql> SELECT IDPROY,IDPELICULA,NUM_SALA,HORA,FECHA


-> FROM PROYECCIONES;
+--------+------------+----------+----------+------------+
| IDPROY | IDPELICULA | NUM_SALA | HORA | FECHA |
+--------+------------+----------+----------+------------+
| 4 | 12 | 1 | 21:00:00 | 2004-07-25 |
+--------+------------+----------+----------+------------+
1 row in set (0.00 sec)

El contenido de las dos restantes tablas puede verse a continuación:

mysql> SELECT IDPELICULA,TITULO FROM PELICULAS;


+------------+----------------------------+
| IDPELICULA | TITULO |
+------------+----------------------------+
| 11 | La ventana secreta |
| 12 | Cuando menos te lo esperas |
| 13 | La mala educación |
+------------+----------------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM SALAS;


+----------+-------+-----------+---------------+
| NUM_SALA | AFORO | NUM_FILAS | OBSERVACIONES |
+----------+-------+-----------+---------------+
| 1 | 180 | 10 | NULL |
| 2 | 120 | 12 | NULL |
+----------+-------+-----------+---------------+
2 rows in set (0.00 sec)

378
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

14.7.4. ACTUALIZACIÓN DE REGISTROS EN TABLAS


RELACIONADAS
Al igual que ocurre en las operaciones de borrado, en las actualizaciones de
registros también se pueden ver afectados registros de tablas relacionadas. Por
ejemplo, un cambio en la numeración de las salas afecta a la correspondiente clave
foránea de las proyecciones de dicha sala.

A la hora de definir las claves primarias se puede definir también la operación a


realizar cuando se modifican registros relacionados. En concreto, son tres las
opciones:

⎯ ON UPDATE RESTRICT: esta es la opción por defecto e impide


cualquier modificación mientras existan registros relacionados.
o Ejemplo: no se podrá cambiar el identificador de una sala o
película mientras existan proyecciones asociadas.

⎯ ON UPDATE SET NULL: se establecerán valores nulos para los atributos


relacionados cuando se produzca un cambio en la clave de la tabla
principal.

⎯ ON UPDATE CASCADE: se producirán las modificaciones en cascada de


todos los registros relacionados.
o Ejemplo: al cambiar el número de sala se cambiará
automáticamente el número de sala de todas las proyecciones que
tenían lugar en esa sala.

Si en la tabla ya se ha definido previamente alguna restricción de clave foránea,


esta tiene que ser previamente eliminada para poder incluir la restricción de
actualización. En la eliminación de la restricción debe usarse el identificador
interno que MySQL asocia a cada restricción de integridad referencial.

Ejemplo 14.25:
mysql> ALTER TABLE PROYECCIONES
-> DROP FOREIGN KEY proyecciones_ibfk_4;
Query OK, 1 row affected (0.30 sec)
Records: 1 Duplicates: 0 Warnings: 0

Una vez eliminada la restricción anterior se vuelve a definir incluyendo en este


caso las dos opciones: la de borrado y la de actualización.

379
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

mysql> ALTER TABLE PROYECCIONES ADD FOREIGN KEY(NUM_SALA)


-> REFERENCES SALAS(NUM_SALA) ON DELETE CASCADE
-> ON UPDATE CASCADE;
Query OK, 0 rows affected (0.30 sec)
Records: 0 Duplicates: 0 Warnings: 0

Cuando en una misma definición de clave foránea se incluyen las dos


opciones: borrado (ON DELETE) y actualización (ON UPDATE),
NOTA necesariamente debe indicarse en primer lugar la de borrado y en
segundo lugar la de actualización.

Ejemplo 14.26:
A continuación se muestra el funcionamiento de la actualización en cascada. En
primer lugar se puede observar que la tabla SALAS incluye dos registros, uno de
los cuales (el correspondiente a la sala 1) se encuentra relacionado con un registro
de la tabla PROYECCIONES:

mysql> SELECT * FROM SALAS;


+----------+-------+-----------+---------------+
| NUM_SALA | AFORO | NUM_FILAS | OBSERVACIONES |
+----------+-------+-----------+---------------+
| 1 | 180 | 10 | NULL |
| 2 | 120 | 12 | NULL |
+----------+-------+-----------+---------------+
2 rows in set (0.00 sec)

mysql> SELECT IDPROY,IDPELICULA,NUM_SALA,HORA,FECHA


-> FROM PROYECCIONES;
+--------+------------+----------+----------+------------+
| IDPROY | IDPELICULA | NUM_SALA | HORA | FECHA |
+--------+------------+----------+----------+------------+
| 4 | 12 | 1 | 21:00:00 | 2004-07-25 |
+--------+------------+----------+----------+------------+
1 row in set (0.00 sec)

La siguiente sentencia modifica el número de la sala 1, pasando a ser a partir de


ahora la sala 3:

mysql> UPDATE SALAS SET NUM_SALA=3 WHERE NUM_SALA=1;


Query OK, 1 row affected (0.45 sec)
Rows matched: 1 Changed: 1 Warnings: 0

380
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Como puede apreciarse, la modificación se produce sobre la tabla SALAS pero


también en el registro seleccionado de la tabla PROYECCIONES:

mysql> SELECT * FROM SALAS;


+----------+-------+-----------+---------------+
| NUM_SALA | AFORO | NUM_FILAS | OBSERVACIONES |
+----------+-------+-----------+---------------+
| 2 | 120 | 12 | NULL |
| 3 | 180 | 10 | NULL |
+----------+-------+-----------+---------------+
2 rows in set (0.00 sec)

mysql> SELECT IDPROY,IDPELICULA,NUM_SALA,HORA,FECHA


-> FROM PROYECCIONES;
+--------+------------+----------+----------+------------+
| IDPROY | IDPELICULA | NUM_SALA | HORA | FECHA |
+--------+------------+----------+----------+------------+
| 4 | 12 | 3 | 21:00:00 | 2004-07-25 |
+--------+------------+----------+----------+------------+
1 row in set (0.00 sec)

14.8. IMPORTACIÓN Y EXPORTACIÓN DE


DATOS

14.8.1. IMPORTACIÓN DE DATOS


Una vez definida la base de datos y establecidas las restricciones de integridad
referencial, se está en condiciones de hacer uso de la misma. Por supuesto, una de
las primeras labores a realizar será la inclusión en las diferentes tablas de los
registros con los datos a manejar. Una primera opción para insertar datos es el uso
de la sentencia INSERT, tal como se ha venido utilizando en los ejemplos
anteriores. Sin embargo, el uso de esta sentencia para la inclusión de un gran
número de registros resulta excesivamente laborioso; por ello, MySQL incorpora
mecanismos mucho más ágiles para cargar datos en las tablas desde ficheros
externos. En concreto, se puede utilizar el programa mysqlimport que se
encuentra en el directorio mysql/bin o el comando LOAD DATA INFILE del
monitor de MySQL. Además de estas opciones también sería posible escribir todo
un conjunto de sentencias INSERT en un fichero de texto y ejecutarlas todas ellas
con el comando SOURCE.

381
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 14.27:
Supóngase que se dispone de un fichero de texto que contiene la siguiente
información:
1 Luis López Floranes 54, Santander 1970-3-31 942221133 llopez@coldmail.com 0 llp70
2 María Anta San Juan 22, Oviedo 1981-11-22 686776612 manta@tumail.com 0 as23b
3 Ana Palacios San Andrés 39, Madrid 1968-5-1 null apm55@tumail.com 0 aaa45b
4 Valeria Vázquez Moro 120, Almería 1990-2-13 645162377 vv90@coldmail.com 0 basw25

Como puede apreciarse, cada una de las líneas del fichero contiene los datos
correspondientes a un registro de la tabla CLIENTES, coincidiendo en número y
tipo los respectivos datos con los atributos de esa tabla, y estando separados los
datos por tabuladores.

Si se desea importar directamente esos datos desde el fichero de texto a la tabla


CLIENTES de la base de datos CINEMAS, lo primero que debe hacerse es nombrar
ese fichero como clientes.txt, obsérvese que es obligatorio que el nombre
del fichero coincida con el nombre de la tabla.

Una vez disponible el fichero anterior, desde la línea de comandos del sistema (no
desde dentro del monitor de MySQL) se haría una llamada a la utilidad
mysqlimport indicando, por este orden, el nombre de usuario para conectarse al
servidor, el parámetro para solicitar la contraseña, el nombre de la base de datos de
destino y el nombre y ruta del archivo de texto:

C:\mysql\bin>mysqlimport -u root -p cinemas


c:\clientes.txt
Enter password: *******
cinemas.clientes: Records: 4 Deleted: 0 Skipped: 0
Warnings: 0

Entrando al monitor de MySQL se observa que los datos han sido correctamente
importados.

C:\mysql\bin>mysql -u root -p
Enter password: *******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 97 to server version: 4.0.18-
nt

Type 'help;' or '\h' for help. Type '\c' to clear the


buffer.

mysql> USE cinemas;


Database changed

382
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> SELECT NUM_CLIENTE, NOMBRE FROM clientes;


+-------------+-----------------+
| NUM_CLIENTE | NOMBRE |
+-------------+-----------------+
| 1 | Luis López |
| 2 | María Anta |
| 3 | Ana Palacios |
| 4 | Valeria Vázquez |
+-------------+-----------------+
4 rows in set (0.00 sec)

El programa mysqlimport cuenta con un gran número de parámetros


opcionales, algunos de los más destacados son:

-d o -delete: esta opción haría que se borraran todos los datos


existentes en la tabla antes de la importación.

-r o -replace: esta opción haría que aquellos registros de la tabla


cuya clave primaria coincida con alguna de las que se están importando
sean reemplazados.

-fields-enclosed-by=char: esta opción permite especificar el


carácter que encierra a los datos en el fichero de texto, por ejemplo, los
diferentes datos podrían estar encerrados entre comillas.

-fields-terminated-by=char: esta opción permite especificar el


carácter que delimita los campos en el fichero de texto. Por defecto el
delimitador es el tabulador.

-lines-terminated-by=str: esta opción permite especificar el


carácter o secuencia de caracteres que actúa de delimitador de registro en el
fichero de texto. Por defecto el delimitador es el cambio de línea.

Otra alternativa para importar datos que se encuentren en ficheros de texto es el uso
del comando LOAD DATA INFILE del monitor de MySQL. Para poder hacer uso
de este comando, a diferencia del caso anterior, se debe estar ya dentro del monitor
de MySQL, e incluso es posible su uso desde aplicaciones programadas al efecto.

En algunos aspectos el uso de este comando es muy similar al uso de la utilidad


mysqlimport ya que, por ejemplo, se pueden especificar los caracteres que
actúan de separadores de campos y registros.

383
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Ejemplo 14.28:
Supóngase que se desea incluir en la tabla SALAS los 7 registros que se
encuentran en un fichero de texto llamado relacionsalas.txt y cuyo
contenido es:

1,300,15,Localidades para minusválidos


2,240,20
3,240,12,Sala renovada recientemente
4,120,10,Localidades para minusválidos
5,120,12
6,120,10,Poca visibilidad en zonas laterales
7,90,10

Como se aprecia, en este caso el carácter que actúa de separador de campos es


la coma y el separador de registros el cambio de línea. Este último es el
separador de registros por defecto, pero en cambio el separador de campos
por defecto es el tabulador.

Desde dentro del monitor de MySQL la secuencia de operaciones necesaria para


importar esos datos es:

mysql> USE CINEMAS;


Database changed
mysql> LOAD DATA INFILE "C:/relacionsalas.txt"
-> REPLACE INTO TABLE SALAS
-> FIELDS TERMINATED BY ',';
Query OK, 7 rows affected (0.64 sec)
Records: 7 Deleted: 0 Skipped: 0 Warnings: 3

El parámetro opcional REPLACE indica que en caso de que ya existan registros con
la misma clave en la tabla destino, estos deben ser reemplazados. De igual manera,
se utiliza otro parámetro opcional (FIELDS TERMINATED BY) para indicar el
separador de campos.

Con una consulta SELECT se puede comprobar que los datos han sido
correctamente importados:

384
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

mysql> SELECT * FROM SALAS;


+----------+-------+-----------+-------------------------------------+
| NUM_SALA | AFORO | NUM_FILAS | OBSERVACIONES
+----------+-------+-----------+-------------------------------------+
| 1 | 300 | 15 | Localidades para minusválidos
| 2 | 240 | 20 | NULL
| 3 | 240 | 12 | Sala renovada recientemente
| 4 | 120 | 10 | Localidades para minusválidos
| 5 | 120 | 12 | NULL
| 6 | 120 | 10 | Poca visibilidad en zonas laterales
| 7 | 90 | 10 | NULL
+----------+-------+-----------+-------------------------------------+
7 rows in set (0.03 sec)

Otro de los parámetros opcionales del comando LOAD DATA IN FILE es el


parámetro ENCLOSED BY, que permite indicar el carácter que se utiliza para
encerrar los campos. Por ejemplo, si los campos de los registros en el fichero de
texto se encontraran encerrados entre caracteres #, el comando a utilizar para la
importación sería:

LOAD DATA INFILE "C:/relacionsalas.txt" INTO TABLE SALAS


FIELDS TERMINATED BY ',' ENCLOSED BY '#';

Las dos opciones de importación de datos analizadas resultan especialmente útiles


cuando se dispone de los datos en otros soportes; por ejemplo, si se dispone de una
hoja de cálculo, se puede generar fácilmente un fichero de texto con los
separadores que se desee para luego importarlo desde MySQL.

14.8.2. EXPORTACIÓN DE DATOS


Al igual que resulta interesante disponer de mecanismos para importar los datos, no
menos interesante resulta poder generar ficheros de texto con los datos de las tablas
o resultados de consultas con objeto de ser exportados a otras aplicaciones.

Existen varias formas o mecanismos de exportación de datos; la primera es el


uso del programa mysqldump que permite generar un fichero de texto con
todos los comandos de SQL necesarios para reconstruir la base de datos. Este
fichero incluiría todas las sentencias de creación de tablas (CREATE TABLE)
con sus relaciones y todas las sentencias de inserción de los registros en cada
tabla (INSERT); de manera que ejecutando este fichero en MySQL o en otro
sistema gestor de bases de datos basado en SQL se podría reconstruir
completamente la base de datos.

385
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La generación de este fichero debe hacerse desde la línea de comandos del sistema,
utilizando la sintaxis siguiente:

C:\mysql\bin>mysqdump -u root -p cinemas >respaldobd.txt


Enter password: *******

Si después del nombre de la base de datos se indica el nombre de una de sus tablas,
el fichero generado únicamente contendrá la definición de esa tabla y las sentencias
de inserción de sus registros.

Ejemplo 14.29:
Se puede generar un fichero de respaldo de la tabla clientes de la siguiente manera:

C:\mysql\bin>mysqdump -u root -p cinemas clientes


>rclie.txt
Enter password: *******

Incluso es posible indicar una condición de filtrado de registros, por ejemplo,


generar el fichero con los datos de las salas de aforo mayor que 200:

C:\mysql\bin>mysqdump -u root -p –w "AFORO>200" cinemas


salas >rsalas.txt
Enter password: *******

Desde dentro del monitor de MySQL también es posible la exportación de datos a


ficheros de texto, en este caso se utiliza el comando SELECT INTO OUTFILE.
A continuación se muestran un par de ejemplos de su uso desde el monitor de
MySQL.

Ejemplo 14.30:
mysql> USE CINEMAS;
Database changed

mysql> SELECT NOMBRE,PUNTOS_ACUM


-> INTO OUTFILE 'PuntosClientes.txt'
-> FIELDS TERMINATED BY ':'FROM CLIENTES;
Query OK, 4 rows affected (0.00 sec)

Con esta instrucción se generaría un fichero de texto con los nombres y puntos
acumulados de todos los clientes, siendo el contenido del fichero el siguiente:

Luis López:0,María Anta:0,Ana Palacios:0,Valeria Vázquez:0,

386
EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

Ejemplo 14.31:
También es posible indicar una condición de selección de registros, en este caso se
obtienen los nombres de todos los clientes de Santander:

mysql> SELECT NOMBRE INTO OUTFILE 'ClientesSant.txt'


-> FIELDS TERMINATED BY ':' FROM CLIENTES
-> WHERE DIRECCION LIKE '%Santander%';
Query OK, 1 rows affected (0.03 sec)

El fichero de salida generado contendrá en este caso un solo registro.

387
PHPMYADMIN:
ADMINISTRACIÓN DE
BASES DE DATOS
MYSQL DESDE LA
WEB

15.1. INTRODUCCIÓN
La administración y gestión de las bases de datos de MySQL mediante el propio
monitor de MySQL resulta en ocasiones un tanto laboriosa, especialmente para
aquellos usuarios acostumbrados al uso de herramientas con interfaz gráfica de usuario.

Afortunadamente existen alternativas para la administración de las bases de datos


que resultan más intuitivas y sencillas de utilizar; muchas de estas herramientas de
gestión están desarrolladas en el lenguaje PHP y permiten la administración remota
a través de un servidor web. En concreto, una de las más conocidas es la
herramienta phpmyadmin, disponible de forma gratuita a través de Internet y

389
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

desarrollada en PHP por una comunidad de usuarios sin ánimo de lucro


(http://www.phpmyadmin.net).

La aplicación phpmyadmin no es más que un conjunto de páginas escritas en PHP y


que son copiadas directamente en el directorio que aloja las páginas web del
servidor. Mediante las diferentes páginas se pueden consultar las bases de datos
disponibles, crear nuevas bases de datos, tablas, realizar consultas, insertar
registros, administrar los usuarios y sus privilegios, hacer copias de seguridad de
las bases de datos,...

Por supuesto, para poder hacer uso de esta aplicación de administración de MySQL
es necesario disponer de un servidor web con un intérprete de PHP, ya que todas las
páginas están escritas en ese lenguaje. Además es preciso establecer los valores de
diferentes parámetros de configuración que se encuentran dentro del fichero
config.inc.php alojado en el directorio que contiene todas las páginas que
componen la aplicación. Dos de estos parámetros serían PmaAbsoluteUri, que
permite indicar el URL que identifica la localización exacta de la aplicación, y
auth_type, que permite indicar el tipo de autentificación que se utilizará (existen
tres opciones: autentificación basada en cookies, basada en http o inclusión en el
fichero de configuración de los datos de usuario).

15.2. ENTRADA A PHPMYADMIN


La forma de comenzar a utilizar phpmyadmin es simple, basta con utilizar el
navegador web para acceder a la página index.php que se encontrará en el
directorio correspondiente del servidor web.

En el caso de tener instalado el servidor web sobre el propio equipo (localhost) que
se utilizará para la administración, se deberá escribir en la barra de direcciones del
navegador:

http://localhost/phpmyadmin/

Para ello es necesario también que el servidor web tenga configuradas las páginas
index.php como páginas de inicio de directorio.

La aplicación dispone de tres métodos de autentificación diferentes basados en


nombres de usuario y contraseñas. El más simple, pero al mismo tiempo más
inseguro, es la escritura del nombre de usuario y la contraseña directamente en el
fichero de configuración. El segundo de los métodos se basa en cookies, y en este

390
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

caso solicita al usuario a través de un formulario de una página web el nombre y


contraseña cada vez que acceda.

Una vez autentificado como usuario registrado, se accede a la página de inicio de


phpmyadmin (véase Figura 15.1).

Figura 15.1 Página de inicio de phpmyadmin

A través de la página de inicio de phpmyadmin se accede de una forma sencilla e


intuitiva a las diferentes opciones disponibles. La página, como puede apreciarse,
está dividida en dos marcos, en el de la izquierda se podrá seleccionar en todo
momento una de las bases de datos que se encuentren disponibles en MySQL. En
el marco de la derecha aparecen una serie de enlaces que permiten realizar las
diferentes operaciones sobre la base de datos activa.

Como podrá comprobarse, todas las opciones disponibles se encuentran bien


documentadas a través de diferentes documentos de ayuda.

391
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

15.3. GESTIÓN DE BASES DE DATOS

15.3.1. CONSULTA DE LAS BASES DE DATOS


Una de las primeras operaciones que se puede realizar en phpmyadmin es la
consulta de las bases de datos disponibles en cada momento. Para ello, en el marco
izquierdo de la ventana aparece una lista desplegable con los nombres de esas
bases de datos; entre paréntesis se indica además el número de tablas de cada una
de ellas, tal como puede apreciarse en la Figura 15.2.

Figura 15.2 Selección de la base de datos activa

Figura 15.3 Estructura de la base de datos de Cinem@s

392
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Una vez seleccionada una base de datos en esta lista, el marco de la derecha de
la ventana mostrará la estructura de dicha base de datos. Por ejemplo, al
seleccionar la base de datos de Cinem@s, la ventana del navegador tendrá el
aspecto que muestra la Figura 15.3.

A través de los enlaces de la parte superior se puede consultar la estructura de la


base de datos (vista por defecto), ejecutar sentencias SQL directamente sobre la
base de datos seleccionada, acceder a diferentes opciones para exportar datos,
realizar consultas de selección (búsquedas) de una forma intuitiva, sin necesidad de
dar el código SQL correspondiente, generar otro tipo de consultas de manera
interactiva y, finalmente, la posibilidad de eliminar completamente la base de datos
activa.

15.3.2. MANIPULACIÓN DE LAS TABLAS


Al analizar la estructura de la base de datos, se puede ver la lista de sus tablas, con
una serie de iconos para ejecutar diferentes acciones. Igualmente se puede obtener
información sobre el número de registros, tipo de tabla y tamaño de cada tabla.

Al pulsar la acción Examinar, se mostrarán todos los registros de la tabla. Por


ejemplo la Figura 15.4 muestra el contenido de la tabla SALAS.

Mediante los enlaces gráficos que aparecen delante de cada registro se podrán
editar sus campos o borrar el registro completamente. Además, pulsando sobre los
nombres de los campos que aparecen en las cabeceras de las columnas se puede
variar el orden en el que se muestran los registros (orden ascendente o descendente
sobre ese campo).

393
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 15.4 Contenido de la tabla SALAS


Por encima de la tabla anterior puede verse también la consulta SQL que el propio
programa ha generado, así como el tiempo empleado en la ejecución de la misma
(véase Figura 15.5). Esta es una interesante característica de phpmyadmin, ya que
al mostrar en todo momento las sentencias SQL su uso tiene también un cierto
grado pedagógico, permitiendo al usuario comprobar el código SQL de las
consultas que genere de manera interactiva.

Figura 15.5 Consulta SQL generad.

La segunda de las posibles acciones a realizar sobre las tablas es la de seleccionar.


Esta opción da acceso a una página en la que es posible generar de manera intuitiva
sencillas consultas de selección (SELECT). Por ejemplo, la Figura 15.6 muestra la
manera de obtener un listado, en orden decreciente de aforo, de los números de sala
y aforos de todas las salas con capacidad mayor o igual a 200. En la Figura 15.7
puede verse el resultado de esta consulta.

394
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Figura 15.6 Consulta de los aforos de las salas

Figura 15.7 Resultado de la consulta de aforos

395
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

De nuevo, además de mostrar los registros, se muestra la sintaxis SQL de la


sentencia SELECT que se ha utilizado para obtenerlos.

La tercera de las opciones de manipulación de tablas es la inserción de nuevos


registros. Al igual que ocurre en los casos anteriores, la inserción se realizará a través
de sencillos formularios que liberarán al usuario de la generación de las
correspondientes sentencias INSERT.

Por ejemplo, si se desea añadir un nuevo registro a la tabla de clientes, se utilizaría


el formulario que se muestra en la Figura 15.8. Por supuesto, los datos introducidos
en los diferentes campos del formulario deben coincidir en tipo con los de los
correspondientes atributos de la tabla, que son mostrados en la segunda columna
del mismo. En la tercera columna del formulario se encuentran a su vez una serie
de listas desplegables que dan acceso a diferentes funciones predefinidas en
MySQL. Por ejemplo, en la inserción se utiliza la función PASSWORD que hace
que el contenido introducido en el correspondiente campo quede almacenado en la
tabla utilizando técnicas de encriptación, de esta manera cualquier operación de
selección posterior no mostraría el valor verdadero de ese atributo.

Figura 15.8 Inserción de un nuevo cliente

En la parte inferior del formulario existen dos botones de opción que permiten
especificar si se desea añadir un nuevo registro o simplemente volver a la
estructura de la base de datos.

396
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Al pulsar el botón Continúe se realizará la inserción del registro y se mostrará


además la sentencia INSERT utilizada para dicha operación (véase Figura 15.9).

Figura 15.9 Sentencia de inserción del nuevo cliente

Puede examinarse la tabla CLIENTES para comprobar que la inserción se realizó


correctamente. Además puede comprobarse cómo el valor que se muestra en el
campo correspondiente a la clave aparece encriptado (véase Figura 15.10).

Figura 15.10 Nuevo registro


En el caso de tablas que contengan campos de texto largo, el formulario de
inserción incluye áreas de texto con barras de desplazamiento para poder introducir
los contenidos. La Figura 15.11 muestra parte del formulario para insertar nuevas
películas.

Figura 15.11 Formulario de inserción de nuevas películas

Además, para el caso de campos de tipo blob, preparados para recibir cualquier
tipo de archivo, el formulario permite directamente examinar el contenido del
equipo y seleccionar el archivo a almacenar en la tabla. Este es el caso del campo
CARTELERA de la tabla de PELICULAS (Figura 15.12).

397
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 15.12 Campo de tipo blob

La siguiente acción que se puede realizar sobre las tablas es la de ver sus
propiedades. En este caso se mostrará la estructura de la tabla, con los nombres y
tipos de sus argumentos, así como cualquier otra propiedad de la misma establecida
en tiempo de diseño (claves primarias, atributos no nulos, valores predeterminados,
índices,...). A través de esta opción no solo es posible consultar las propiedades de
la tabla sino también modificarlas. La próxima sección mostrará detalladamente las
distintas opciones accesibles desde la página de propiedades.

Finalmente, las dos últimas acciones a realizar sobre las tablas son las de eliminar
y vaciar. La eliminación borra la tabla completa (sentencia DROP TABLE),
mientras que el vaciado únicamente borra los registros que contiene la tabla pero la
mantiene vacía en la base de datos (sentencia TRUNCATE).

Al utilizar el enlace gráfico de eliminación aparecerá un cuadro de diálogo que


exige la confirmación de la acción, preguntando si realmente se quiere eliminar
dicha tabla (véase Figura 15.13).

Figura 15.13 Cuadro de confirmación de la acción de borrado

De la misma manera, cuando se realiza la acción de vaciado, se pide confirmación


al usuario.

Cuando se trabaja en MySQL con tablas que soporten la integridad referencial, las
operaciones de eliminación de tabla o de vaciado de registros solo son permitidas
cuando no se estén utilizando en otras tablas vinculadas.

15.3.3. ESTRUCTURA DE LAS TABLAS

A través de phpmyadmin es posible analizar la estructura completa de cada una de


las tablas, comprobando los nombres y tipos de los diferentes atributos,así como

398
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

cualquier otra propiedad que se haya establecido en su diseño. No solo es posible


analizar esa estructura sino también modificarla, cambiando los tipos de los
atributos, eliminando o añadiendo nuevos atributos,...

Para analizar la estructura de una de las tablas se puede pulsar sobre el enlace
correspondiente que aparece en el marco izquierdo de la página principal (Figura
15.14).

Figura 15.14 Lista de tablas de la base de datos

Al hacerlo, se accede a una página similar a la que aparece cuando se consultan las
propiedades de una tabla. En la parte superior de esa misma página aparecen una
serie de enlaces adicionales que permiten realizar todo tipo de acciones sobre la
tabla: examinar sus registros, ejecutar sentencias SQL, generar consultas de
selección, insertar nuevos registros, exportar datos, cambiar el nombre de la tabla,
cambiar su ubicación,... Algunas de estas acciones pueden realizarse también a
través de la página que muestra la estructura completa de la base de datos.
Al seleccionar una tabla, la página muestra por defecto sus propiedades, tal como
se ve en la Figura 15.15, para el caso de la tabla CLIENTES.

Figura 15.15 Propiedades de la tabla CLIENTES

399
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

La relación de campos de la tabla viene acompañada por información sobre sus


respectivos tipos, atributos especiales, posibilidad de admitir valores nulos, valores
predeterminados, uso de funciones especiales y, finalmente, una serie de iconos
que permiten realizar las siguientes acciones sobre cada uno de los atributos:

1. Cambiar el atributo: se pueden modificar su nombre, tipo, valor por


defecto y otros atributos.

2. Eliminar el atributo de la tabla.

3. Establecer dicho atributo como clave primaria de la tabla.

4. Definir un índice sobre ese atributo.

5. Establecer la propiedad de unicidad de valores en el atributo.

Debajo de la relación de campos de la tabla puede verse información sobre los


índices definidos sobre la misma y espacio utilizado por la tabla.

Finalmente, la página incluye algunos enlaces que permiten realizar acciones


interesantes (véase Figura 15.16). El primero de ellos (vista impresión) genera una
página con toda la información de la tabla en un formato más manejable de cara a
su impresión. También es posible incluir nuevas columnas o campos a la tabla y
ejecutar consultas SELECT en formato SQL o a través de un fichero externo. El último
enlace de la página permite introducir datos en la tabla procedentes de un fichero de
texto. En este caso deben establecerse los caracteres delimitadores de los campos y de
los registros.

15.4. CREACIÓN DE NUEVAS BASES DE DATOS


En la sección anterior se ha explicado la forma de consultar y gestionar las bases de
datos existentes en MySQL. Como ejemplo se ha tomado la base de datos de
Cinem@s que en su momento fue creada directamente mediante sentencias SQL a
través del monitor de MySQL. En esta sección se verá cómo con phpmyadmin resulta
sencillo el proceso de creación de una base de datos completa, sin necesidad de tener
ningún conocimiento del lenguaje de definición SQL.

En la página de inicio de phpmyadmin, la primera de las opciones disponibles es


precisamente la de creación de una nueva base de datos (Figura 15.17).

400
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Figura 15.16 Opciones adicionales de manipulación de tablas

Figura 15.17 Opción de creación de una nueva base de datos


En primer lugar debe indicarse el nombre para la nueva base de datos, al pulsar el
botón Crear se accede a una nueva página (Figura 15.18) en la que se crearán las
diferentes tablas. En este caso se está creando una nueva base de datos de nombre
recursos_humanos cuyo objetivo podría ser mantener información sobre los
trabajadores de la empresa Cinem@s, turnos de trabajo, horas extraordinarias,... Al
crear la base de datos, la página muestra también la sentencia SQL correspondiente
e incluye un simple formulario para crear las diferentes tablas de la nueva base de
datos.

15.4.1. CREACIÓN DE TABLAS


La creación de nuevas tablas se realiza a través del formulario que incluye la página de
la Figura 15.18. En primer lugar debe indicarse el nombre de la tabla y el número de
campos que contendrá (estos valores podrán ser modificados posteriormente). Por

401
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ejemplo, a continuación se creará una tabla de nombre empleados y con 7 campos


(Figura 15.19).

Figura 15.18 Creación de nuevas tablas

Figura 15.19 Creación de una tabla con 7 campos

Al formulario de creación de tablas puede accederse también desde la página que


muestra la estructura de una base de datos en el caso de bases de datos ya
existentes.

El siguiente paso, será definir los 7 campos de la tabla; para ello phpmyadmin
muestra un nuevo formulario en el que este proceso se realiza de forma intuitiva
(Figura 15.20). El formulario permite indicar los nombres de los campos, sus tipos,

402
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

longitud, atributos, admisión de valores nulos, valores predeterminados, definición


de claves, índices,... El formulario finaliza con una lista en la que es posible elegir
el tipo de tabla entre los tipos soportados por MySQL.

Figura 15.20 Formulario de definición de campos de la tabla

Al pulsar el botón Grabar del formulario, la tabla se creará y phpmyadmin


mostrará la sentencia SQL que la genera.

Accediendo a la página de la estructura de la base de datos se podrá repetir el


proceso para crear nuevas tablas.

15.5. OPERACIONES DE IMPORTACIÓN Y


EXPORTACIÓN DE DATOS

15.5.1. IMPORTACIÓN DE DATOS EXTERNOS EN LAS


TABLAS
Dada una base de datos con su conjunto de tablas, evidentemente, una de las
operaciones más habituales será la inserción de nuevos registros. Esta operación
puede realizarse de diferentes maneras, por un lado la ejecución directa de las
correspondientes sentencias INSERT, por otro, la utilización de los formularios de
inserción que phpmyadmin genera y que fueron presentados al explicar las
operaciones de manipulación de tablas. Una tercera opción disponible para crear

403
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

nuevos registros es la importación de datos de ficheros externos. Esta opción es


especialmente recomendable cuando se desea importar un gran volumen de
registros en una sola operación.

Supóngase que se dispone de un fichero de texto con el contenido de la Figura


15.21, como puede apreciarse, cada una de las líneas del fichero corresponderá a un
registro de la tabla EMPLEADOS, los valores para cada campo se encuentran
entrecomillados y separados entre sí por comas.

Figura 15.21 Fichero de texto con datos de empleados

Para importar todos esos datos a la tabla de empleados se tendría que pulsar sobre
el enlace Insertar archivo de texto en la tabla que aparece al final de la página que
muestra la estructura de la correspondiente tabla. Al hacerlo se accede al
formulario que muestra la Figura 15.22, en él se debe especificar el fichero fuente
de los datos y los diferentes caracteres que actuarán de separadores de campos y de
registros.

Figura 15.22 Formulario para la importación de datos desde ficheros de texto

404
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Una vez pulsado el botón Enviar, se procederá a la inserción automática de los


correspondientes registros. Tras dicha operación puede examinarse la tabla para
comprobar la correcta inserción de los mismos (Figura 15.23).

Figura 15.23 Contenido de la tabla EMPLEADOS

Si se desea importar datos que se encuentren en una hoja de cálculo,


como por ejemplo Excel, puede utilizarse la opción de exportar a un
NOTA fichero de texto los datos de la hoja, para posteriormente importarlos
desde MySQL utilizando phpmyadmin.

15.5.2. EXPORTACIÓN DE DATOS


Cuando se desea utilizar los datos almacenados en MySQL por otras aplicaciones,
o incluso por otros sistemas gestores de bases de datos, se pueden utilizar las
opciones de exportación que incorpora phpmyadmin.

Existen dos posibilidades de exportación:

— Exportar la base de datos completa.

— Exportar tablas individuales.

Para exportar una base de datos debe activarse el enlace Exportar que aparece en la
página de inicio de phpmyadmin. Al hacerlo se accede a una nueva página en la
que en primer lugar habría que seleccionar la o las bases de datos que se desean
exportar y el formato de exportación (Figura 15.24).

Existen cuatro formatos de exportación:

405
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— SQL: se generaría un documento de texto con todas las sentencias SQL


necesarias para crear la estructura de la base de datos y añadir todos sus
registros. Este documento podría ser ejecutado en otro sistema gestor de bases
de datos basado en SQL para reproducir exactamente la base de datos
exportada. Este formato de exportación incorpora una serie de opciones para
indicar si se desea utilizar las sentencias DROP antes de la creación.

— LaTeX: en este caso se generaría un documento con el código necesario para


visualizar las tablas de la base de datos en el formato LaTeX. LaTeX es un
editor de texto muy utilizado en el ámbito científico y para la edición de
publicaciones.

— CSV para Excel: se generaría un fichero de texto con los contenidos de las
tablas de la base de datos en formato CSV (valores separados por comas). Este
formato puede ser leído directamente por Excel para mostrar los contenidos de
las tablas en una hoja de cálculo.

— Datos CSV: exporta los datos de las tablas a formato CSV, pero en este caso se
permite que el usuario elija los caracteres delimitadores de campo y de registro,
los caracteres de fin de línea y los valores a utilizar para reemplazar los valores
nulos.

Figura 15.24 Exportación de bases de datos

Cualquiera que sea el formato de exportación elegido, la página de exportación


permite finalmente indicar si el resultado se desea visualizar directamente en el
navegador o enviar a un archivo. En el caso de que se opte por esta última opción,

406
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

se debe indicar el nombre del archivo a crear e incluso es posible especificar si se


desea que sea comprimido utilizando el formato ZIP o GZIP (Figura 15.25).

Figura 15.25 Opciones de envío a archivo

La exportación de una única tabla de la base de datos es una operación muy


similar. Se accede a ella seleccionado la tabla a exportar en el enlace
correspondiente del marco izquierdo de la página y posteriormente activando el
enlace Exportar de la parte superior del marco derecho. La página a la que se
accede es prácticamente igual a la del caso anterior, pero con dos diferencias:

— Existe un nuevo formato de exportación exclusivo para tablas: el formato


XML.

— La segunda diferencia es la posibilidad de elegir el número de registros que se


desean exportar y el registro a partir del cual se inicia la exportación.

15.6. GESTIÓN DE USUARIOS

15.6.1. USUARIOS Y PRIVILEGIOS


Todos los usuarios registrados en MySQL se encuentran almacenados en la tabla
user de la base de datos mysql. Por supuesto, el contenido de dicha tabla puede ser
visualizado desde phpmyadmin como el de cualquier otra tabla, bastaría seleccionar
la base de datos mysql en el marco izquierdo y examinar la tabla user.

En dicha tabla se almacena el nombre de usuario, su contraseña, servidor desde el


que se conecta y los privilegios globales que tendrá sobre las bases de datos de
MySQL. Cuando un usuario tiene permisos específicos sobre una base de datos

407
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

concreta, una tabla, o incluso una sola columna de una tabla, estos privilegios
quedan reflejados en sendos registros de las tablas: db, tables_priv y columns_priv.

Existe otra manera de consultar desde phpmyadmin los usuarios registrados.


Además, con esta opción resulta muy simple la creación de nuevos usuarios y la
asignación de privilegios.

En la página de inicio de phpmyadmin se encuentra el enlace Privilegios, que da


acceso a la página que puede verse en la Figura 15.26. En esta página se muestran
todos los usuarios registrados en MySQL y los privilegios globales de cada uno de
ellos. En el caso que se muestra existe un único usuario (el usuario root que se crea
por defecto al instalar MySQL) que tiene además todos los privilegios globales,
esto quiere decir que este usuario podrá realizar cualquier tipo de acción sobre
cualquier tabla de cualquier base de datos.

Por debajo de la información de usuarios se encuentra un enlace que permitirá


agregar nuevos usuarios.

Figura 15.26 Página de gestión de usuarios

15.6.2. CREACIÓN DE USUARIOS


Para crear un nuevo usuario se puede insertar directamente un nuevo registro en la
tabla user o utilizar la opción anterior (enlace Agregar nuevo usuario de la página
de Privilegios). Esta última alternativa permite definir privilegios específicos de
una manera simple.

408
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Por ejemplo, supóngase que se desea crear un usuario de nombre cinemasadmin


que tenga todo tipo de privilegios sobre la base de datos cinemas, pero no sobre las
restantes bases de datos disponibles. Al pulsar sobre el enlace Agregar nuevo
usuario, se accede al formulario mostrado en la Figura 15.27. En este formulario
debe indicarse el nombre, servidor desde el que puede conectarse y contraseña,
además de señalar los privilegios globales que tendrá. Estos privilegios globales se
referirán a todas las bases de datos de MySQL; en este caso, el usuario
cinemasadmin no tendrá ningún privilegio global.

Figura 15.27 Inserción de un nuevo usuario

Al pulsar el botón Continúe, se accede a una nueva página en la que se podrá


especificar privilegios específicos (Figura 15.28).

409
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 15.28 Definición de privilegios específicos para el usuario

Lo primera será indicar sobre qué base de datos el usuario tendrá privilegios
específicos, para ello en la página aparece una lista con todas las bases de datos
disponibles. Al elegir la base de datos cinemas o escribir su nombre en el campo
que acompaña a la lista y pulsar Continúe, se accederá a una nueva página (Figura
15.29). En esta nueva página se pueden señalar los privilegios específicos sobre la
base de datos cinemas; como puede apreciarse se han señalado todos los
privilegios. Una vez señalados, bastaría pulsar el botón Continúe para que esos
privilegios queden registrados.

Figura 15.29 Definición de privilegios

Como puede apreciarse en la Figura 15.29, es posible incluso especificar


privilegios específicos para tablas concretas. Por ejemplo, supóngase que Cinem@s
quiere generar un nuevo usuario cuya labor sea el mantenimiento de la tabla de
películas, pero no se desea que tenga acceso a ninguna otra tabla. El proceso de
creación de este nuevo usuario se describe a continuación.

410
PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

Lo primero será crear el nuevo usuario sin asignarle ningún privilegio global. El
proceso es idéntico al realizado con el usuario anterior. A continuación, de nuevo,
se señalará que se desea definir privilegios específicos para la base de datos
cinemas, en el formulario correspondiente, no se señalará ningún privilegio
específico para la base de datos y se indicará la tabla sobre la que sí se desean
definir privilegios, tal como puede verse en la Figura 15.30.

Figura 15.30 Asignación de privilegios específicos sobre una tabla

Tras señalar la tabla PELICULAS, se accede a una nueva página (Figura 15.31) en
la que es posible indicar las acciones que el usuario podrá realizar sobre las
diferentes tablas e incluso sobre los diferentes campos de cada tabla. En el caso
anterior se está indicando que el usuario podrá efectuar operaciones de selección,
inserción, actualización y borrado sobre todos los campos de la tabla de películas.
Pulsando el botón Continúe estos privilegios quedarán registrados en la base de
datos mysql.

411
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 15.31 Definición de las acciones permitidas sobre la tabla

Para que todos los cambios realizados sobre los usuarios tengan efecto
sobre MySQL, suele ser conveniente reiniciar el servidor de MySQL. Para
NOTA realizar esta acción, en la página de inicio de phpmyadmin hay un enlace:
Reinicio de MySQL.

Tras todos los procesos realizados, en la tabla user de la base de datos mysql habrá
dos nuevos registros correspondientes a los dos nuevos usuarios; en la tabla db
aparecerá un nuevo registro en el que se indica que el usuario cinemasadmin tiene
todos los privilegios sobre la base de datos cinemas; y finalmente, en la tables_priv
habrá un nuevo registro en el que se indican los privilegios del usuario
películas_op sobre la tabla películas de la base de datos cinemas.

412
CONECTIVIDAD A
BASES DE DATOS
MYSQL DESDE PHP

16.1. INTRODUCCIÓN
El elemento esencial en todo proceso de generación de páginas web dinámicas es la
conectividad con aplicaciones de gestión de bases de datos. Muchas de las páginas
que se pueden encontrar en Internet se generan como resultado de una consulta a
una base de datos. En estos casos es preciso utilizar el lenguaje de consulta de las
bases de datos relacionales (SQL) embebido dentro de un lenguaje de
programación que permita generar esas páginas. En este capítulo se mostrará cómo
es posible realizar este proceso usando el lenguaje PHP y cómo la conectividad a
bases de datos en MySQL se caracteriza por su sencillez y efectividad.

Al igual que en los capítulos precedentes, el objetivo no será una mera descripción
de las diferentes funciones de conexión y de sus sintaxis; más bien se tratará de
mostrar su funcionamiento a través de sencillos ejemplos tomando como referencia
el sitio web Cinem@s que se viene desarrollando a lo largo del libro. Usando PHP

413
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

resultará muy sencillo, por ejemplo, generar la cartelera de películas del día
interrogando a la base de datos y generando una página dinámica.
Aunque este capítulo se centra en la conectividad a bases de datos MySQL, desde
PHP es posible comunicarse con la mayoría de aplicaciones gestoras de bases de
datos (Oracle, Informix, SQL Server, dBase, Ingres,...) de una forma similar a la
que se utilizará con MySQL.

En PHP las funciones de conectividad son específicas del gestor de bases de datos al
que se realiza la conexión. Así por ejemplo, para abrir una conexión con una base de
datos MySQL se utiliza la función mysql_connect() mientras que si se desea
abrir la conexión con una base de datos Oracle debe utilizarse la función
Ora_Open(). Los nombres de todas las funciones PHP relativas a conectividad a
bases de datos comienzan por un prefijo identificativo del gestor al que se dirigen.
Por ejemplo, los nombres de las funciones de conexión a algunos de los gestores de
bases de datos más conocidos siguen los siguientes patrones:
— Funciones de conectividad con MySQL: mysql_nombrefuncion
— Funciones de conectividad con Oracle: Ora_nombrefuncion
— Funciones de conectividad con Informix: ifx_nombrefuncion
— Funciones de conectividad con dBase: dbase_nombrefuncion
— Funciones de conectividad con Ingres: ingres_nombrefuncion

16.2. CONEXIÓN CON MYSQL DESDE PHP

16.2.1. APERTURA DE LA CONEXIÓN


El primer paso para conseguir acceder a los datos de una base de datos MySQL es
establecer la conexión con el servidor de bases de datos. Desde PHP esta conexión
se realiza con la función:

mysql_connect(servidor,usuario,contraseña)

Los tres parámetros anteriores permiten identificar el servidor sobre el que está
instalado MySQL, y el nombre de usuario y contraseña necesarios para conectarse.
Por supuesto, estos dos últimos datos deben coincidir con los de un usuario
registrado en MySQL.

414
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Cuando el servidor MySQL y el servidor web se encuentran en el mismo equipo la


identificación del servidor para realizar la conexión es localhost; en este caso
además, este parámetro sería opcional en la función mysql_connect(), ya que
precisamente el valor por defecto es localhost.

La función mysql_connect() devuelve un valor entero que se utilizará como


identificador de la conexión en las operaciones posteriores. Si se produce un error
en la conexión, el valor devuelto por la función será 0.

16.2.2. CIERRE DE LA CONEXIÓN


La conexión realizada se cierra automáticamente al terminar la ejecución del script
en el que se ha establecido, o bien explícitamente con la función
mysql_close(). Esta función recibe como único argumento el identificador de
la conexión:

mysql_close(identificador)

El identificador de la conexión en la función mysql_close() es opcional, en


caso de que no se indique se cerrará la última conexión abierta.

La función mysql_close() devuelve un valor entero que será nulo en el caso


de que se produzca algún error en el proceso.

De esta manera, el esquema general de un programa que realiza conectividad con


MySQL sería:

$c = mysql_connect("localhost", "root", "miclave");


if (!$c) {
die("Lo siento, error en la conexión");
}
else {
print("Conexión establecida correctamente");
}
...............
...............
...............
mysql_close($c);

Como puede apreciarse, en primer lugar se realiza la conexión con el servidor local
y utilizando como nombre de usuario root y contraseña miclave. Se asigna el
identificador de la conexión a la variable $c, y se comprueba si su valor es distinto

415
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

de cero. Si la variable $c toma el valor nulo se deberá a un error de conexión, por


tanto se utiliza la función die() para mostrar el correspondiente aviso de error y
abortar la ejecución del resto del programa. Si la conexión se estableció
satisfactoriamente, se mostrará un mensaje, se realizarán las operaciones deseadas
sobre la base de datos y, finalmente, se cerrará la conexión.

En el caso de no utilizar la función mysql_close(), cualquier conexión


realizada con mysql_connect() se cerrará automáticamente al finalizar la
ejecución del script. No obstante, si se desea que la conexión permanezca abierta
para ser utilizada en programas de otras páginas que se ejecuten posteriormente,
puede utilizarse una función alternativa para la apertura:

mysql_pconnect(servidor,usuario,contraseña)

La sintaxis de esta función es idéntica a la de la función mysql_connect().


Este tipo de conexiones que no se cierran automáticamente se denominan
conexiones persistentes.

El cierre de las conexiones persistentes debe realizarse con una función especial:

mysql_pclose(identificador)

16.3. SELECCIÓN DE LA BASE DE DATOS


Una vez abierta la conexión con el servidor MySQL, el siguiente paso será la
selección de una de las bases de datos disponibles para la realización de las
operaciones posteriores sobre ella. La función que permite seleccionar una base de
datos es:

mysql_select_db(nombreBD, identificador)

El primer parámetro será el nombre de la base de datos a seleccionar y el segundo


el identificador de la conexión. Este segundo parámetro es opcional, en caso de no
indicarse, se considerará la última conexión realizada.

De nuevo, como en todas las funciones de conexión, si se produce un error, por


ejemplo, porque la base de datos no existe, la función mysql_select_db()
devolverá el valor 0. El valor devuelto por la función puede utilizarse en
estructuras condicionales para asegurar que las operaciones posteriores se realizan
únicamente si la selección ha sido exitosa.

416
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Ejemplo 16.1:
La siguiente estructura aborta el programa si no se puede seleccionar la base de
datos cinemas:

$c = mysql_connect("localhost","root","miclave");
$bd = mysql_select_db("cinemas",$c);
if(!$c) {
die("Base de datos no existente");
}

Una vez seleccionada la base de datos, esta pasa a ser la base de datos activa, y
cualquier operación posterior se dirigirá a ella. En cualquier momento, mientras la
conexión permanezca abierta, puede cambiarse la selección de la base de datos
activa con una nueva llamada a la función mysql_select_db().

Si en lugar de trabajar con una de las bases de datos existentes se desea


crear una nueva desde un programa PHP, se debe utilizar previamente la
función mysql_create_db(nombreBD, identificador) para crearla.
NOTA Posteriormente, y una vez seleccionada como base de datos actual, deberán
ejecutarse las correspondientes sentencias de creación de tablas.

16.4. EJECUCIÓN DE SENTENCIAS SQL SOBRE


LA BASE DE DATOS SELECCIONADA

La función mysql_query() permite ejecutar cualquier sentencia SQL sobre la


base de datos activa. Esta función admite dos argumentos, el primero es una cadena
de caracteres con el código SQL de la consulta a realizar; el segundo argumento
será el identificador de la conexión. Este segundo argumento es opcional y, de
nuevo, en caso de no indicarse se asume la última conexión establecida.

mysql_query(sentencia, identificador)

Esta función devuelve 0 si se produce algún error o un número entero positivo en


caso de ejecución correcta. En las sentencias de selección, este valor devuelto se
utilizará posteriormente para acceder al resultado de la consulta. En el caso de
sentencias de creación, inserción, eliminación o actualización, este valor devuelto
únicamente sirve para comprobar si la sentencia se ejecutó correctamente.

417
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Existe otra función similar que permite ejecutar sentencias sobre cualquier base de
datos, en este caso debe indicarse además de la sentencia y el identificador de
conexión, el nombre de la base de datos a la que se dirige la consulta:

mysql_db_query(nombreBD, sentencia, identificador)

Ejemplo 16.2:
Supóngase que se desea añadir un nuevo atributo a la tabla clientes de la base de
datos cinemas para guardar el NIF de cada cliente. Esta sencilla modificación
podría realizarse desde un programa PHP como el siguiente:

$c = mysql_connect("localhost","root","miclave");
if(!$c) {
die("Conexión fallida");
}
$ok = mysql_select_db("cinemas",$c);
if(!$ok) {
die("Error en la selección de la base de datos");
}
$consulta =
"ALTER TABLE clientes ADD NIF VARCHAR(9) NOT NULL";
$resultado = mysql_query($consulta,$c);
if($resultado) {
print("Tabla actualizada");
} else {
print("No se ha podido actualizar la tabla");
}
mysql_close($c);

En este ejemplo puede apreciarse la sencillez para la integración de sentencias SQL


dentro de un programa PHP: basta con definirlas como una cadena de caracteres
que será enviada al servidor de MySQL mediante la función mysql_query().

Las condiciones iniciales de comprobación de la conexión y selección de la base de


datos podrían escribirse de una forma más compacta utilizando el operador lógico
or:

$c = mysql_connect("localhost","root","miclave")
or die("Conexión fallida: " . mysql_error());

mysql_select_db("cinemas",$c)
or die("Error en la selección: " . mysql_error());

$consulta =

418
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

"ALTER TABLE clientes ADD NIF VARCHAR(9) NOT NULL";


if(mysql_query($consulta,$c)) {
print("Tabla actualizada");
} else {
print("Error: " . mysql_error());
}
mysql_close($c);

En este caso, cuando se desea realizar la asignación del identificador de conexión,


si la conexión se realiza satisfactoriamente, el funcionamiento del operador or
hace que no se evalúe su segundo argumento. Sin embargo, si la conexión no se
puede establecer, ese segundo argumento del operador lógico será evaluado, y por
tanto, se abortará el programa.

Además, en esta segunda versión se utiliza la función mysql_error() que


devuelve una cadena de caracteres explicando el último error producido en la
operación de acceso a datos.

16.4.1. INSERCIÓN DE DATOS A TRAVÉS DE


FORMULARIOS
El Ejemplo 16.2 ha mostrado la sencillez de la ejecución de una sentencia SQL
desde PHP; sin embargo, ha tenido un mero carácter pedagógico, ya que la
modificación de la estructura de la tabla se podría haber realizado de una manera
más rápida y sencilla directamente desde el monitor de MySQL o desde la
herramienta de administración phpmyadmin. La verdadera utilidad de las funciones
de conectividad a bases de datos desde PHP radica en la posibilidad de construir
sentencias SQL de manera dinámica en el propio programa. Por ejemplo, generar
una consulta de inserción a partir de los datos que el usuario introduzca en un
formulario. Esto es lo que se tratará de presentar paso a paso a continuación,
tomando como referencia el formulario de inserción de nuevos clientes registrados
en Cinem@s que ya fue presentado en el Capítulo 3. El aspecto de la página que
incluye este formulario es el que se muestra en la Figura 16.1.

Implementación del "Área de clientes"


El formulario de registro de clientes de la Figura 16.1 solicita al usuario que
introduzca los datos necesarios para crear un nuevo registro en la base de datos,
esos datos serán remitidos a un programa PHP para su procesamiento.

419
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El código completo que define este formulario es el siguiente:

Fichero clientes.html:

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


<TABLE>
<TR>
<TD>Nombre (*):</TD>
<TD><INPUT TYPE=text size="40" name="nombre"></TD>
</TR>
<TR>
<TD>Dirección:</TD>
<TD><INPUT TYPE=text size="50" name="direccion"></TD>
</TR>
<TR>
<TD>NIF (*):</TD>
<TD><INPUT TYPE=text size="9" name="nif"></TD>
</TR>
<TR>
<TD>Fecha de Nacimiento:</TD>
<TD>día <INPUT TYPE=text size="2" name="dianac">
mes <INPUT TYPE=text size="2" name="mesnac">
año <INPUT TYPE=text size="4" name="annonac">
</TD>
</TR>
<TR>
<TD>Teléfono:</TD>
<TD><INPUT TYPE=text size="20" name="telefono"></TD>
</TR>
<TR>
<TD>Email:</TD>
<TD><INPUT TYPE=text size="30" name="email"></TD>
</TR>
</TABLE>
Contraseña (*):
<INPUT TYPE=password size="6" name="pass1">
Repita su contraseña:
<INPUT TYPE=password size="6" name="pass2">
<BR>
<FONT SIZE=-1> (*) campos obligatorios</FONT>
<BR>
<INPUT TYPE=submit value=Enviar>
<INPUT TYPE=reset value=Borrar>
</FORM>

420
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Figura 16.1 Página de registro de nuevos clientes

Cuando el usuario pulse el botón Enviar, los datos introducidos por este llegarán al
fichero nuevocliente.php a través de variables del mismo nombre que el de los
campos correspondientes. Se asume que esos valores han sido validados en el cliente
antes de ser remitidos al servidor (por ejemplo, mediante un script en JavaScript). A
partir de los valores recibidos el programa PHP debe generar la correspondiente
sentencia INSERT que se dirigirá a la base de datos cinemas.

Las operaciones de manipulación de datos requerirán conectarse al servidor


MySQL mediante un usuario registrado. Para facilitar el desarrollo y el
mantenimiento de todos los programas que realicen esas conexiones, los datos de

421
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

configuración (servidor, nombre de usuario, contraseña y base de datos a utilizar)


pueden ser guardados en un fichero auxiliar que será llamado desde cualquier
programa que necesite realizar la conexión.

A lo largo de este capítulo se utilizará un usuario cinemasadmin con privilegios


completos sobre la base de datos cinemas. En el Capítulo 15 se explicó el proceso de
creación de este usuario. Los datos de este usuario serán guardados en un fichero de
nombre configuracion.inc cuyo contenido se muestra a continuación:

Fichero configuración.inc:

<?
$host = "localhost";
$usuario = "cinemasadmin";
$password = "miclave";
$db = "cinemas";
?>

En cualquier otra página del sitio en la que se requiera hacer uso de esas variables
de configuración, bastaría incluir la sentencia:

require('configuracion.inc');

Cualquier modificación futura de los datos de usuario requerirá únicamente la


actualización de este fichero de configuración, sin necesidad de modificar el resto
de ficheros que compongan la aplicación web.

El código completo del fichero nuevocliente.php con el que se insertarían en la


base de datos los nuevos clientes registrados sería:

Fichero nuevocliente.php:

<HTML>
<HEAD>
<TITLE>Registro de nuevo cliente</TITLE>
</HEAD>
<BODY>
<?php
// comprobación de la recepción de las variables
if (isset($nombre,$nif,$pass1)) {
// carga de las variables de configuración
// y realización de la conexión
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());

422
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

mysql_select_db($db,$c)
or die("Error: " . mysql_error());

// generación de la consulta SQL a partir de las


// variables del formulario
$fecha = "$annonac-$mesnac-$dianac";
$consulta = "INSERT INTO
clientes(NOMBRE,NIF,DIRECCION,
FECHANAC,TELEF,
EMAIL,CLAVE)
VALUES('$nombre','$nif','$direccion',
'$fecha','$telefono','$email',
'$pass1')";
// ejecución de la consulta
if(mysql_query($consulta,$c)) {
$numcliente = mysql_insert_id();
print("<CENTER><H2>$nombre, muchas gracias
por registrarte en Cinem@s.</H2>");
if ($email!="") {
$mens = "Bienvenido a Cinem@s.\n Al ser " .
"cliente registrado de nuestra " .
"empresa te podrás beneficiar de " .
"grandes ventajas.\n Para acceder " .
"a tu página personal necesitarás " .
"tu número de cliente ($numcliente) " .
"y tu clave ($pass1).";
mail($email,"Registro en Cinem@s",$mens);
}
print("Tu número de cliente es: <B> $numcliente
</B><BR> Necesitarás este número y tu
contraseña para entrar a tu página
personal.<BR>. Hemos enviado un email a tu
dirección de correo electrónico
informándote
de tus datos de acceso </CENTER>");
} else {
print("Fallo en el registro: " . mysql_error());
}
// cierre de la conexión
mysql_close($c);
}
?>
</BODY>
</HTML>

La sintaxis SQL de la sentencia INSERT obliga a dar entrecomillados los


diferentes valores para los campos; en este caso se utilizan las comillas simples

423
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

dentro de la cadena definida con comillas dobles. En la generación de la consulta


se puede apreciar la utilidad de la opción de expandir variables dentro de las
cadenas en PHP.

En el programa anterior se utiliza la función mysql_insert_id() para obtener


el valor del campo clave del último registro insertado en el caso de que ese atributo
haya sido definido como autonumérico (AUTO_INCREMENT).

Igualmente se utiliza la función mail() para el envío de un mensaje de correo


electrónico. Los argumentos mínimos de esta función son, por este orden, la
dirección de correo electrónico del destinatario, el asunto del mensaje y el cuerpo
del mensaje.

El correcto funcionamiento de la función mail() exige que el servidor


NOTA
tenga instalada y correctamente configurada una aplicación servidor de
correo electrónico.

16.4.2. RECUPERACIÓN DE LOS RESULTADOS DE LAS


CONSULTAS
Determinadas consultas de SQL, como las de inserción, borrado o actualización,
realizan acciones sobre los datos de la base de datos pero no devuelven ninguna
información, simplemente realizan esa acción. En cambio, las consultas de
selección (SELECT) deben devolver un conjunto de registros como consecuencia
de su realización. La ejecución de la sentencia de selección se realiza, como con
cualquier otra sentencia, mediante la función mysql_query(); una vez
ejecutada, el resultado se almacena en una zona de la memoria mediante un tipo
especial de estructura de datos conocida como recurso y que en PHP se utiliza para
referenciar ciertos recursos externos. Para identificar esa zona de memoria y poder
acceder a los datos se debe utilizar el valor entero que devuelve la función
mysql_query().

Para acceder a los resultados de la consulta puede utilizarse la función:

mysql_fetch_row(resultado)

424
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Cada vez que se produce la llamada a esta función se genera un array con los
valores de una de las filas de la tabla de resultados. Mediante un bucle de llamadas
sucesivas se podrán recorrer todas las filas que constituyen el resultado. Cuando no
hay más filas por leer, la función devuelve un valor nulo que puede ser utilizado
como indicador de finalización del bucle.

También es posible saber cuántas filas o registros incluye el resultado de la


consulta. Para ello se puede utilizar la función:

mysql_num_rows(resultado)

Esta función devuelve una valor entero indicando el número de filas del resultado.

El valor del argumento en ambas funciones es el entero devuelto por la función


mysql_query() para identificar al recurso resultado.

Relacionada con esta última función está la función

mysql_affected_rows()

que devuelve el número de registros que se han visto afectados por la última
consulta realizada de inserción, actualización o borrado.

Como primer ejemplo de ejecución de sentencias de selección desde programas


PHP se presenta a continuación la implementación del acceso a la página personal
de los clientes de Cinem@s. Como punto de partida se toma el formulario que se
incluye en la página de clientes compuesto de sendos campos de texto para solicitar
el número de cliente y la contraseña de acceso. El código HTML de este formulario
es:

<FORM ACTION=accesocliente.php METHOD=POST>


Número de cliente:
<INPUT TYPE=text SIZE="5" NAME="numcliente"><BR>
Contraseña:
<INPUT TYPE=password SIZE="6" NAME="pass"><BR>
<INPUT TYPE=submit VALUE=Entrar>
</FORM>

El archivo accesocliente.php es el encargado de recibir los datos de autentificación


del cliente y con ellos realizará una búsqueda del registro correspondiente,
comprobará la validez de la contraseña aportada y, en su caso, generará la página
mostrando toda la información del cliente. El código completo se incluye a
continuación:

425
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Fichero accesocliente.php:

<HTML>
<HEAD><TITLE>Página personal</TITLE></HEAD>
<BODY>
<TABLE WIDTH="100%" BORDER BGCOLOR=#99CCFF>
<TR>
<TH WIDTH="16%">
<A HREF="principal.htm">Página principal</A></TH>
<TH WIDTH="17%">
<A HREF="proyecciones.htm">Nuestra cartelera</A></TH>
<TH WIDTH="17%">
<A HREF="salas.htm">Nuestras salas</A></TH>
<TH WIDTH="17%">
<A HREF="entradas.htm">Compra de entradas</A></TH>
<TH WIDTH="17%">
<A HREF="estrenos.htm">Próximos estrenos</A></TH>
<TH WIDTH="16%">
<A HREF="foros/index.php">Foro Cinem@s</A></TH>
</TR>
</TABLE>
<BR>

<?php
// comprobación de la recepción de las variables
if (isset($numcliente,$pass)) {
// carga de las variables de configuración
// y realización de la conexión
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// comprobación de petición de modificación de datos
if(isset($modificar)) {
// generación de la consulta de actualización
$consulta = "UPDATE CLIENTES SET
NOMBRE = '$nombre',
NIF = '$nif',
DIRECCION = '$direccion',
FECHANAC = '$fecha',
TELEF = '$telefono',
EMAIL = '$email',
CLAVE = '$pass'
WHERE NUM_CLIENTE = $numcliente";
// ejecución de la consulta
$resultado = mysql_query($consulta,$c);

426
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

if ($resultado)
print "<CENTER><I>
Datos actualizados</I></CENTER>";
}
// generación de la consulta de selección a partir
// de las variables del formulario
$consulta = "SELECT * FROM CLIENTES WHERE
NUM_CLIENTE=$numcliente";
// ejecución de la consulta
$resultado = mysql_query($consulta,$c);
// comprobación existencia de algún registro
resultado
if(mysql_num_rows($resultado)) {
// se recupera el registro resultado en un array
$registro = mysql_fetch_row($resultado);
// obtención del password real del cliente en la
BD
//(octavo campo del registro: índice 7)
$passwordreal = $registro[7];
// comprobación de la validez del password
if ($pass == $passwordreal) {
mostrarpagina($registro);
}
else {
// denegar acceso
print "<H2 ALIGN=center>
Contraseña incorrecta</H2>";
}
} else {
// ningún registro coincide con el número de
cliente
print("<H2 ALIGN=center>
Error en la identificación</H2>");
}
// cierre de la conexión
mysql_close($c);
}
?>

<?php
// función que genera la página personal
function mostrarpagina($datos) {
print "<H2 ALIGN=center> Página de $datos[1] </H2>";
print "<CENTER>";
print "<FORM ACTION=accesocliente.php METHOD=post>";
print "<TABLE WIDTH=80% BORDER BGCOLOR=#99CCFF>
<TR>

427
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<TH BGCOLOR=blue>Número de cliente</TH>


<TD> $datos[0] </TD>
</TR>
<TR>
<TH BGCOLOR=blue>Nombre</TH>
<TD>
<INPUT TYPE=text SIZE=40 NAME=nombre
VALUE='$datos[1]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>Dirección</TH>
<TD>
<INPUT TYPE=text SIZE=50 NAME=direccion
VALUE='$datos[2]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>Fecha de nacimiento</TH>
<TD>
<INPUT TYPE=text SIZE=10 NAME=fecha
VALUE='$datos[3]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>Teléfono</TH>
<TD>
<INPUT TYPE=text SIZE=9 NAME=telefono
VALUE='$datos[4]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>email</TH>
<TD>
<INPUT TYPE=text SIZE=30 NAME=email
VALUE='$datos[5]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>clave</TH>
<TD>
<INPUT TYPE=password SIZE=6 NAME=pass
VALUE='$datos[7]'>
</TD>
</TR>
<TR>
<TH BGCOLOR=blue>NIF</TH>

428
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

<TD>
<INPUT TYPE=text SIZE=9 NAME=nif
VALUE='$datos[8]'>
</TD>
</TR>
</TABLE>";
print "<INPUT TYPE=hidden NAME=modificar VALUE=1>
<INPUT TYPE=hidden NAME=numcliente
VALUE=$datos[0]>
<BR><INPUT TYPE=submit VALUE=Actualizar>
</FORM>";
print "<H3 ALIGN=center> A fecha de hoy tienes un total
de $datos[6] puntos acumulados </H3>";
print "</CENTER><BR>";
}
?>

<HR>
<A HREF="clientes.htm">Volver al área de clientes</A>
</BODY>
</HTML>

Este archivo comienza con el código HTML que genera una pequeña barra de
navegación en la página para que el usuario pueda desplazarse a otras páginas del
sitio web. Tras este código HTML aparece el programa PHP encargado de la
generación del contenido de la página personal. Este programa comienza
comprobando si se han recibido las variables correspondientes al número de cliente
y clave de acceso desde el formulario previo.

La página ha sido diseñada para que permita también actualizar los datos del
cliente, de manera que se utilizará una variable $modificar que tomará el valor
1 cuando se acceda a la página después de una petición de actualización de datos.
En el caso de acceder directamente desde el formulario del área de clientes, esta
variable no estará definida.

Cuando se acceda en modo actualización, a la página accesocliente.php se habrá


llegado después de una carga previa de la propia página y usando un formulario
que se encuentra en la página y que es construido más adelante en el propio
programa PHP. Ese formulario enviará los valores de los nuevos atributos del
cliente, con esos valores se genera y ejecuta la correspondiente sentencia UPDATE.

Posteriormente, se encuentra el código que genera el contenido de la página que


será visible por el cliente. Se comprueba la correcta autentificación del cliente
mediante la comparación de la clave aportada y la clave real almacenada, y en caso

429
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

de coincidencia se llama a una función mostrarpagina(). Esta función se


encuentra definida en un script posterior de la página y genera una tabla en la que
se muestran, utilizando campos de formulario, los valores de los atributos del
cliente. Estos campos de formulario tendrán una doble funcionalidad: mostrar los
valores actuales y permitir las actualizaciones.

El aspecto final de la página personal del cliente que es generada con este
programa es el que puede verse en la Figura 16.2.

Figura 16.2 Página personal de un cliente

En el programa anterior se ha utilizado la función mysql_fetch_row() para


recuperar en un array el resultado de la consulta de selección. Posteriormente, para
acceder a los diferentes campos del registro se necesitó saber el orden en el que

430
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

dichos campos se encuentran en la tabla de la base de datos, ya que el primer


campo corresponde con el valor de índice 0 en el array, el segundo con el índice 1,
y así sucesivamente. En algunas ocasiones esto puede resultar un tanto engorroso y
puede provocar errores en la codificación de los programas; por esa razón, PHP
dispone de otra función que puede facilitar el tratamiento de los resultados de las
consultas:

mysql_fetch_array(resultado)

mysql_fetch_array(resultado, tipo_asociación)

Esta función tiene un funcionamiento similar a mysql_fetch_row(), es decir,


en cada llamada genera un array con los datos correspondientes a uno de los
registros del resultado. Se pueden ir repitiendo las llamadas de forma sucesiva para
recuperar todos los registros obtenidos en la consulta.

La principal ventaja de la función mysql_fetch_array()es que permite


recuperar los datos en arrays asociativos en los que en lugar de utilizar índices
numéricos se pueden utilizar los propios nombres de los campos de la tabla como
llaves índices del array.

El segundo argumento de mysql_fetch_array() es opcional y puede tomar


uno de los valores siguientes:

— MYSQL_ASSOC el registro se carga en un array al que se accede


únicamente mediante palabras clave (los campos
de la tabla).
— MYSQL_NUM el registro se carga en un array al que se accede
únicamente usando índices numéricos, tal como
ocurre con la función mysql_fetch_row().
— MYSQL_BOTH (opción por defecto) ambos métodos de acceso a
los elementos del array son posibles.

Al igual que mysql_fetch_row()permite un acceso únicamente con índices


numéricos, existe en PHP una nueva función, de sintaxis similar, que permite un
acceso únicamente mediante palabras clave, dicha función es:

mysql_fetch_assoc(resultado)

En definitiva, de las tres funciones comentadas de recuperación de datos, la más


general, y la que resulta más recomendable, es mysql_fetch_array() ya que
permite utilizar los dos tipos de mecanismos de acceso a los elementos del array.

431
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Además, debe destacarse que no se aprecian diferencias significativas con las otras
dos funciones en cuanto a tiempo de ejecución.

Implementación de la página de características de las salas


A modo de ejemplo de uso de la función mysql_fetch_array()para
recuperar los registros en arrays asociativos se comenta a continuación la
implementación de un sencillo programa que muestra en una página web todos los
registros correspondientes a la tabla salas de la base de datos cinemas. Además de
la utilización de esta función se podrá ver la forma de generar un bucle para
recuperar todos los registros del resultado de la consulta.
Como punto de partida se toma la página del sitio web de Cinem@s que muestra
información general de las salas de proyección disponibles (Figura 16.3).

Figura 16.3 Página de información sobre las características de las salas

Esta página incorpora en su parte inferior un enlace que dará acceso al programa
que realiza la conexión a la base de datos para recuperar todos los registros de la
tabla salas. El enlace se encuentra definido de la siguiente manera:

432
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Si quieres ver las características de cada una de nuestras


salas <A HREF="listadosalas.php">pulsa aquí</A>.

El destino del enlace es la página listadosalas.php cuyo código completo se detalla


a continuación:

Fichero listadosalas.php:

<HTML>
<HEAD><TITLE>Salas disponibles</TITLE></HEAD>
<BODY>
<?php
// carga de las variables de configuración
// y realización de la conexión
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// generación de la consulta de selección
$consulta = "SELECT * FROM SALAS";
// ejecución de la consulta
$resultado = mysql_query($consulta,$c);
if ($resultado) {
print "<H2 ALIGN=center>
Listado de salas disponibles</H2>";
// se recorren todos los registros del resultado
print "<TABLE WIDTH=100% BORDER>
<TR> <TH>Numero de sala</TH>
<TH>Aforo</TH>
<TH>Número de filas</TH>
<TH>Observaciones</TH> </TR>";
$cont = 0;
while($sala = mysql_fetch_array($resultado)){
$cont++;
$nsala = $sala['NUM_SALA'];
$aforo = $sala['AFORO'];
$nfilas = $sala['NUM_FILAS'];
$observaciones = $sala['OBSERVACIONES'];
if ($cont%2==0)
echo("<TR ALIGN=center BGCOLOR='#99CCFF'>\n");
else
echo("<TR ALIGN=center BGCOLOR='#3399FF'>\n");
print "<TD> $nsala </TD>
<TD> $aforo </TD>
<TD> $nfilas </TD>

433
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<TD> $observaciones </TD>";


print "</TR>";
}
print "</TABLE>";
}
// cierre de la conexión
mysql_close($c);
?>
<HR>
<A HREF="salas.htm">Volver</A>
</BODY>
</HTML>

Como puede apreciarse en este ejemplo, la recuperación de los registros en arrays


asociativos resulta más intuitiva. Puede verse también cómo puede construirse un
bucle while para recuperar los registros de todas las salas y a partir de ellos ir
generando dinámicamente una tabla HTML. Para que la presentación resulte un
poco más vistosa, se está cambiando el color de fondo de cada una de las filas de
las tablas de manera alternativa, para ello ha sido preciso utilizar una variable
$cont, que va contando el número de filas de la tabla.

El resultado de la carga de la página anterior sería la visualización de todos los


registros de la tabla salas en una página como la que se muestra en la Figura 16.4.

Figura 16.4 Página con la relación de salas disponibles

434
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Implementación del servicio de consulta de la cartelera


El sitio web Cinem@s implementa igualmente un sencillo sistema de consulta de la
cartelera de proyecciones para un día concreto y de adquisición de localidades. En
ambos casos la conectividad a la base de datos resulta imprescindible.

El punto de partida del sistema que se presentará es la página que se muestra en la


Figura 16.5.

Figura 16.5 Página de consulta de la cartelera

Esta página dispone de un enlace directo a la cartelera del día actual y un calendario con
enlaces a las carteleras de cualquier otro día. Todos estos enlaces dinámicos son creados
por un programa PHP. El primero de ellos, el que genera el enlace a la cartelera del día,
es bastante simple puesto que únicamente utiliza la función date() para obtener el día

435
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

actual e incluye esos parámetros en el enlace como parte del URL. El segundo script, el
que genera el calendario, resulta más complejo y en este caso se ha programado en un
documento diferente e integrado con la función include().

El código completo de la página es:

Fichero proyecciones.php:

<HTML>
<HEAD>
<TITLE>Nuestra cartelera</TITLE>
</HEAD>
<BODY TEXT=blue>
<TABLE WIDTH="100%" BORDER BGCOLOR=#99CCFF>
<TR>
<TH WIDTH="16%">
<A HREF="principal.htm">Página principal</A></TH>
<TH WIDTH="17%">
<A HREF="salas.htm">Nuestras salas</A></TH>
<TH WIDTH="17%">
<A HREF="clientes.htm">Área de clientes</A></TH>
<TH WIDTH="17%">
<A HREF="entradas.htm">Compra de entradas</A></TH>
<TH WIDTH="17%">
<A HREF="estrenos.htm">Próximos estrenos</A></TH>
<TH WIDTH="16%">
<A HREF="foros/index.php">Foro Cinem@s</A></TH>
</TR>
</TABLE>
<H1 ALIGN="center">Nuestra cartelera</H1>
<CENTER>
<TABLE BORDER>
<TR ALIGN=center><TD WIDTH=50%>
<FONT SIZE=+1>
Aquí puedes consultar nuestra oferta para el día de hoy
<BR><BR>
<?php
$dia_hoy=date("d");
$mes_hoy=date("m");
$anno_hoy=date("Y");
print "<A HREF =
cartelera.php?dia=$dia_hoy&mes=$mes_hoy&anno=$anno_hoy>
<IMG SRC='images/rollo.gif' BORDER=0><BR>
Cartelera de hoy
</A>";
?>

436
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

</FONT>
</TD>
<TD WIDTH=50%>
<FONT SIZE=+1>
Si prefieres puedes consultar la cartelera de otro día
seleccionando la fecha deseada en nuestro calendario:
</FONT>
<BR><BR>
<?php
include("calendario.php");
?>
<BR>
</TD>
</TR>
</TABLE>
</CENTER>
</BODY>
</HTML>

El documento calendario.php es el que implementa el algoritmo de generación del


calendario de un mes con los enlaces a las carteleras de los días. El contenido de
este documento sería:

Fichero calendario.php:

<?php
$nombremes=array(1=>"ENERO",2=>"FEBRERO",3=>"MARZO",
4=>"ABRIL",5=>"MAYO",6=>"JUNIO",
7=>"JULIO",8=>"AGOSTO",9=>"SEPTIEMBRE",
10=>"OCTUBRE",11=>"NOVIEMBRE",
12=>"DICIEMBRE");

// función que calcula el número de días de un mes


function numerodiasmes($mes,$anno) {
// comprobación de año bisiesto
$bisiesto=date("L");
switch($mes) {
case 2:
if($bisiesto)
$nd=29;
else
$nd=28;
break;
case 4: case 6: case 9: case 11:
$nd=30;
break;

437
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

default:
$nd=31;
}
return($nd);
}

// funcion que genera el calendario de un mes concreto


function calendariomes($mes,$anno) {
global $nombremes;
// comprobación de mes actual
$mes_hoy=date("m");
$anno_hoy=date("Y");
if (($mes_hoy <> $mes) || ($anno_hoy <> $anno))
$hoy=0;
else
$hoy=date("d");
// cálculo del mes anterior y el mes siguiente
$mes_anterior = $mes - 1;
$anno_anterior = $anno;
if ($mes_anterior==0){
$anno_anterior--;
$mes_anterior=12;
}
$mes_siguiente = $mes + 1;
$anno_siguiente = $anno;
if ($mes_siguiente==13){
$anno_siguiente++;
$mes_siguiente=1;
}
// cálculo del día de inicio del mes (0=dom...6=sáb)
$diasemana=date("w",mktime(0,0,0,$mes,1,$anno));
// los domingos se tratarán como último día de la
semana
if($diasemana==0)
$diasemana=7;
// cálculo del número de días del mes actual
$nd = numerodiasmes($mes,$anno);
// generación del calendario
print "<TABLE CELLSPACING=3 CELLPADDING=2 BORDER=0>
<TR BGCOLOR=blue><TH>
<A HREF =
proyecciones.php?mes=$mes_anterior&anno=$anno_anterior>
<FONT COLOR=white>&lt;&lt;
</A>
</TH>
<TH COLSPAN=5 ALIGN=center>
<FONT COLOR=white> $nombremes[$mes] $anno

438
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

</TH><TH>
<A HREF =
proyecciones.php?mes=$mes_siguiente&anno=$anno_siguiente>
<FONT COLOR=white>&gt;&gt;
</A>
</TH></TR>";
print "<TR ALIG=center BGCOLOR=#3399FF>
<TH WIDTH=14%>Lu</TH><TH WIDTH=14%>Ma</TH>
<TH WIDTH=14%>Mi</TH><TH WIDTH=14%>Ju</TH>
<TH WIDTH=14%>Vi</TH><TH WIDTH=14%>Sa</TH>
<TH WIDTH=14%>Do</TH> </TR>";
print("<TR>");
$aux=1;
//genera celdas en blanco hasta llegar al comienzo del mes
while($aux<$diasemana) {
print("<TD>&nbsp;</TD>");
$aux++;
}
for($i=1;$i<=$nd;$i++) {
$enlace = "<A HREF =
cartelera.php?dia=$i&mes=$mes&anno=$anno>
<FONT SIZE=+1> $i </A>";
if ($i==$hoy)
print("<TH BGCOLOR=red>$enlace</TH>");
elseif(($diasemana==6) or ($diasemana==7))
print("<TH BGCOLOR=#99CCFF>$enlace</TH>");
else
print("<TH>$enlace</TH>");
$diasemana++;
if($diasemana==8) {
// comienza nueva semana
print("</TR>");
print("<TR>");
$diasemana=1;
}
}
print("</TR></TABLE>");
}

// programa principal con llamada a la función


if(!isset($mes,$anno)) {
// datos del mes actual
$mes=date("n");
$anno=date("Y");
}
calendariomes($mes,$anno);
?>

439
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Como puede apreciarse en estos programas, los enlaces generados dinámicamente apuntan
hacia la página cartelera.php, enviándose a dicha página a través del URL tres parámetros
(día, mes y año) que identifican la fecha cuya cartelera se quiere consultar. El documento
recibe esos parámetros y generará con ellos la cartelera mediante un programa PHP que se
conecta a la base de datos. El contenido completo de este documento cartelera.php sería:

Fichero cartelera.php:

<HTML>
<HEAD><TITLE>La cartelera</TITLE></HEAD>
<BODY>
<?php
if(isset($dia,$mes,$anno)) {
// carga de las variables de configuración
// y realización de la conexión
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// generación de la consulta
$fecha = "$anno-$mes-$dia";
$q = "SELECT PELICULAS.IDPELICULA,TITULO,
IDPROY,NUM_SALA,HORA
FROM PELICULAS,PROYECCIONES
WHERE
PROYECCIONES.IDPELICULA =
PELICULAS.IDPELICULA
AND
FECHA = '$fecha'
ORDER BY HORA";
// ejecución de la consulta
$r = mysql_query($q,$c);
if ($r) {
print "<H2 ALIGN=center>
Cartelera del dia $dia-$mes-$anno</H2>";
// se recorren todos los registros del resultado y
// se genera una tabla con ellos
if(mysql_num_rows($r)==0) {
print "<H2 ALIGN=center>
<I>Lo sentimos, no tenemos disponible
la cartelera de este día </I></H2>";
}
else {
print "<TABLE WIDTH=100% BORDER>
<TR> <TH>Película</TH>

440
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

<TH WIDTH=50>Sala</TH>
<TH WIDTH=80>Hora</TH>
<TH WIDTH=100>Compra</TH>
</TR>";
$cont = 0;
while($proy = mysql_fetch_array($r)){
$cont++;
$idpelicula = $proy['IDPELICULA'];
$idproy = $proy['IDPROY'];
$titulo = $proy['TITULO'];
$num_sala = $proy['NUM_SALA'];
$hora = $proy['HORA'];
list($h,$m,$s)=explode(":",$hora);
if ($cont%2==0)
print "<TR ALIGN=center
BGCOLOR='#99CCFF'>\n");
else
print "<TR ALIGN=center
BGCOLOR='#3399FF'>\n");
print "<TD><A
HREF=pelicula.php?peli=$idpelicula
TARGET='_blank'>
<FONT SIZE=+2> $titulo </FONT>
</A>
</TD>
<TD>
<FONT SIZE=+2> $num_sala </FONT>
</TD>
<TD>
<FONT SIZE=+2> $h:$m </FONT> </TD>";
print "<TD> <A
HREF=comprar.php?idproy=$idproy>
<IMG SRC='images/ticket.gif'
BORDER=0>
</A> </TD>";
print "</TR>";
}
}
print "</TABLE>";
}
// cierre de la conexión
mysql_close($c);
}
?>
<HR>
<A HREF="proyecciones.php">Volver</A>
</BODY>

441
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El aspecto de la tabla que es generada dinámicamente por el programa anterior es


el que muestra la Figura 16.6. En dicha tabla, cada título de película se encuentra
enlazado con una nueva página en la que se presenta una breve ficha técnica de la
misma. De nuevo este ficha es generada a partir de los datos del correspondiente
registro de la película en la base de datos.

El destino de todos los enlaces de la tabla con la cartelera es un mismo documento:


película.php. Para que este programa sea capaz de identificar la película cuya ficha
debe generar, se envía en el propio URL del enlace el identificador de la
correspondiente película. El programa podrá utilizar ese dato para acceder a toda la
información del registro correspondiente en la base de datos.

El aspecto final de la ficha técnica de cada película es el que se muestra en la


Figura 16.7.

Figura 16.6 Cartelera de un día

Se incluye a continuación el código de la página que la genera la ficha técnica:

442
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

Fichero pelicula.php:

<HTML>
<HEAD><TITLE>Ficha técnica de la película</TITLE></HEAD>
<BODY>
<?php
// comprobación de la correcta recepción del
// identificador de la película
if (isset($peli)) {
// conexión
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// generación de la consulta
$q = "SELECT * FROM PELICULAS
WHERE IDPELICULA = $peli";
// ejecución de la consulta
$r = mysql_query($q,$c);
if ($r) {
print "<H2 ALIGN=center>Ficha de la pelicula</H2>";
$p = mysql_fetch_array($r);
$titulo = $p['TITULO'];
$actores = $p['ACTORES'];
$produccion = $p['PRODUCCION'];
$direccion = $p['DIRECCION'];
$guion = $p['GUION'];
$anno = $p['ANNO'];
$duracion = $p['DURACION'];
$nacionalidad = $p['NACIONALIDAD'];
$genero = $p['GENERO'];
$edad = $p['EDAD_RESTRICCION'];
$sinopsis = $p['SINOPSIS'];
$cartelera = $p['CARTELERA'];
// generación de un archivo temporal con la
// imagen del cartel de la película
$foto=tempnam("/carteles",'car');
$ft=fopen($foto,"w");
fwrite($ft,$cartelera);
fclose($ft);
print "<TABLE WIDTH=100% BORDER BGCOLOR='#99CCFF'>";
print "<TR> <TD>
<H2> $titulo </H2>";
print " <IMG SRC='$foto'>
</TD>";
print "<TD> <B>Sinopsis:</B> $sinopsis <BR>

443
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

<B>Actores:</B> $actores <BR>


<B>Producción:</B> $produccion <BR>
<B>Dirección:</B> $direccion <BR>
<B>Guión:</B> $guion <BR>
<B>Año:</B> $anno <BR>
<B>Nacionalidad:</B> $nacionalidad <BR>
<B>Duración:</B> $duracion <BR>
<B>Género:</B> $genero <BR>
<B>Autorizada para:</B> $edad <BR>
</TD> </TR>";
print "</TABLE>";
}
// cierre de la conexión
mysql_close($c);
}
?>
<HR>
<INPUT TYPE="button" VALUE="Cerrar"
onClick="window.close()">
</BODY>

Figura 16.7 Ficha técnica y artística de una película

444
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

En la generación de la ficha se necesita incorporar a la página la


imagen de la cartelera de la película que se encuentra almacenada en
un campo BLOB de la tabla de la base de datos. La inserción de esa
NOTA
imagen en la página se consigue generando un archivo temporal con la
función tempnam() y escribiendo sobre él el contenido de la base de
datos recuperado en la consulta. Posteriormente este archivo gráfico
temporal se incorpora a la página con el comando <IMG> de HTML.

Implementación de un sistema de compra on-line de localidades


Finalmente, cada película de la cartelera viene acompañada de un icono que
permite realizar la reserva de localidades para la proyección correspondiente. El
sistema realizará de nuevo una consulta a la base de datos para obtener la relación
de localidades ya vendidas y generará un formulario con campos de tipo checkbox
representando las localidades disponibles para la proyección. El usuario marcará
los asientos deseados e introducirá su número de cliente y clave de acceso.

El aspecto de la página de compra de localidades es el que muestra la Figura 16.8.

Figura 16.8 Consulta y reserva de localidades disponibles

445
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

El código completo que genera esta página se incluye a continuación.

Fichero comprar.php:

<HTML>
<HEAD><TITLE>Compra de entradas</TITLE></HEAD>
<?php
function generarplanosala($filas,$cols) {
global $ocupada;
global $idproy;
// número de columnas de la tabla
print "<FORM ACTION=confirmarcompra.php
METHOD='post'>";
print "<TABLE BORDER>";
print "<TR><TH></TH>
<TH COLSPAN=$cols BGCOLOR=#99CCFF>
Asiento </TH>";
print "<TR BGCOLOR=#99CCFF><TH>Fila</TH>";
for($j=1;$j<=$cols;$j++) {
print "<TH WIDTH=50>A$j</TH>";
}
print "</TR>";
for($i=1;$i<=$filas;$i++) {
print "<TR><TH BGCOLOR=#99CCFF>F$i</TH>";
for($j=1;$j<=$cols;$j++) {
if ($ocupada[$i][$j]) {
print "<INPUT TYPE='hidden'
NAME='F$i" . "A$j' VALUE=0>";
print "<TD ALIGN=center BGCOLOR=red>O</TD>";
}
else {
print "<TD ALIGN=center>
<INPUT TYPE='hidden'
NAME='F$i" . "A$j' VALUE=0>
<INPUT TYPE='checkbox'
NAME='F$i" . "A$j' VALUE=1>
</TD>";
}
}
print "</TR>";
}
print "</TABLE>";
print "<INPUT TYPE='hidden' NAME='numfilas'
VALUE=$filas>";
print "<INPUT TYPE='hidden' NAME='numcols'
VALUE=$cols>";
print "<INPUT TYPE='hidden' NAME='idproy'

446
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

VALUE=$idproy>";
print "<P ALIGN=right>Número de cliente:
<INPUT TYPE='text' SIZE=6 NAME=numcliente><BR>
Contraseña:
<INPUT TYPE='password' SIZE=6 NAME=clave>";
print "<BR> <INPUT TYPE='submit' VALUE='Comprar'>
</P></FORM>";
}
?>

<BODY>
<?php
if (isset($idproy)) {
// conexión a la base de datos
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// obtención de las dimensiones de la sala
$q = "SELECT AFORO,NUM_FILAS FROM SALAS,PROYECCIONES
WHERE
IDPROY = $idproy
AND
PROYECCIONES.NUM_SALA = SALAS.NUM_SALA";
// ejecución de la consulta
$r = mysql_query($q,$c);
list($aforo,$num_filas) = mysql_fetch_array($r);
print "<H2 ALIGN=center> Localidades disponibles
</H2>";
// generación de un array bidimensional para anotar
// las localidades ya ocupadas
$num_columnas =(integer)($aforo/$num_filas);
for($i=1;$i<=$num_filas;$i++) {
for($j=1;$j<=$num_columnas;$j++) {
$ocupada[$i][$j]=FALSE;
}
}
// recuperación de todas las localidades ya ocupadas
$q = "SELECT FILA,NUM_ASIENTO FROM ENTRADAS
WHERE IDPROY = $idproy";
// ejecución de la consulta
$r = mysql_query($q,$c);
if ($r) {
while(list($f,$a) = mysql_fetch_array($r)){
$ocupada[$f][$a]=TRUE;
}

447
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

}
// generación del plano de la sala
generarplanosala($num_filas,$num_columnas);
// cierre de la conexión
mysql_close($c);
}
?>
<A HREF="proyecciones.php">Volver a la cartelera</A>
</BODY>
</HTML>

El formulario de la Figura 16.8 envía los datos relativos al cliente y las localidades
adquiridas por este a una nueva página (confirmarcompra.php) que se encarga de
comprobar la validez de la identificación del cliente y, en su caso, añadir la compra
a la correspondiente tabla de la base de datos, incrementar el saldo de puntos
acumulados por el cliente y presentarle una página de notificación. El código
completo de este último archivo es el siguiente.

Fichero confirmarcompra.php:

<HTML>
<HEAD><TITLE>Confirmación de la compra</TITLE></HEAD>
<BODY>
<?php
if (isset($numcliente,$clave)) {
// conexión a la base de datos
require('configuracion.inc');
$c = mysql_connect($host,$usuario,$password)
or die("Error: " . mysql_error());
mysql_select_db($db,$c)
or die("Error: " . mysql_error());
// autentificación del cliente
$q = "SELECT CLAVE,PUNTOS_ACUM FROM CLIENTES
WHERE NUM_CLIENTE=$numcliente";
$r = mysql_query($q,$c);
if (mysql_num_rows($r)==0)
die("CLIENTE NO REGISTRADO");
$p = mysql_fetch_array($r);
$clave_real=$p['CLAVE'];
$puntos_acum=$p['PUNTOS_ACUM'];
if ($clave!=$clave_real)
die("ERROR: identificación incorrecta");
// registro de las entradas adquiridas
$compra = FALSE;
$ncompradas = 0;
print "Localidades adquiridas:";

448
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

print "<UL>";
for($i=1;$i<=$numfilas;$i++)
for($j=1;$j<=$numcols;$j++) {
$nomCheck="F$i"."A$j";
if ($$nomCheck) {
// localidad adquirida por el cliente
$compra = TRUE;
$ncompradas++;
// se inserta el registro en la tabla entradas
$q = "INSERT INTO ENTRADAS(IDPROY,FILA,
NUM_ASIENTO,

NUM_CLIENTE,RECOGIDA)
VALUES($idproy,$i,$j,$numcliente,0)";
$r = mysql_query($q,$c);
print "<LI> Fila <B>$i</B>, asiento
<B>$j</B>";
}
}
if ($compra) {
// actualización de los puntos acumulados del
cliente
$puntos_acum = $puntos_acum + 5 * $ncompradas;
$q = "UPDATE CLIENTES SET PUNTOS_ACUM=$puntos_acum
WHERE NUM_CLIENTE=$numcliente";
$r = mysql_query($q,$c);
if ($r)
print "<CENTER><U>Tu saldo de puntos tras
esta compra será de $puntos_acum
puntos</U></CENTER>";
print "<H3 ALIGN=center> <I>Recuerda que tu entrada
estará reservada hasta 5 minutos antes del
inicio de la sesión. Si transcurrido ese
plazo
no has procedido al pago de la misma, la
reserva se anulará automáticamente </I><BR>
Muchas gracias por tu compra y a difrutar con
el mejor cine!!!</H3>";
}
// cierre de la conexión
mysql_close($c);
}
?>
<A HREF="proyecciones.php">Volver a la cartelera</A>
</BODY>
</HTML>

449
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

16.5. OTRAS FUNCIONES DE MANIPULACIÓN


DE DATOS
Para finalizar este capítulo destinado a la conectividad a bases de datos MySQL
desde programas PHP, se presentan a continuación algunas funciones adicionales
que pueden resultar útiles.
Como se ha visto, cuando se realiza una consulta de selección sobre la base de
datos, se genera un tipo especial de variable con el resultado: una variable de tipo
recurso. El espacio utilizado por ese recurso se libera automáticamente cuando
finaliza la ejecución del script en el que se creó. Sin embargo, en ocasiones puede
ser interesante liberar ese espacio de manera explícita; por ejemplo, cuando los
resultados de las consultas son grandes y dejan de ser utilizados, ocupando un
innecesario espacio de almacenamiento. La función a utilizar para liberar la
memoria es:

mysql_ free_result(resultado)

En el caso de sentencias de inserción, actualización o borrado, puede ser


interesante en ocasiones saber cuántos registros fueron afectados por dicha
sentencia; por ejemplo, saber cuántos registros fueron borrados. Para ello PHP
dispone de una nueva función que llamada justo a continuación de la ejecución de
la sentencia devuelve ese resultado:

mysql_affected_rows()

En el caso de consultas de selección, si se desea saber el número de registros


resultado de la consulta, se utiliza la función:

mysql_num_rows(resultado)

Cuando a partir de la variable recurso con el resultado de la consulta se desea


obtener alguna información adicional como nombres, tamaños o tipos de los
campos en la tabla, pueden utilizarse las siguientes funciones:

mysql_field_name(resultado,indice)

mysql_field_len(resultado,indice)

mysql_field_type(resultado,indice)

En definitiva, PHP dispone de una completísima librería de funciones específicas


para la conectividad con MySQL. En este capítulo se ha pretendido únicamente

450
CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

presentar las más importantes, a través de un sencillo ejemplo de consulta y reserva


on-line de localidades para Cinem@s. Por supuesto, la aplicación desarrollada es
susceptible de mejoras.

451
IMPLEMENTACIÓN
DE FOROS

17.1. INTRODUCCIÓN
Mediante el uso combinado de MySQL y el lenguaje PHP resulta muy sencillo
implementar en un sitio web un sistema de foros a través del cual todos los
visitantes del sitio puedan enviar sus comentarios, responder a mensajes de otros
usuarios, plantear dudas,... Los foros constituyen una de las aplicaciones más
utilizadas de PHP y MySQL; de hecho, es posible encontrar una amplia variedad
de desarrollos open source para implementarlos. En el Capítulo 18, en el que se
presentan algunas de la soluciones open source más conocidas, se pueden encontrar
algunas referencias a este tipo de aplicaciones de gestión de foros.

En este capítulo se mostrará paso a paso el proceso de creación de un sencillo


sistema de foros para el sitio web de Cinem@s. Los mensajes enviados por los
usuarios quedarán registrados en una tabla de la base de datos y mostrados en la
página ordenados según la fecha de creación y enlazados a todas las posibles
respuestas dadas a dicho mensaje. Por tanto, el primer paso será diseñar una nueva
tabla en la base de datos para almacenar todos los mensajes. Una vez creada la
tabla se deben programar los procedimientos necesarios para insertar nuevos
mensajes y consultar los mensajes enviados.

453
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Cuando un usuario acceda a la página de inicio de los foros se encontrará con la


página que muestra la Figura 17.1. En las próximas secciones se detallará el
proceso completo de creación de esta aplicación.

Figura 17.1 Página de entrada a los foros

17.2. ESTRUCTURA DE LA TABLA DE LA BASE


DE DATOS

Todos los mensajes enviados por los usuarios deben quedar almacenados para
poder ser visualizados por cualquier otro usuario en cualquier momento. Por tanto,
lo primero que se necesitará es una nueva tabla en la base de datos de Cinem@s.

454
IMPLEMENTACIÓN DE FOROS

La nueva tabla a crear tendrá la siguiente estructura:

CREATE TABLE foro (


id int(11) NOT NULL auto_increment,
autor varchar(80) default NULL,
titulo varchar(100) default NULL,
mensaje text,
fecha int(11) default NULL,
respuestas int(11) default 0,
identificador int(11) default 0,
KEY id (id)
) TYPE=MyISAM;

A continuación se comentan los diferentes campos de la tabla:


— id: número de identificación del mensaje. Actuará de
clave de la tabla.
— autor: cadena de caracteres con el nombre del autor del
mensaje.
— titulo: cadena que incluirá el título o asunto del mensaje.
— mensaje: contenido del mensaje.
— fecha: fecha de creación del mensaje. Se opta por utilizar
un campo entero para almacenar este dato porque se
utilizará el sistema de identificación de instantes de
tiempo con el que cuenta PHP.
— respuestas: número entero que indicará el número de respuestas
que ha recibido el mensaje.
— identificador: en el caso de mensajes que sean respuestas a otros
mensajes, este atributo contendrá el identificador del
mensaje al que responde. En caso contrario su valor
será 0.

17.3. GENERACIÓN DE LA PÁGINA PRINCIPAL


DE LOS FOROS
Una vez creada la tabla de la base de datos en la que quedarán registrados todos los
mensajes, el siguiente paso será la construcción de la página principal de los foros
(véase Figura 17.1). Esta página realizará una conexión a la base de datos para

455
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

recuperar todos los registros correspondientes a mensajes de inicio de cada cadena


de mensajes (los mensajes que no son respuesta a ningún otro) y con ellos generará
dinámicamente una tabla de enlaces en la página. El código completo de esta
página de inicio es el siguiente:

<HTML>
<HEAD>
<TITLE>El foro de Cinem@s</TITLE>
</HEAD>
<BODY>
<TABLE WIDTH="100%" border bgColor=#99CCFF>
<TR>
<TH WIDTH="16%"><A HREF="../principal.htm">
Página principal</A></TH>
<TH WIDTH="17%"><A HREF="../proyecciones.htm">
Nuestra cartelera</A></TH>
<TH WIDTH="17%"><A HREF="../salas.htm">
Nuestras salas</A></TH>
<TH WIDTH="17%"><A HREF="../clientes.htm">
Área de clientes</A></TH>
<TH WIDTH="17%"><A HREF="../entradas.htm">
Compra de entradas</A></TH>
<TH WIDTH="16%"><A HREF="../estrenos.htm">
Próximos estrenos</A></TH>
</TR>
</TABLE>
<H1 ALIGN="center">
<FONT COLOR=blue>El foro de usuarios de Cinem@s</FONT>
</H1>
<TABLE WIDTH="100%" border>
<TR>
<TH WIDTH=100>FECHA</TH>
<TH>TITULO</TH>
<TH WIDTH=100>RESPUESTAS</TH>
</TR>

<?
// conexión a la base de datos
require('configuracion.inc');
$enlace = mysql_connect($host,$usuario,$password);
mysql_select_db($db,$enlace);
// consulta: selección de todos los mensajes
// cuyo identificador de mensaje "padre" es 0
$consulta = "SELECT * FROM foro WHERE identificador = 0
ORDER BY fecha DESC";
$consulta = mysql_query($consulta,$enlace);

456
IMPLEMENTACIÓN DE FOROS

// recorrido de todos los mensajes


$cont = 0;
while($row = mysql_fetch_array($consulta)){
$id=$row["id"];
$titulo=$row["titulo"];
$fecha=$row["fecha"];
$respuestas=$row["respuestas"];
$cont++;
if ($cont%2==0)
print "<TR BGCOLOR='#99CCFF'>\n";
else
print "<TR BGCOLOR='#3399FF'>\n";
print "<TH>" . date("d-m-Y",$fecha) . "</TH>\n";
print "<TD>
<A HREF=foro.php?id=$id> $titulo </A>
</TD>\n";
print "<TH>$respuestas</TH>\n";
print "</TR>\n";
}
mysql_close($enlace);
?>
</TABLE>
<BR>
<CENTER>
<FONT FACE="arial" size=2>
<A HREF="formulario.php?respuestas=0">
Añadir nuevo mensaje
</A>
</FONT>
</CENTER>
</BODY>
</HTML>

Como puede apreciarse, la página comienza con el código necesario para generar
una tabla con enlaces a las restantes páginas del sito web de Cinem@s, tras esos
enlaces se genera, mediante un script PHP, una nueva tabla con las fechas, títulos y
números de respuestas de los mensajes cabecera de cada cadena de mensajes. Los
títulos de cada mensaje se encuentran enlazados con la página foro.php, pasando a
esta página en dicho enlace el id concreto del mensaje; este id será utilizado para
acceder al correspondiente registro de la tabla. Finalmente, se encuentra un enlace
a la página formulario.php que permitirá crear un nuevo mensaje.

457
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

17.4. CONSULTA DE UN MENSAJE CON SUS


RESPUESTAS
Como se ha visto en la página principal, el título de cada mensaje se encuentra
enlazado con la página foro.php. Esta página recibirá a través del URL el
identificador del mensaje y realizará una nueva conexión a la base de datos para
recuperar toda la información de dicho mensaje y todos los posibles mensajes que
se hayan enviado como respuesta. Con toda esta información se generará una
página como la que se muestra en la Figura 17.2.

Figura 17.2 Consulta de cadenas de mensajes de los foros

458
IMPLEMENTACIÓN DE FOROS

El código que se encarga de generar esta página es el siguiente.

Fichero foro.php:

<HTML>
<HEAD>
<TITLE>Foro Cinem@s</TITLE>
</HEAD>
<BODY>
<?
// comprobación de la correcta recepción del
// id del mensaje a través del URL
if(isset($id)) {
// conexión a la base de datos
require('configuracion.inc');
$enlace = mysql_connect($host,$usuario,$password);
mysql_select_db($db,$enlace);
// consulta: selección de todos los mensajes cuyo
// valor del atributo identificador es el que ha
// sido pasado a través del URL
$consulta = "SELECT * FROM foro
WHERE id = '$id'
ORDER BY fecha DESC";
$consulta = mysql_query($consulta,$enlace);
// muestra de los atributos del mensaje
$row = mysql_fetch_array($consulta);
$titulo=$row["titulo"];
$autor=$row["autor"];
$mensaje=$row["mensaje"];
$fecha=$row["fecha"];
$respuestas=$row["respuestas"];
print "<TABLE WIDTH=100% BORDER>
<TR><TH WIDTH=100 BGCOLOR=blue>
<FONT COLOR=white>Título</TH>";
print "<TD WIDTH=*> $titulo </TD></TR>";
print "<TR><TH BGCOLOR=blue>
<FONT COLOR=white>Fecha</TH>";
print "<TD>" . date("d-m-Y",$fecha) . "</TD></TR>";
print "<TR><TH BGCOLOR=blue>
<FONT COLOR=white>Autor</TH>";
print "<TD> $autor </TD></TR>";
print "<TR><TH BGCOLOR=blue>
<FONT COLOR=white>Mensaje</TH>";
print "<TD> $mensaje </TD></TR></TABLE>";
// generación de enlaces para añadir respuesta
// y para volver a la página principal del foro
print "<CENTER><FONT FACE=arial SIZE=2>";

459
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

$url = "formulario.php?id=$id&" .
"respuestas=$respuestas&" .
"titulo=$titulo";
print "<A HREF=$url>";
print "<BR>Añadir respuesta </A>&nbsp;";
print "<A HREF=index.php>Volver al foro</A>
</FONT></CENTER>";

// obtención de todas las respuestas al mensaje


$consulta2 = "SELECT * FROM foro
WHERE identificador = '$id'
ORDER BY fecha ASC";
$consulta2 = mysql_query($consulta2,$enlace);
print "<H3 ALIGN=center>
RESPUESTAS A ESTE MENSAJE:
</H3><HR>";
// escritura de las respuestas
while($row = mysql_fetch_array($consulta2)){
$autor=$row['autor'];
$mensaje=$row['mensaje'];
$fecha=$row['fecha'];
print "<B>De:</B> $autor<BR>";
print "<B>Fecha:</B> " .
date("d-m-Y",$fecha) .
"<BR>";
print "<B>Mensaje:</B> $mensaje<BR>";
print "<HR>";
}
mysql_close($enlace);
}
?>
</BODY>
</HTML>

17.5. INSERCIÓN DE NUEVOS MENSAJES


Tanto el enlace situado en la página principal que permite añadir un nuevo
mensaje, como el enlace para añadir una respuesta a un mensaje dado, señalan
como destino una misma página: formulario.php. En el primer caso, creación de un
nuevo mensaje, se envía a través del URL una variable de nombre respuestas y
valor 0; en el segundo caso, respuesta a un mensaje previo, a través del URL se
envían además de la variable anterior, cuyo valor en este caso será el número de
respuestas recibidas, dos nuevas variables, señalando el identificador y título del
mensaje al que se está respondiendo.

460
IMPLEMENTACIÓN DE FOROS

La página formulario.php recogerá esas variables y generará un simple formulario


(véase Figura 17.3) en el que el usuario podrá escribir su mensaje, indicando su
nombre, el título y el texto del mensaje.

Figura 17.3 Formulario para el envío de un nuevo mensaje

El código completo de esta página es el siguiente.

Fichero formulario.php:

<H1>Nuevo mensaje para el foro</H1>


<FORM ACTION="nuevomensaje.php">
<TABLE>
<INPUT TYPE="hidden" NAME="respuestas"
VALUE="<? echo $respuestas; ?>">
<INPUT TYPE="hidden" NAME="identificador"
VALUE="<? echo $id; ?>">
<TR>
<TD>Autor:</TD>
<TD><INPUT TYPE="text" NAME="autor" SIZE=40></TD>
</TR>
<TR>
<TD>Título del mensaje:</TD>
<TD><INPUT TYPE="text" NAME="titulo" SIZE=40
VALUE="<? if (isset($titulo))
echo 'Re: mensaje' . $id; ?>">
</TD>

461
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

</TR>
<TD>Mensaje:</TD>
<TD><TEXTAREA NAME="mensaje" ROWS=6 COLS=30>
</TEXTAREA>
</TD>
</TR>
<TR><TD> <INPUT TYPE=submit VALUE="Enviar"> </TD></TR>
</TABLE>
</FORM>

Como aspectos a destacar de este formulario es el hecho de disponer de dos


campos ocultos cuyo valor es generado por sendos scripts PHP a partir de las
variables recibidas a través del URL.

Una vez que el usuario ha completado todos los campos del formulario, estos serán
enviados a la página nuevomensaje.php que se encargará de realizar la inserción en
la base de datos y cuyo código se presenta a continuación.

Fichero nuevomensaje.php:

<?php
// conexión a la base de datos
require('configuracion.inc');
$enlace = mysql_connect($host, $usuario, $password);
mysql_select_db($db,$enlace);
// obtención de la fecha y hora actual
$fecha = time();
// si el mensaje no es respuesta a ningún otro
// se asigna el valor 0 al identificador del
// mensaje "padre".
if(empty($identificador)){
$identificador=0;
}
// generación de la consulta de inserción
$sql = "INSERT INTO foro(autor,titulo,mensaje,
fecha,identificador)
VALUES ('$autor','$titulo',
'$mensaje','$fecha',
'$identificador')";
mysql_query($sql);
// en el caso de ser respuesta a un mensaje previo
// es necesario actualizar el número de respuestas
// del mensaje al que responde
if($identificador!=0) {
$respuesta = $respuestas+1;
$sql2 ="UPDATE foro SET respuestas = '$respuesta'

462
IMPLEMENTACIÓN DE FOROS

WHERE id = '$identificador'";
mysql_query($sql2);
}
// se vuelve a la página principal del foro
header("location: index.php");
?>

Como ha podido verse en estas secciones, el proceso de implementación de un


sencillo sistema de foros usando PHP y MySQL resulta muy simple. Por supuesto,
diferentes mejoras al sistema implementado podrían hacerse, pero la estructura de
la aplicación sería similar a la planteada. En el próximo capítulo pueden
encontrarse algunas referencias a productos open source de implementación de
foros.

463
SOLUCIONES OPEN
SOURCE BASADAS EN
PHP Y MYSQL

18.1. INTRODUCCIÓN
La evolución y cambios de Internet, tanto en contenidos como en formas y modos
de desarrollarlos y presentarlos al usuario o navegante, ha sido algo continuo.
Partiendo de los desarrollos iniciales en HTML, estático, se ha ido buscando
progresivamente un mayor dinamismo e interacción con el usuario, completando
HTML con Html dinámico, lenguajes embebidos Java Script, PHP, etc. A esta
necesidad de dinamismo e interacción de los sitios web se une otra no menos
importante como es la necesidad de una cada vez mayor cantidad de información y
de herramientas informáticas apropiadas para su gestión.

La utilización conjunta del lenguaje PHP y el sistema gestor de bases de datos


MySQL permite desarrollar múltiples aplicaciones que optimizan los procesos de
generación, mantenimiento y gestión de sitios web. En este capítulo se hará una
breve presentación de algunas de las soluciones open source más conocidas entre la

465
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

comunidad de desarrolladores web. Una de las características comunes a todas las


herramientas que se mostrarán es el hecho de presentarse tanto como soluciones
LAMP (Linux-Apache-MySQL-PHP) como WAMP (Windows-Apache-MySQL-
PHP).

Para la presentación de las herramientas se ha optado por agruparlas en diferentes


categorías en función del uso para el que han sido diseñadas. En primer lugar se
describirán las conocidas como aplicaciones de gestión de contenidos, entre las que
se encuentran algunas de las soluciones basadas en PHP y MySQL más utilizadas
en la actualidad.

Siguiendo con el enfoque mantenido en este libro, la presentación de las diferentes


aplicaciones se centrará en aquellas que son open source. Por supuesto, en el
mercado de software pueden encontrarse desarrollos que no son de código
abierto24, pudiéndose observar una gran oscilación de precios, con aplicaciones de
gestión de contenidos con costes que superan los 48.000 euros, ejemplo Vignette
(www.vignette.com), o aplicaciones con costes inferiores a 900 euros, ejemplo
doITlive (www.doitlive.com).

18.2. GESTORES DE CONTENIDO


La cada vez mayor cantidad de información que ofrecen los sitios web obliga a un
importante esfuerzo en la gestión de contenidos con tareas como revisión,
actualización continua de los mismos, publicación de nuevos contenidos,
eliminación o archivo de los anteriores, etc. Ante esta tendencia de dinamismo e
interacción de los portales y sitios web junto con la necesidad de una mayor
información y capacidad de comunicación, con el consiguiente esfuerzo que
conlleva una gestión adecuada de los contenidos, se han desarrollado una serie de
aplicaciones denominadas gestores de contenido25 o CMS (Content Managment
System) con la intención de facilitar tanto el desarrollo de sitios web dinámicos
como la gestión de elevados volúmenes de información y contenidos en dichos
sitios web.

24
En las aplicaciones que no son de código abierto lo que se adquiere es el derecho a usar
la aplicación pero no la propiedad de la misma ni la capacidad de modificarla, copiarla o
distribuirla, sin el permiso del propietario de la patente, lo que supone la dependencia de
este.
25
Indicar que nos referimos exclusivamente a los gestores de contenido web, pues el
termino gestión de contenido tiene un significado amplio existiendo otro tipo de
aplicaciones de gestión de contenido, como por ejemplo las de gestión de contenido
documental, etc.

466
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

Atrás queda el periodo de Internet como mero escaparate o catálogo en el que


primaba la redundancia de efectos técnicos y la vistosidad del sitio o portal en
detrimento de los contenidos. En la actualidad, la Red es un medio de
comunicación bidireccional donde, si bien la apariencia, presentación y formato
son importantes, estos están estrechamente ligados y en dependencia del contenido
de la página o portal, factor discriminatorio26 a la hora de que los internautas
visiten un sitio web. Por tanto, el contenido debe ser de interés y calidad para la
audiencia objetivo, actualizado tantas veces como sea necesario; debe permitir la
bidireccionalidad y feedback de la información haciendo al usuario participar
activamente en el contenido mediante foros, chat, recogida de opiniones, etc., y
todo ello con una presentación de los contenidos mediante un interfaz de
navegación agradable, intuitivo, fácil de usar y sobre todo útil.

Para lograr esto, o al menos intentarlo, la opción tradicional en el caso de las


empresas consistía en disponer de un equipo formado por técnicos capaces de
desarrollar el aspecto tecnológico plataforma, formato, diseño y actualización del
sitio, y personal especializado exclusivamente en los contenidos a situar en la web.
Lo cual suponía un elevado desembolso económico. Y, en el caso de los
particulares, obligaba a estos a tener elevados conocimientos técnicos y a estar
continuamente pendientes de la vigencia de sus contenidos.

Sin embargo, una solución más reciente que ha ido cobrando importancia
creciente tanto entre empresas como entre particulares es la aportada por los
gestores de contenido web, denominados generalmente con las siglas CMS,
procedente de la terminología anglosajona Content Management System. Si bien
no hay una definición oficial u homogénea referida a los gestores de contenido
web, analizando qué son y qué permiten hacer se podría proponer la siguiente
definición:

Un gestor de contenidos web es un software que permite y facilita el


desarrollo de un sitio o portal (formato, estructura, presentación,...) sin
tener elevados conocimientos técnicos, y gestionar su contenido,
entendiendo por gestión de contenido la administración y control total del
ciclo de vida de los contenidos web (creación, clasificación, publicación,
actualización, eliminación o archivo de todos los contenidos). Todo ello de
forma automática, atendiendo a una configuración predeterminada por el
creador o administrador del sitio.

26
Forrester Research: Las condiciones de retorno de un visitante a un sitio disponible en:
http://www.jipo-interactive.com/es/articles/webmastering/article_webmastering_1

467
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.2.1. FUNCIONAMIENTO
Pese a la gran diversidad de aplicaciones, generalmente los gestores de contenido
tienen un funcionamiento similar. Son aplicaciones modulares que se apoyan en
bases de datos o repositorios y están formadas por dos elementos, la aplicación
gestora de contenidos (CMA) y la aplicación de presentación de contenidos (CDA)
que se utilizan mediante una única interfaz más o menos intuitiva, dependiendo de
la aplicación, y por lo general de tipo web. El CMA, permite al autor del sitio, sin
necesidad de que este posea conocimientos de HTML u otro lenguaje, realizar la
creación, actualización y eliminación del contenido del sitio web. El CDA por su
parte, permite al autor elegir, mediante la selección de plantillas, el formato en que
se presentarán los contenidos.

El funcionamiento de los CMS puede ser resumido de la siguiente forma:


— Un sitio web o portal está formado por un conjunto de páginas organizadas
jerárquicamente.
— A cada página le corresponde un determinado diseño o plantilla, que define
la estructura de la página y el formato.
— Dentro de cada página, las distintas secciones pueden tener sus propias
plantillas distintas de las de la página a la que pertenecen, lo que permite
mostrar en una misma página contenidos con distinta presentación.
— Cada página o sección se asocia a un campo de la base de datos donde se
depositan los contenidos.

Por tanto, el administrador utilizando un CMS creará el sitio web y decidirá la


apariencia de las distintas páginas y sus secciones, los contenidos a mostrar y cómo
se presentará cada contenido.

18.2.2. CARACTERÍSTICAS
La oferta existente de aplicaciones dedicadas a la gestión de contenidos web
(CMS) es muy heterogénea tanto en número de aplicaciones como en las
características concretas que estas presentan. Respecto a las aplicaciones de gestión
de contenidos web open source, existe un elevado número de alternativas fruto de
un continuo desarrollo y mejora, característico de las comunidades open source.
Pero este elevado número de aplicaciones no implica que todas estén al mismo
nivel de desarrollo. Algunas están ampliamente testadas y consolidadas, con
numerosos manuales y documentación de apoyo, entre otras se pueden citar como

468
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

ejemplos PHPnuke, PostNuke, Xoops, y otras son de creación más reciente, aunque
no por ello peores, como Mambo.

El elegir una u otra aplicación debería venir precedido, tanto para empresas como
particulares, por:

1. Definir cuáles son los objetivos, características y público objetivo del sitio
web a crear.
2. Analizar las características de las distintas aplicaciones y de las
comunidades que las han desarrollado para determinar cuál se ajusta mejor
a las necesidades detectadas.

A pesar de la gran diversidad de aplicaciones CMS open source, todas tienen una
misma finalidad y convergen en una serie de características. Estas características
podrían considerarse como las propiedades o requisitos mínimos a exigir a un
CMS, de forma que sirvan de indicativo para cribar entre las numerosas
aplicaciones y determinar cuáles pueden ser las más adecuadas en función siempre
de las necesidades particulares. A continuación, examinado el funcionamiento de
distintas aplicaciones CMS, se recoge una orientación de los requisitos mínimos
deseables para dichas aplicaciones, tanto relativos a la creación de contenido como
a la gestión, publicación y presentación de los contenidos.

— Creación de contenido:
o Interfaz intuitivo y fácil de utilizar, para la creación y gestión tanto del
sitio web como de los contenidos, por personal no técnico o sin
conocimientos informáticos elevados.
o Separación de la presentación, diferentes formatos y diseños definidos,
de los contenidos a publicar.
o Posibilidad de establecer múltiples autores de contenidos.
o Reutilización y compartición de los elementos que conforman el sitio
web, estructuras, contenidos, diseños, etc., evitando duplicaciones y
ahorrando recursos.

— Gestión de contenidos
o Control completo del ciclo de vida de los contenidos, entendidos estos
en sentido amplio como cualquier información, imágenes, texto, etc.,
desde su creación hasta su eliminación o archivo pasando por su
control o validación, publicación, actualización y control de versiones.
o Nivel de seguridad aceptable para poder proteger la integridad de los
contenidos.
o Permitir la designación de roles o distintos perfiles de usuarios, cada
uno con unos privilegios respecto a la gestión del contenido.

469
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

— Publicación
o Publicación de contenidos en diferentes formatos HTML, PDF,...
o Permitir la personalización, presentar diferente información para
diferentes perfiles.
o Definir los flujos de trabajo incluyendo actualización, validación y
publicación en función de los distintos perfiles definidos.
o Proporcionar estadísticas sobre hábitos de navegación de los visitantes,
contenidos más visitados, etc.
o Previsualización interna de contenidos anterior a su publicación a los usuarios.
o Composición especificada en plantillas basadas en XML.
o Posibilidad de ofrecer soporte multilingüe.

— Presentación final
o Usabilidad, recoge conceptos de facilidad de uso y eficiencia para todos los
usuarios además de una navegación coherente y comprensible.
o Accesibilidad, el sitio que se desarrolle debe ser conforme a estándares
como los de W3C y permitir ser soportado por distintos navegadores.
o Velocidad de descarga, limitar el tamaño del sitio para garantizar un
tiempo de descarga aceptable para el usuario.
o Metadatos, las páginas del sitio deben ofrecer suficientes metadatos
para asegurar la indexación en buscadores.

18.2.3. VENTAJAS E INCONVENIENTES


Tras la lectura de los distintos epígrafes el lector posiblemente ya ha sacado sus
conclusiones sobre las ventajas e inconvenientes de los gestores de contenido open
source. No obstante, en este apartado revisamos las principales ventajas y
dificultades que pueden presentar dichas aplicaciones.

Ventajas Inconvenientes
— Facilitan la creación de un sitio web y la — Dominar una aplicación CMS requiere
completa gestión de sus contenidos sin tener tiempo y en el caso de grandes empresas,
excesivos conocimientos informáticos. pueden suponer un alto coste en consultores
— Permiten incorporar al sitio web diferentes que integren la aplicación con el sistema
servicios como foros, chats, encuestas,... existente en la organización.
— Facilidad para la modificación del sitio y de los — En algunos casos puede generar un exceso
contenidos de forma remota, desde cualquier de homogeneidad con otros sitios
punto con conexión a Internet. desarrollados con el mismo CMS.
— Personalización del sitio en función del — El desarrollo y mejoras de la aplicación
usuario, creando distintos perfiles. están vinculados al desarrollo de la
— Gratuidad y código abierto. comunidad creadora del software.
Tabla 18.1 Ventajas e inconvenientes de los gestores de contenido

470
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

Para finalizar esta sección, y antes de pasar a presentar aplicaciones concretas, se


incluyen a continuación un listado de direcciones de Internet donde se puede
completar información relativa a los CMS open source:

— www.opensourcecms.com: completo portal en el que se recoge toda la


información relativa a los CMS open source.
— www.cmsreview.com: sitio web dedicado exclusivamente a informar sobre los
CMS, realizando comparativas entre distintas aplicaciones.
— www.cms-spain.com: portal informativo con informes y artículos, en
castellano, sobre las novedades en los CMS.

18.3. GESTORES DE CONTENIDO BASADOS EN


PHP Y MYSQL
En esta sección se recoge una recopilación de los gestores de contenido open
source más conocidos y utilizados, presentando brevemente sus características más
destacadas e indicando las direcciones de Internet donde se pueden obtener las
correspondientes aplicaciones y toda la información necesaria sobre las mismas.

18.3.1. PHP-NUKE
Sitio oficial http://www.phpnuke.org
www.phpnuke-espanol.org/

Es un sistema de gestión de contenidos y un sistema automatizado de noticias


diseñado para ser usado en intranets e Internet utilizando bases de datos. Posee un
conjunto de herramientas que permiten construir páginas atractivas e interactivas.

La licencia gratuita GPL permite al usuario modificar el código fuente y adaptarlo


a sus necesidades.

PHPNuke se ha convertido en los últimos años en uno de los gestores de web más
utilizados y completos que existen, ya que permite crear los sitios web con enorme
facilidad, gestionar su publicación y desarrollar una comunidad de usuarios, todo
en uno y con múltiples servicios añadidos. Algunas de las características que se
podrían destacar son:

— Creación y administración rápida de una comunidad on line.


— Administración sencilla con interfaz intuitivo y gráfico.
— Gestión y administración de usuarios registrados.

471
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Figura 18.1 Sitio oficial de PHPNUKE

— Estadísticas del sitio (páginas más votadas, más vistas,...)


— Zonas personalizables por el usuario.
— Servicio de encuestas y valoración de artículos on line.
— Administrador de plantillas para usuarios registrados.
— Completo sistema de moderación de contenidos.
— Gestor de zonas y secciones.
— Gestión de referencias para controlar los enlaces externos al sitio web.
— Sistema de gestión de banners integrado.
— Motor de búsqueda integrado.
— Sistema de generación de noticias.
— Soporte para más de 22 lenguajes.
— Disponibles cientos de plantillas y módulos para añadir más opciones.
— Gestor de ficheros incluido.
— Gestión de faqs (preguntas frecuentes).

472
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.3.2. POSTNUKE
Sitio oficial www.postnuke.com
www.postnuke-hispano.com

PostNuke puede verse como un sistema de gestión de contenidos, pero también


como un sistema de gestión colaborativo que permite generar verdaderas
comunidades de usuarios, en las que los miembros de la comunidad interactúan con
el contenido. PostNuke se autodefine como una herramienta C3MS (comunidad,
contenido y sistema de colaboración de contenido). Se caracteriza por su facilidad
de instalación, utilización y administración, todo ello a través de la web. La
herramienta tiene un diseño modular, disponiendo de módulos que permiten
construir, por ejemplo, un chat integrado, un sistema de foros, galerías de
imágenes, estadísticas,...

Figura 18.2 Sitio oficial de POSTNUKE

473
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.3.3. MAMBO SERVER


Sitio oficial www.mamboserver.com
www.mambohispano.org

Mambo open source es una aplicación escrita en PHP basada en los sistemas de
administración de contenidos, que permite la fácil creación y mantenimiento de
sitios web y portales. Como todos los CMS, su simplicidad se traduce en que no
son necesarios grandes conocimientos para actualizar, mantener y personalizar los
contenidos. Incorpora un editor WYSIWYG propio de contenido. Sus
características son similares a las de los productos anteriores.

Está disponible para diferentes plataformas, entre las que se encuentran Linux,
FreeBSD, MacOSX Server, Solaris, AIX, SCO, WinNT y Win2K.

Figura 18.3 Sitio oficial de MAMBO

474
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.3.4. PHPWEBSITE
Sitio oficial phpwebsite.appstate.edu

Gestor de contenido desarrollado en PHP por el grupo de tecnologías web de la


Appalachian State University de Boone (USA). Aunque menos conocido que los
anteriores, presenta características similares, destacando por la facilidad de
administración a través de su interfaz gráfica. En su desarrollo se respetan los
estándares recomendados por la W3C.

A fecha de hoy no existe sitio oficial en español y tiene pocos complementos para
añadir. Puede ser una opción interesante para desarrollar sitios de empresas sin los
requerimientos de una comunidad.

Figura 18.4 Sitio oficial de PHPWEBSITE

475
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.3.5. PHP-WCMS
Sitio oficial www.phpwcms.de

Es un CMS optimizado para una rápida y fácil instalación sobre cualquier servidor
web que soporte PHP y MySQL. Ha sido probado satisfactoriamente sobre
Windows 2000/XP, MacOSX y LINUX.

Es ideal para usuarios profesionales, públicos y privados, por su facilidad de


aprendizaje y por brindar la posibilidad de separar diseño de contenido. Las
poderosas pero simples características que tienen implementadas sirven de mucha
ayuda tanto a diseñadores como a desarrolladores Web.

Figura 18.5 Sitio oficial de PHP-WCMS

476
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.3.6. XOOPS
Sitio oficial www.xoops.org
www.esxoops.com

Recomendable CMS con buen soporte en español y muchos módulos, XOOPS ha


revolucionado la creación dinámica de portales, escrito en PHP y bajo licencia
open source.

Se trata de una herramienta basada en programación orientada a objetos (OOP,


Object Oriented Programing) y que puede ser utilizada para crear y mantener
fácilmente sitios web personales, portales corporativos, weblogs,...

Figura 18.6 Sitio oficial de XOOPS

477
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.3.7. DRUPAL
Sitio oficial www.drupal.org
drupal.badopi.org

Drupal es un CMS desarrollado en PHP, puede ser usado con MySQL o con
PostgreSQL y ejecutado sobre múltiples plataformas, incluyendo los servidores
Apache o IIS de Microsoft.

Permite a los usuarios publicar, gestionar y organizar contenidos. Drupal incorpora


igualmente herramientas colaborativas para el desarrollo de comunidades. Otras
prestaciones de la plataforma son su motor de búsqueda, muestreo del sitio,
weblog, control de versiones, gestor de noticias, foros de discusión...

Figura 18.7 Sitio oficial de DRUPAL

478
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.3.8. SITEFRAME
Sitio oficial siteframe.org

Se trata de un CMS diseñado para crear rápidamente sitios web para comunidades.
Dispone de un conjunto de plantillas con un diseño agradable y artístico.

Está orientado a compartir documentos, haciendo uso de una interfaz clara y


sencilla.

Figura 18.8 Sitio oficial de SITEFRAME

479
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.4. OTRAS SOLUCIONES OPEN SOURCE

18.4.1. WEBLOGS
Los weblogs, también conocidos como bitácoras, constituyen una de las formas
más sencillas de crear y actualizar una página web. De este fenómeno emergente
han nacido varios sistemas de publicación gratuitos basados en PHP y MySQL que
permiten poner un weblog en marcha en menos de cinco minutos, sin ningún
conocimiento previo.

Antes de nada conviene tratar de clarificar lo que se entiende por weblog, aunque
no es fácil encontrar una definición precisa, y de hecho existe un debate abierto
sobre el tema, se podría decir que un weblog es un sitio web donde se recopilan
cronológicamente mensajes de uno o varios autores, sobre una temática o a modo
de diario personal. Estos sitios web suelen incorporar enlaces a otros weblogs,
archivos de entradas anteriores, enlaces para citar anotaciones, funciones para
añadir comentarios,...

GeekLog
Sitio oficial www.geeklog.net

Geeklog es una herramienta para la creación de weblogs basada en PHP y MySQL,


permite generar en pocos minutos un sitio web dinámico completamente funcional.
Algunas características de esta herramienta son:

— Permite que los usuarios se registren como miembros y envíen sus historias o
artículos.
— Dispone de un sistema para añadir comentarios a los artículos publicados por
los miembros.
— Sistema basado en plugins para extender la aplicación.
— Generación automática de estadísticas del sitio.
— Dispone de un calendario para añadir eventos o citas.
— Herramientas de comunicación entre los miembros de la comunidad de
usuarios.

480
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

Figura 18.9 Sitio oficial de GEEKLOG

481
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Pmachine
Sitio oficial www.pmachine.com

Sistema de weblogs muy completo que permite una administración por web
mediante un interfaz gráfico fácil de utilizar y muy intuitivo. Soporta múltiples
weblogs, organizándolos en categorías, separándolos en páginas independientes o
colocando múltiples weblogs en la misma página. Puede llegar a convertir un
weblog en una comunidad on line.

Figura 18.10 Sitio oficial de pMachine

482
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

B2, B2evolution y WordPress


Sitio oficial www.cafelog.com
b2evolution.net
wordpress.org

B2 es un sistema de generación de weblogs basado en PHP y MySQL. Se trata de


uno de los productos más simples y sencillos de utilizar en su categoría. Dispone
de dos extensiones más completas: b2evolution y WordPress.

Figura 18.11 Sitio oficial de B2

483
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.4.2. SISTEMAS DE FOROS

Los foros de discusión constituyen uno de los más importantes mecanismos para el
intercambio de información con los que cuenta Internet. En la actualidad pueden
encontrarse foros temáticos prácticamente sobre cualquier tema imaginable, foros
en los que los usuarios plantean sus dudas, buscan información especializada,
contactan con usuarios interesados en los mismos temas, solicitan ayuda o
consejo,... En definitiva, los foros permiten diseñar páginas de contenido atractivo
autogenerado por los visitantes del sitio web.

Los foros favorecen los canales de comunicación con clientes, proveedores,


usuarios, etc., y resultan ideales para dar soporte técnico a usuarios.

La corriente open source no ha sido ajena al interés en desarrollar herramientas que


faciliten la creación y gestión de foros. En esta sección se presentan dos de los
proyectos más conocidos en este campo y que han sido desarrollados utilizando las
tecnologías PHP y MySQL.

Algunas de las características habituales de estos sistemas son:

— Creación y administración rápida de una comunidad on line.


— Interfaz de usuario de fácil manejo.
— Formato de los mensajes con múltiples estilos y tamaños de fuentes y
enlace automático de URL.
— Integración de sistemas de generación de encuestas.
— Notificación por e-mail de las respuestas.
— Posibilidad de envío de mensajes privados entre usuarios.
— Mecanismos de control de la IP desde la que se envían los mensajes.
— Encriptación de información sensible (por ejemplo contraseñas).
— Uso de cookies para simular conexiones continuas.
— Posibilidad de establecer usuarios moderadores para cada foro temático.
— En ocasiones disponen de mecanismos que permiten filtrar los mensajes,
censurando a determinados usuarios o palabras que puedan resultar
ofensivas.

484
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

Phpbb
Sitio oficial www.phpbb.com

PHPBB es una aplicación open source muy potente y de fácil personalización para
establecer comunidades virtuales con foros interactivos donde los usuarios pueden
añadir temas, crear y responder mensajes... Su interfaz de usuario es muy fácil de
usar por el visitante, con un panel de administración simple y de ejecución rápida y
sencilla y una sección de ayuda siempre a mano.

Figura 18.12 Sitio oficial de phpBB

485
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Minibb
Sitio oficial www.minibb.net

MiniBB es un sistema de foros altamente configurable escrito en el lenguaje PHP.


Incluye las características más populares de los sistemas de foros conocidos pero
con un tamaño más reducido y mucho más rápido. Está basado en MySQL pero
también se puede utilizar con otros gestores de bases de datos como PostgreSQL o
Microsoft SQL Server a través de módulos especiales.

Figura 18.13 Sitio oficial de miniBB

18.4.3. PLATAFORMAS DE E-LEARNING

Otro de los campos de aplicación más destacado de las tecnologías web es el


desarrollo de entornos de enseñanza on line, también conocidos como entornos de
enseñanza virtual o e-learning. En este caso, los desarrollos que tratan de dar
apoyo a estos sistemas de enseñanza recrean un verdadero entorno virtual de
enseñanza, en el que se reflejen los elementos habituales de todo actividad de

486
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

aprendizaje. Estos sistemas, además de servir como gestores de contenido estructurado


en unidades didácticas, permiten gestionar los diferentes usuarios, realizar un
seguimiento detallado de su actividad dentro del curso, poner a disposición de los
mismos diferentes herramientas de comunicación, establecer procesos de evaluación, etc.

Existe una amplia variedad de plataformas de e-learning comerciales, pero también


es posible encontrar algún producto dentro de la corriente open source, este es el
caso de la plataforma Moodle.

Moodle
Sitio oficial moodle.org

Moodle (Modular Object-Oriented Dynamic Learning Environment) es un


proyecto en desarrollo diseñado para dar soporte a un marco de educación social
constructivista y que se distribuye gratuitamente como software libre. Está
desarrollando en PHP y trabaja con diferentes tipos de bases de datos, aunque lo
habitual es encontrarlo trabajando sobre MySQL. En el desarrollo de la plataforma
se ha puesto un especial énfasis en la seguridad sólida de toda la plataforma, los
mecanismos de autentificación y en la claridad del código fuente PHP para facilitar
su modificación y adaptación a necesidades particulares.

Figura 18.14 Sitio oficial de Moodle

487
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.4.4. ENTORNOS DE COMERCIO ELECTRÓNICO


En el ámbito del comercio electrónico también es posible encontrar algunos productos
interesantes basados en PHP y MySQL y que pueden ser utilizados gratuitamente. Por
ejemplo es posible encontrar desarrollos para implementar una tienda virtual.

OSCommerce
Sitio oficial www.oscommerce.com

OsCommerce es una solución de comercio electrónico sencilla de mantener y


administrar, que con el mínimo esfuerzo permite disponer de una tienda virtual.
Comenzó su desarrollo en marzo 2000 y desde entonces ha madurado
notablemente en sus soluciones, existiendo en la actualidad miles de tiendas en el
mundo con este sistema. Entre sus características están: un completo sistema de
administración web, estadísticas de productos más vendidos, módulos de pago y
envío, soporte SSL, buscador, control de impuestos, gestión de pedidos,...

Figura 18.15 Sitio oficial de osCommerce

488
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

Cubecart
Sitio oficial www.cubecart.com

CubeCart es otro producto basado en PHP y MySQL que puede utilizarse


gratuitamente para implementar una tienda virtual, siempre y cuando el copyright
del producto no sea modificado o eliminado. En caso de desear eliminar ese
copyrigth en el sitio web desarrollado, se debe pagar una cantidad por la licencia.

Debe destacarse que CubeCart no se distribuye como código abierto, por lo que no
puede ser redistribuido.

Figura 18.16 Sitio oficial de CubeCart

489
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

18.4.5. SISTEMAS DE ATENCIÓN AL CLIENTE

OsTicket
Sitio oficial www.osticket.com

OsTicket es un sistema automatizado de soporte al cliente basado en lenguaje PHP


en el que se pueden abrir consultas vía e-mail o directamente desde la web. En
ambos casos, los clientes, al abrir una consulta recibirán un e-mail de auto
respuesta. El cliente puede consultar en todo momento el estado de su consulta.

Figura 18.17 Sitio oficial de osTicket

490
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

PHP-Support-Tickets
Sitio oficial www.phpsupporttickets.com

PHP-Support-Tickets es otra solución basada en PHP y MySQL para atender a los


clientes y con un funcionamiento y características similar al producto anterior. A
través de la página oficial del producto se puede acceder a una demo on line del
mismo.

Figura 18.18 Sitio oficial de PHP Support Tickets

491
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

SugarSales
Sitio oficial www.sugarcrm.com

SugarSales es una suite CRM (Customer Relationship Management) que incluye la


gestion de procesos de ventas, comercialización y servicio al cliente.

Es una aplicación fácil de utilizar y fácil de instalar construida en PHP y MySQL.

Figura 18.19 Sitio oficial de SugarSales

492
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.4.6. HERRAMIENTAS DE GESTIÓN DE PROYECTOS

PHPCollab
Sitio oficial www.php-collab.com

PHPCollab es un sistema de gestión de proyectos basado en lenguaje PHP con el


que se crea un entorno de colaboración en equipos de proyectos. PHPCollab
permite compartir información con otros miembros en un mismo espacio e
incorpora aspectos importantes de la gestión de proyectos: planificación de tareas,
documentos compartidos, seguimiento de tiempos y plazos, gráficos de progreso,
generación de informes,...

Figura 18.20 Sitio oficial de phpCollab

493
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

DotProject
Sitio oficial www.dotproject.net

DotProject es otra herramienta open source de administración de proyectos basada


en PHP. Incluye módulos para gestión de clientes y compañías, listado de
proyectos, asignación de tareas, calendarios, foros, contactos,...

Figura 18.21 Sitio oficial de dotProject

494
SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

18.4.7. OTRAS HERRAMIENTAS


Para finalizar, se incluyen en esta sección referencias a diferentes herramientas,
todas ellas basadas en PHP y MySQL y que permiten dar mayores funcionalidades
a los sitios web.

PhpAdsNew
Sitio oficial phpadsnew.com

PhpAdsNew es una herramienta que permite gestionar de manera sencilla los


banners y publicidad de un sitio web. Incorpora un sistema de seguimiento
avanzado con estadísticas. PhpAdsNew permite publicar diferentes banners con
parámetros que controlan la dirección IP, dominio, día de la semana, hora del día,
lenguaje, navegador o sistema operativo. Los anunciantes pueden controlar su
histórico desde el interfaz de usuario y ver estadísticas de los ratios de efectividad
de sus banners.

4images
Sitio oficial www.4homepages.de

4images es un sistema de administración de galerías de imágenes para la web.


Permite incluir comentarios para cada imagen, administrar la galería vía web, auto
dimensionar las imágenes e incorpora plantillas HTML para diseño y un motor de
búsqueda integrado.

OWL
Sitio oficial owl.sourceforge.net

OWL es un sistema muy completo que permite la administración y publicación de


documentación en distintos entornos. Permite compartir documentos dentro de la
organización, estableciendo mecanismos de control de accesos, organización de
documentos en carpetas, control de versiones,... En definitiva, se trata de un
completo sistema de gestión documental.

495
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

OpenClinic
Sitio oficial openclinic.sourceforge.net

OpenClinic es un sistema de gestión de expedientes médicos, permite almacenar


información sobre pacientes, crea informes, permite realizar búsquedas,...

PHPList
Sitio oficial tincan.co.uk/phplist

PHPlist es una aplicación web que implementa un gestor de listas de correo


personalizado y que puede verse también como un sencillo CRM.

PHP Auction
Sitio oficial www.phpauction.org

Se trata de una herramienta para la elaboración y gestión de subastas on-line.


Existen varias versiones del producto, siendo una de ellas distribuida gratuitamente
bajo la licencia GPL.

Web Calendar
Sitio oficial www.k5n.us/webcalendar.php

Herramienta que implementa un calendario de eventos, puede ser configurado


como un sistema monousuario o multiusuario.

496
Índice alfabético

— · 124 &
! & · 127, 203
! · 130 && · 130
!= · 128
!== · 128 .
. · 131
$
$_COOKIE · 291 @
$_GET · 142
@ · 132
$_POST · 142
$_REQUEST · 142
[
$_SERVER · 110
[] · 216
$GLOBALS · 208, 265
^
$HTTP_COOKIE_VARS · 290
^ · 127
$HTTP_GET_VARS · 143

$HTTP_POST_VARS · 143
‘ · 132
$this · 275
|
| · 127
%
|| · 130
% · 124
~
~ · 127
+

497
++ · 124 array_diff_assoc · 239
< array_fill · 237
< · 128 array_filter · 228
<< · 127 array_intersect · 239
<= · 128 array_intersect_assoc · 239
= array_key_exists · 230
== · 128 array_keys · 229
=== · 128 array_map · 240
> array_pad · 237
> · 128 array_pop · 237
-> · 278 array_push · 237
>= · 128 array_rand · 230
>> · 127 array_reverse · 245
array_search · 231
array_shift · 237
A array_splice · 235
array_unique · 237
A · 82 array_unshift · 238
ACTION · 137 array_values · 232
ALL · 331 array_walk · 242
ALTER · 318, 321 Arrays · 113
ámbito de las variables · 116 arrays asociativos · 217
and · 130 arsort · 244
applet · 10 ASC · 334
Applet · 19 asort · 244
argumentos ASP · 21
longitud variable · 201 AVG · 335
opcionales · 199
por referencia · 203 B
por valor · 203
valores por defecto · 200 B · 69
argumentos opcionales · 199 BIGINT · 357
array · 215, 216 BINARY · 360
multidimensional · 218 BIT · 357
array_change_key_case · 225 BLINK · 69
array_chunk · 226 BLOB · 360
array_combine · 232 BLOCKQUOTE · 70
array_count_values · 227 BODY · 62
array_diff · 239 BOOL · 357

498
borrado en cascada · 324 CREATE INDEX · 323
break · 170, 188 CREATE TABLE · 318
ctype_alnum · 250
C ctype_alpha · 250
ctype_digit · 250
Cadenas · 113 ctype_lower · 250
case · 170 ctype_print · 250
CASE_LOWER · 225 ctype_punct · 250
CASE_UPPER · 225 ctype_space · 250
CGI · 21 ctype_upper · 250

Ch D

CHAR · 359 date · 107, 167, 260


checkdate · 260 DEC · 358
chr · 182 DECIMAL · 358
default · 170
C define · 119
DELETE · 328
class · 273 DESC · 334
clave DESCRIBE · 347
ajena · 323 die · 416
Cliente · 6 DISTINCT · 331, 332
cliente/servidor · 5 do...while · 176
ColdFusion · 22 DOCTYPE · 64
comentarios · 112 DOUBLE · 358
compact · 232 DROP · 318
comunidades · 47
constructor · 275 E
continue · 188
cookie · 285, 286 each · 221
de sesión · 291 echo · 103
permanente · 291 eliminación en cascada · 374
visibilidad · 294 else · 162
copy · 306 elseif · 165
count · 223, 227 empty · 119
COUNT · 335 ENCTYPE · 307
CREATE · 317 endfor · 179
CREATE DATABASE · 317 endif · 167

499
endswitch · 173 func_get_args · 202
endwhile · 175 func_num_args · 202
ENUM · 361 funciones variables · 211
EXIT · 344 function · 193
explode · 251 function_exists · 212
extends · 283 fwrite · 303
EXTR_OVERWRITE · 233
EXTR_PREFIX_ALL · 233 G
EXTR_PREFIX_SAME · 233
EXTR_SKIP · 233 get_defined_functions · 212
extract · 233 gettype · 118
global · 207
F GNU · 29
GPL · 37
fclose · 297 GROUP BY · 331, 336
feof · 298
fgetc · 300 H
fgets · 298
file · 299 HAVING · 331, 336
file_exists · 307 HEAD · 62
filesize · 299 herencia · 281
FLOAT · 358 hipertexto · 5
FLUSH PRIVILEGES · 351 Hn · 68
FONT · 69 HTML · 7, 57
fopen · 296 http · 7, 55
for · 179
foreach · 187, 220 I
Foreign Key · 313
FOREIGN KEY · 323 I · 69
FORM · 90 if · 158
fputs · 303 IMG · 79
FRAME · 86 implode · 251
FRAMESET · 85 in_array · 232
fread · 299 include · 209
free software · 27 INDEX · 366
FROM · 331 índices · 322
fscanf · 300 InnoDB · 365
FSF · 29 INSERT · 325
func_get_arg · 202 INT · 357

500
INTEGER · 357 metatags · 62
integridad referencial · 364 método GET · 144
Internet · 3 Método GET · 143
is_array · 118 método POST · 145
is_float · 118 Método POST · 143
is_int · 118 métodos · 270
is_object · 118 MIN · 335
is_string · 118 mktime · 187, 260
isset · 118 MySQL · 339
mysql_ free_result · 450
J mysql_affected_rows · 425, 450
MYSQL_ASSOC · 431
Java · 19 MYSQL_BOTH · 431
JavaScript · 18 mysql_close · 415
JSP · 21 mysql_connect · 414
mysql_db_query · 418
K mysql_error · 419
mysql_fetch_array · 431
krsort · 244 mysql_fetch_assoc · 431
ksort · 244 mysql_fetch_row · 424
mysql_field_len · 450
L mysql_field_name · 450
mysql_field_type · 450
LI · 71 mysql_insert_id · 424
list · 221 MYSQL_NUM · 431
LOAD DATA INFILE · 381 mysql_num_rows · 425, 450
localhost · 104 mysql_pclose · 416
mysql_pconnect · 416
M mysql_query · 417
mysql_select_db · 416
mail · 424 mysqld · 341
matriz · 215 mysqldump · 385
MAX · 335 mysqlimport · 381
max_execution_time · 181 mysqlshow · 341
MAX_FILE_SIZE · 308
MEDIUMINT · 357 N
META HTT-EQUIV · 63
META NAME · 65 natcasesort · 245
metaetiquetas · 62 natsort · 245

501
new · 277 operador Y · 130
NO ACTION · 324 operadores aritméticos · 124
NOT NULL · 325 operadores de bit · 127
NULL · 325 Operadores de comparación · 128
NUMERIC · 358 operadores de desplazamiento de bits ·
Números en coma flotante · 113 127
Números enteros · 113 operadores lógicos · 130
OPTION · 92
O or · 130
ORDER BY · 331, 333
objetos · 269
Objetos · 113 P
OL · 71
ON DELETE · 324, 374 P · 70
ON UPDATE · 379 PASSWORD · 351
open source · 2, 27 PHP · 23, 99
operación de negación · 130 phpinfo · 106
operador asignación · 125 phpmyadmin · 389
operador condicional · 130, 164 PRE · 70
operador de cast · 116 PRECISION · 358
operador de concatenación · 131 Primary Key · 313
Operador de conversión de tipo · 133 print · 106
operador de dirección · 203 print_r · 219
operador de ejecución · 132 print_r() · 198
operador de identidad · 128 prioridad de operadores · 133
operador de igualdad · 128 programación orientada a objetos · 269
operador de negación · 127
operador de negación de identidad · 128 Q
operador de negación de igualdad · 128
operador de supresión de error · 132 QUIT · 344
operador decremento · 124
operador diferencia · 124 R
operador división · 124
operador incremento · 124 rand · 182
operador O · 130 range · 234
operador O exclusivo · 130 REAL · 358
operador producto · 124 register_globals · 141
operador resto · 124 rename · 307
operador suma · 124 require · 209

502
return · 194 strlen · 259
rewind · 304 strnatcasecmp · 256
rsort · 245 strnatcmp · 256
strpos · 257
S strrchr · 256
strrev · 254
S · 69 strrpos · 257
SCRIPT · 108 strstr · 110, 257
script, insercción · 108 strtok · 258
secuencias de escape · 120 strtolower · 254
SELECT · 92, 330 strtoupper · 254
SELECT INTO OUTFILE · 386 SUB · 69
Servidor · 5 subclases · 281
servlets · 21 substr · 257
SET · 361 substr_count · 257
SET NULL · 324 substr_replace · 254
SET PASSWORD · 350 SUM · 335
setcookie · 286 SUP · 69
settype · 116 switch · 169
Shareware · 27
SHOW COLUMNS · 347 T
show databases · 345
SHOW TABLES · 347 TABLE · 76
shutdown · 341 TD · 77
SMALLINT · 357 tempnam · 445
sort · 245 TEXT · 360
SOURCE · 369 TEXTAREA · 91
SQL · 316 TH · 76
str_pad · 253 this · 275
STR_PAD_BOTH · 253 time · 260
STR_PAD_LEFT · 253 TIMESTAMP · 363
STR_PAD_RIGHT · 253 TINYINT · 357
str_repeat · 253 TITLE · 62
str_replace · 254 TR · 76
str_word_count · 252
strcasecmp · 256 U
strchr · 256
strcmp · 256 U · 69
stristr · 257 ucfirst · 255

503
ucwords · 255 variables · 114
UL · 73 ámbito · 206
unlink · 307 VBScript · 20
unset · 118, 204
UNSIGNED · 357 W
UPDATE · 329
USE · 346 W3C · 59
user · 346 web · 1, 4
WHERE · 331
V while · 175
wordwrap · 258
valores por defecto · 200
var · 273 X
VARCHAR · 359
variable xor · 130
estática · 208
global · 207 Z
local · 206
variable global · 117 ZEROFILL · 357
variable local · 117

504

You might also like