PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

Transcript of PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

Page 1: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

III

PHP y MySQLTecnologías para el desarrollo de

aplicaciones web

Page 2: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IV

Page 3: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

V

PHP y MySQLTecnologías para el desarrollo de

aplicaciones web

ÁNGEL COBO

PATRICIA GÓMEZ

DANIEL PÉREZ

ROCÍO ROCHA

Page 4: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

VI

©Á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 sutratamiento informático, ni la transmisión de ninguna forma o porcualquier medio, ya sea electrónico, mecánico por fotocopia, por registrou otros métodos, sin el permiso previo y por escrito de los titulares delCopyright.»

Ediciones Díaz de SantosInternet: http//www.diazdesantos.es/edicionesE-mail: [email protected]

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

Fotocomposición: P55 Servicios CulturalesDiseño de cubierta: P55 Servicios CulturalesImpresión: Fernández CiudadEncuadernación: Rústica-Hilo

Printed in Spain - Impreso en España

Page 5: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

VII

A Valeria

Page 6: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

VIII

Page 7: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IX

Índice

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

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

1. INTERNET Y LA PROGRAMACIÓN DE ORDENADORES ............. 11.1. INTRODUCCIÓN ............................................................................ 11.2. INTERNET ....................................................................................... 3

1.2.1. El servicio web ..................................................................... 41.2.2. Relación cliente/servidor ...................................................... 51.2.3. Proceso de creación y publicación de páginas web ............. 71.2.4. Dinamismo e interactividad en las páginas web .................. 8

1.3. PROGRAMACIÓN DE ORDENADORES ..................................... 91.3.1. Tipos de lenguajes de programación .................................... 11

1.4. PROGRAMACIÓN EN INTERNET ............................................... 151.4.1. Programación del lado del cliente vs programación del

lado del servidor ................................................................... 161.4.2. Tecnologías de programación del lado del cliente ................ 181.4.3. Tecnologías de programación del lado del servidor ............. 20

2. OPEN SOURCE Y SOFTWARE LIBRE .................................................. 252.1. INTRODUCCIÓN ............................................................................ 25

2.1.1 ¿Qué es open source? .......................................................... 27

Page 8: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

X

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

2.2. BREVE RESEÑA CRONOLÓGICA ............................................... 282.2.1. Primera etapa, antecedentes ................................................. 282.2.2. Segunda etapa, desarrollo .................................................... 282.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 ...................................................................................... 352.4.1. Licencias propietarias .......................................................... 362.4.2. Licencias libres .................................................................... 372.4.3. Licencias semilibres ............................................................. 38

2.5. SITUACIÓN ACTUA DEL SOFTWARE OPEN SOURCE ............ 402.5.1. Software open source, aplicaciones para todo .................... 402.5.2. Comunidades open source ................................................... 472.5.3. Usuarios de software open source ....................................... 48

2.6. VENTAJAS, INCONVENIENTES Y PERSPECTIVAS DEFUTURO ........................................................................................... 512.6.1. Ventajas ................................................................................ 512.6.2. Inconvenientes ...................................................................... 522.6.3 Perspectivas de futuro .......................................................... 52

3. CREACIÓN DE PÁGINAS WEB MEDIANTE ELLENGUAJE HTML ................................................................................. 553.1. INTRODUCCIÓN ............................................................................ 55

3.1.1. Definición de HTML ........................................................... 573.2. HISTORIA DE HTML ..................................................................... 583.3. SOFTWARE NECESARIO PARA TRABAJAR CON HTML ....... 60

3.3.1. Navegadores......................................................................... 603.3.2. Editores ................................................................................ 60

3.4. ESTRUCTURA DE UNA PÁGINA WEB ....................................... 623.4.1. Complementos a la estructura básica: metatags .................. 62

3.5. CARACTERÍSTICAS GENERALES DEL LENGUAJEY SINTAXIS DE SUS COMANDOS .............................................. 663.5.1. Caracteres especiales ........................................................... 67

3.6. COMANDOS BÁSICOS .................................................................. 683.6.1. Comandos de cabeceras para definición de títulos

y secciones ........................................................................... 683.6.2. Comandos de cambio de estilo de texto ............................... 683.6.3. Bloques de texto y párrafos ................................................. 693.6.4. Comandos para la generación de listas ................................ 71

Page 9: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XI

3.6.5. Creación de Tablas ............................................................... 763.6.6. Inserción de imágenes .......................................................... 793.6.7. Tratamiento del color ........................................................... 813.6.8. Enlaces o hipervínculos ....................................................... 82

3.7. MARCOS O FRAMES ...................................................................... 853.7.1. Construcción de páginas con marcos ................................... 853.7.2. Enlaces en páginas con marcos ............................................ 87

3.8. FORMULARIOS .............................................................................. 90

4. INTRODUCCIÓN A PHP .......................................................................... 994.1. EL LENGUAJE PHP ........................................................................ 994.2. ORÍGENES Y EVOLUCIÓN DEL LENGUAJE ............................. 1004.3. PROGRAMACIÓN EN PHP: PRIMEROS EJEMPLOS ................ 1024.4. FORMAS DE INCRUSTAR EL CÓDIGO PHP

EN LOS DOCUMENTOS HTML ................................................... 1084.5. ESCRITURA DEL CÓDIGO FUENTE PHP .................................. 111

4.5.1. Aspectos sobre la sintaxis del lenguaje ................................ 1114.5.2. Inserción de comentarios en el código ................................. 112

4.6. ELEMENTOS BÁSICOS DEL LENGUAJE ................................... 1134.6.1. Tipos de datos ...................................................................... 1134.6.2. Variables .............................................................................. 1144.6.3. Constantes ............................................................................ 1194.6.4. Cadenas de caracteres y variables ....................................... 1204.6.5. Operadores ........................................................................... 124

5. PHP Y LOS FORMULARIOS DE HTML ............................................... 1375.1. FORMULARIOS DE HTML ........................................................... 1375.2. ENVÍO DE DATOS A PROGRAMAS PHP .................................... 1395.3. MÉTODOS DE ACCESO A LAS VARIABLES

DEL FORMULARIO........................................................................ 1415.4. MÉTODOS DE TRANSFERENCIA DE DATOS

EN FORMULARIOS........................................................................ 1435.4.1. Método GET ........................................................................ 1445.4.2. Método POST ...................................................................... 1455.4.3. Diferencias entre ambos métodos ........................................ 146

5.5. TRANSFERENCIA DE DATOS AL SCRIPT DESDEEL URL ............................................................................................. 147

5.6. TRATAMIENTO DE FORMULARIOS CON LISTASDE SELECCIÓN MÚLTIPLE.......................................................... 153

ÍNDICE

Page 10: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XII

6. SENTENCIAS DE CONTROL ................................................................. 1576.1. INTRODUCCIÓN ............................................................................ 1576.2. ESTRUCTURAS CONDICIONALES ............................................ 158

6.2.1. Sentencia IF ......................................................................... 1586.2.2. La cláusula ELSE ................................................................ 1626.2.3. Sentencia If ... ELSEIF ... ELSE ......................................... 1656.2.4. Sintaxis alternativa de las sentencias IF .............................. 1676.2.5. Estructuras condicionales SWITCH ... CASE .................... 169

6.3. ESTRUCTURAS ITERATIVAS ...................................................... 1756.3.1. Sentencia WHILE ................................................................ 1756.3.2. Sentencia DO ... WHILE ..................................................... 1766.3.3. Sentencia FOR ..................................................................... 1796.3.4. Sentencia FOREACH .......................................................... 1876.3.5. Sentencias BREAK y CONTINUE ..................................... 188

7. DEFINICIÓN DE FUNCIONES ............................................................... 1937.1. ¿CÓMO SE DEFINEN FUNCIONES EN PHP?............................. 1937.2. LLAMADA A LAS FUNCIONES ................................................... 1967.3. ARGUMENTOS DE UNA FUNCIÓN ............................................ 199

7.3.1. Argumentos opcionales ........................................................ 1997.3.2. Argumentos con valores por defecto .................................... 2007.3.3. Listas de argumentos de longitud variable ........................... 2017.3.4. Paso de argumentos por valor o por referencia ................... 203

7.4. ÁMBITO DE LAS VARIABLES ..................................................... 2067.4.1. Variables locales .................................................................. 2067.4.2. Variables globales ................................................................ 2077.4.3. Variables estáticas ................................................................ 208

7.5. CLÁUSULAS INCLUDE Y REQUIRE ........................................... 2097.6. FUNCIONES VARIABLES ............................................................. 211

8. ARRAYS ............................................................................................. 2158.1. CONCEPTOS FUNDAMENTALES ............................................... 215

8.1.1. Construcción de arrays ........................................................ 2168.1.2. Arrays multidimensionales ................................................... 218

8.2. RECORRIDO DE TODOS LOS ELEMENTOS DE UNARRAY ............................................................................................. 219

8.3. FUNCIONES DE MANIPULACIÓN DE ARRAYS ....................... 2258.3.1. Transformación de los índices ............................................. 2258.3.2. Subdivisión .......................................................................... 226

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

Page 11: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XIII

8.3.3. Contabilización de elementos ............................................... 2278.3.4. Búsqueda de datos ............................................................... 2288.3.5. Generación de arrays ........................................................... 2328.3.6. Prolongación o truncamiento de un array ............................ 2378.3.7. Combinación de arrays ........................................................ 2388.3.8. Aplicación de funciones ....................................................... 2408.3.9. Ordenación de los elementos de un array ............................. 244

9. FUNCIONES PREDEFINIDAS ................................................................ 2499.1. INTRODUCCIÓN ............................................................................ 2499.2. FUNCIONES DE MANIPULACIÓN DE CADENAS

DE CARACTERES .......................................................................... 2509.2.1. Reconocimiento de caracteres .............................................. 2509.2.2. Conversiones entre cadenas y arrays ................................... 2509.2.3. Prolongación de una cadena................................................. 2539.2.4. Modificación de una cadena ................................................ 2549.2.5. Comparación de cadenas ..................................................... 2569.2.6. Búsqueda de datos ............................................................... 2569.2.7. Subdivisión de cadenas ........................................................ 2589.2.8. Longitud de una cadena ....................................................... 259

9.3. FUNCIONES DE FECHA Y HORA ................................................ 2599.4. FUNCIONES MATEMÁTICAS ...................................................... 267

10. PROGRAMACIÓN ORIENTADA A OBJETOS ................................... 26910.1. INTRODUCCIÓN ............................................................................ 26910.2. DEFINICIÓN DE UNA CLASE ...................................................... 272

10.2.1. Constructores ....................................................................... 27510.3. CONSTRUCCIÓN DE OBJETOS ................................................... 277

10.3.1. Acceso a las variables y métodos del objeto ........................ 27810.4. HERENCIA ...................................................................................... 281

10.4.1. Definición de subclases ........................................................ 283

11. COOKIES ............................................................................................. 28511.1. ¿QUÉ SON LAS COOKIES? ........................................................... 28511.2. GENERACIÓN DE COOKIES ........................................................ 28611.3. RECUPERACIÓN DE LOS VALORES DE LAS COOKIES ........ 28811.4. COOKIES DE SESIÓN Y COOKIES PERMANENTES ............... 29111.5. VISIBILIDAD DE LAS COOKIES EN EL SITIO WEB ................ 294

ÍNDICE

Page 12: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XIV

12. MANEJO DE FICHEROS ........................................................................ 29512.1. MECANISMOS DE ALMACENAMIENTO DE DATOS .............. 29512.2. OPERACIONES DE MANIPULACIÓN DE FICHEROS .............. 296

12.2.1. Apertura y cierre de ficheros ............................................... 29612.2.2. Operaciones de lectura de datos ........................................... 29812.2.3. Lectura con formato ............................................................. 30012.2.4. Operaciones de escritura de datos ........................................ 30312.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 ............ 30913.1. INTRODUCCIÓN ............................................................................ 30913.2. DISEÑO DE BASES DE DATOS .................................................... 310

13.2.1. Modelo relacional ................................................................ 31013.2.2. Diagramas entidad/relación ................................................. 311

13.3. UN EJEMPLO ILUSTRATIVO: CINEM@S .................................. 31113.4. EL LENGUAJE SQL ........................................................................ 316

13.4.1. Introducción ......................................................................... 31613.4.2. Sentencias de definición de datos ......................................... 31713.4.3. La sentencia INSERT .......................................................... 32413.4.4. La sentencia DELETE ......................................................... 32813.4.5. La sentencia UPDATE ......................................................... 32913.4.6. La sentencia SELECT ......................................................... 330

14. EL SISTEMA GESTOR DE BASES DE DATOS MYSQL .................. 33914.1. ¿QUÉ ES MYSQL? .......................................................................... 33914.2. UTILIZACIÓN DE MYSQL ............................................................ 340

14.2.1. Arranque del servidor MySQL ............................................ 34014.2.2. Inicio del monitor de MySQL .............................................. 342

14.3. EJECUCIÓN DE SENTENCIAS SQL ............................................ 34414.4. GESTIÓN DE USUARIOS .............................................................. 346

14.4.1. La tabla USER ..................................................................... 34614.4.2. Eliminación de usuarios ....................................................... 34914.4.3. Establecimiento de contraseñas para los usuarios ............... 35014.4.4. Creación de nuevos usuarios................................................ 352

14.5. BASES DE DATOS Y TABLAS EN MYSQL ................................. 35414.6. TIPOS DE DATOS ........................................................................... 356

14.6.1. Tipos Numéricos .................................................................. 356

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

Page 13: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XV

14.6.2. Tipos cadena de caracteres .................................................. 35914.6.3. Tipos enum y set .................................................................. 36114.6.4. Tipos fecha/hora .................................................................. 362

14.7. INTEGRIDAD REFERENCIAL EN MYSQL ................................ 36414.7.1. Definición de claves foráneas .............................................. 36514.7.2. Inserción de registros en tablas relacionadas ....................... 37214.7.3. Eliminación de registros en tablas relacionadas .................. 37314.7.4. Actualización de registros en tablas relacionadas................ 379

14.8. IMPORTACIÓN Y EXPORTACIÓN de datos ................................. 38114.8.1. Importación de datos ............................................................ 38114.8.2. Exportación de datos............................................................ 385

15. PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB ......................................................... 38915.1. INTRODUCCIÓN ............................................................................ 38915.2. ENTRADA A PHPMYADMIN ........................................................ 39015.3. GESTIÓN DE BASES DE DATOS ................................................. 392

15.3.1. Consulta de las bases de datos ............................................. 39215.3.2. Manipulación de las tablas .................................................. 39315.3.3. Estructura de las tablas ........................................................ 398

15.4. CREACIÓN DE NUEVAS BASES DE DATOS ............................. 40015.4.1. Creación de tablas ................................................................ 401

15.5. OPERACIONES DE IMPORTACIÓN Y EXPORTACIÓNDE DATOS ....................................................................................... 40315.5.1. Importación de datos externos en las tablas ........................ 40315.5.2. Exportación de datos............................................................ 405

15.6. GESTIÓN DE USUARIOS .............................................................. 40715.6.1. Usuarios y privilegios .......................................................... 40715.6.2. Creación de usuarios ............................................................ 408

16. CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP ........ 41316.1. INTRODUCCIÓN ............................................................................ 41316.2. CONEXIÓN CON MYSQL DESDE PHP ....................................... 414

16.2.1. Apertura de la conexión ....................................................... 41416.2.2. Cierre de la conexión ........................................................... 415

16.3. SELECCIÓN DE LA BASE DE DATOS ........................................ 41616.4. EJECUCIÓN DE SENTENCIAS SQL SOBRE LA BASE

DE DATOS SELECCIONADA ........................................................ 417

ÍNDICE

Page 14: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XVI

16.4.1. Inserción de datos a través de formularios........................... 41916.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 .......................................................... 45317.1. INTRODUCCIÓN ............................................................................ 45317.2. ESTRUCTURA DE LA TABLA DE LA BASE DE DATOS .......... 45417.3. GENERACIÓN DE LA PÁGINA PRINCIPAL DE LOS FOROS .... 45517.4. CONSULTA DE UN MENSAJE CON SUS RESPUESTAS .......... 45817.5. INSERCIÓN DE NUEVOS MENSAJES ........................................ 460

18. SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL ....... 46518.1. INTRODUCCIÓN ............................................................................ 46518.2. GESTORES DE CONTENIDO ....................................................... 466

18.2.1. Funcionamiento .................................................................... 46818.2.2. Características ..................................................................... 46818.2.3. Ventajas e inconvenientes ..................................................... 470

18.3. GESTORES DE CONTENIDO BASADOS EN PHPY MYSQL ......................................................................................... 47118.3.1. PHP-NUKE ......................................................................... 47118.3.2. POSTNUKE ........................................................................ 47318.3.3. MAMBO SERVER.............................................................. 47418.3.4. PHPWEBSITE .................................................................... 47518.3.5. PHP-WCMS ........................................................................ 47618.3.6. XOOPS ................................................................................ 47718.3.7. DRUPAL .............................................................................. 47818.3.8. SITEFRAME ....................................................................... 479

18.4. OTRAS SOLUCIONES OPEN SOURCE ....................................... 48018.4.1. Weblogs ................................................................................ 48018.4.2. Sistemas de foros ................................................................. 48418.4.3. Plataformas de e-learning ................................................... 48618.4.4. Entornos de comercio electrónico ........................................ 48818.4.5. Sistemas de atención al cliente ............................................. 49018.4.6. Herramientas de gestión de proyectos .................................. 49318.4.7. Otras herramientas ............................................................... 495

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

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

Page 15: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XVII

Prefacio

El presente libro aborda una temática de plena actualidad y de gran auge enlos últimos años, como es el uso de soluciones open source para el desarrollode aplicaciones web. El uso conjunto del lenguaje PHP y el sistema gestor debases de datos MySQL permite la construcción, de una manera sencilla yeficiente, 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íaspara el desarrollo de sus portales; incluso, en el caso de particulares, algunosde los servicios gratuitos de alojamiento de páginas web ofrecen la posibilidadde 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 presentelibro. Parte del material que incluye ha sido usado exitosamente para laimpartición de varios cursos de verano y un módulo de desarrollo de aplicacionesweb 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 personascon conocimientos muy básicos de lenguajes de programación y con inquietudespor 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 claramentevocacional; este tipo de libros va dirigido a ellos.

Page 16: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XVIII

Es por ello que se ha buscado un enfoque eminentemente práctico, ilustrandolos diferentes conceptos con un gran número de ejemplos. De hecho, se pretendeque a lo largo de los diferentes capítulos se vaya describiendo paso a paso todoel 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 empresaficticia; en concreto consideraremos el sitio web de un multicine que hemosbautizado como «Cinem@s» y que ofrecerá la posibilidad de consultar cartelerasdinámicas (mostrando siempre la información actualizada), consultardisponibilidades de localidades, registrarse como cliente,...

El libro comienza con una rápida presentación de las características generalesde 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 conocidacomo corriente open source. El tercer capítulo tiene por objeto presentar loscomandos básicos del lenguaje HTML que permitan diseñar unas sencillaspá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óndel lenguaje PHP, su interacción con los formularios de HTML, así como apresentar las estructuras básicas presentes en todo lenguaje de programación(sentencias de control, funciones y estructuras de datos). Se ha dedicado tambiénun 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 loque se ha considerado oportuno introducir un capítulo previo de estudio delmodelo relacional de bases de datos y el lenguaje SQL. Tras analizar lascaracterísticas de MySQL se muestra cómo es posible la administración remotade las bases de datos mediante una aplicación desarrollada en PHP. Una vezanalizada esta aplicación de administración, los siguientes capítulos muestranla sencillez de los procesos de conectividad a MySQL desde PHP.

El libro finaliza con un capítulo en el que se presentan muy brevementealgunas de las aplicaciones open source más conocidas en Internet y que sebasan en las tecnologías explicadas en el libro. Llegado a este punto se esperaque el lector pueda no solo hacer uso de esas aplicaciones, sino tambiénmodificarlas y adaptarlas a sus necesidades particulares, aprovechando de estaforma la gran ventaja de las aplicaciones de código abierto.

Finalmente, quisiéramos mostrar nuestro agradecimiento a los Departamentosde Matemática Aplicada y Ciencias de la Computación y de Administración deEmpresas de la Universidad de Cantabria por sus facilidades y apoyo para escribir

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

Page 17: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XIX

este libro. Agradecimiento que hacemos extensivo a todos nuestros alumnosdurante estos años; ellos nos han servido de incentivo para embarcarnos eneste proyecto editorial.

Ángel CoboPatricia GómezDaniel PérezRocío Rocha

Santander, febrero de 2005

PREFACIO

Page 18: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

XX

¡ALERTA!

Page 19: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

1

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

Page 20: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

2

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

Page 21: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

3

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

Page 22: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

4

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

Page 23: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

5

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.

Page 24: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

6

— 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

Page 25: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

7

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

Page 26: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

8

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.

Page 27: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

9

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

Page 28: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

10

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.

Page 29: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

11

— 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

Page 30: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

12

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

Page 31: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

13

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)

0110110111010111101000111....

if(x<0) return 1;else ...

Traducción

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

Page 32: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

14

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

Page 33: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

15

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.

Page 34: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

16

— ¿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 VSPROGRAMACIÓ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

Page 35: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

17

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

pero se ejecutan en el cliente — Los programas residen y son ejecutados

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 transmisión por la red del código necesario para ello

— Al cliente solo se les transfiere el resultado de la ejecución del programa

— Las respuestas a las acciones de los usuarios sobre el programa pueden ser invocadas sin necesidad de realizar transmisiones por la red

— Una vez enviada al usuario la respuesta del programa, cualquier petición adicional del cliente requiere una nueva conexión con el servidor y la ejecución en él de un nuevo programa

— Para la correcta ejecución del programa se requiere que el cliente tenga instalados programas o plug-ins adecuados

— En los equipos de los clientes no se necesita ningún software especial, todo lo necesario debe estar instalado en el servidor

— Si en un cliente no está instalado alguno de los programas intérpretes o plug-ins, la página no se ejecutará correctamente

— Todos los clientes podrán visualizar correctamente la página

— Al transferirse el código, el cliente tiene acceso a dicho código y puede obtener a partir de él información que pueda resultar comprometida

— El código fuente permanece en el servidor, se conserva su privacidad y los clientes no tienen acceso a él

— Se pueden integrar los programas en las páginas alojadas en cualquier servidor web

— La mayoría de los servicios de alojamiento gratuito de páginas no admiten este tipo de programación

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

Page 36: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

18

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.

Page 37: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

19

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.

Page 38: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

20

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.

Page 39: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

21

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.

Page 40: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

22

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.

Page 41: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTERNET Y LA PROGRAMACIÓN DE ORDENADORES

23

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.

Page 42: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 43: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

25

OPEN SOURCE Y SOFTWARE LIBRE

2.1. INTRODUCCIÓN

El actual entorno mundial está claramente caracterizado por el fenómeno de la globalización1, 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).

Page 44: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

26

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

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.

Segmentos 2003 Diciembre

2004Noviembre

% Cto 03/04

Previsión2005

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

Page 45: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

27

aplicaciones con la aparición de la corriente denominada free software u opensource, 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

Page 46: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

28

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.

Page 47: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

29

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.

Page 48: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

30

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 sourceInitiative (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 opensource 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 opensource.

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.

Page 49: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

31

1984 Richard Stallman crea el proyecto GNU.

1985 Los componentes del proyecto GNU crean la FSF (free softwareFoundation).

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 (opensource Initiative).

1998 Bruce Parents miembro de OSI establece la definición de opensource.

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

Page 50: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

32

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

Page 51: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

33

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

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

Page 52: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

34

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

Page 53: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

35

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.

Page 54: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

36

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.

Page 55: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

37

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

9Así queda regulado en el artículo 25.3 de la Ley de Propiedad Intelectual RDL 1/1996 de 12 de abril. 10La 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.11Copyleft 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.

Page 56: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

38

— 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

Page 57: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

39

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

Page 58: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

40

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.

Page 59: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

41

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

Page 60: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

42

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

Page 61: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

43

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.

Page 62: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

44

— 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 MicrosoftOutlook, se tienen varias opciones, las más reconocidas Evolution y MozillaThunderbird, 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.

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

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

Page 63: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

45

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 httpde otros ordenadores y satisfacerlas sirviendo páginas web.

Algunos de los servidores web open source más conocidos son: Apache, AOLServer, 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

Page 64: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

46

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 Accesscontinúan dominando el desarrollo de bases de datos, pero las bases de datos opensource 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.

Page 65: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

47

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

Page 66: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

48

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 Usuariosregistrados

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

Page 67: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

49

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

16Información tomada de Netcraft, empresa britanica de servicios de Internet reconocida internacionalmente por sus estudios sobre la Red.17La ú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.

Page 68: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

50

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

Page 69: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

51

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.

Page 70: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

52

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

Page 71: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

OPEN SOURCE Y SOFTWARE LIBRE

53

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.

Page 72: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 73: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

55

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

Page 74: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

56

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

Page 75: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

57

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

NOTA

Page 76: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

58

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.

Page 77: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

59

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.

Page 78: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

60

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.

Page 79: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

61

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)

Page 80: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

62

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

Page 81: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

63

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

Page 82: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

64

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/

Page 83: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

65

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.

Page 84: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

66

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, yWIDTH, que marca la longitud de la línea.

Page 85: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

67

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

&amp;

&iquest;

&Aacute;

&Eacute;

&Iacute;

&Oacute;

&Uacute;

&Auml;

&Ntilde;

>

"

i

á

é

í

ó

ú

ä

ñ

&gt;

&quot;

&iexcl;

&aacute;

&eacute;

&iacute;

&oacute;

&uacute;

&auml;

&ntilde;

Tabla 3.1 Caracteres especiales en HTML

Page 86: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

68

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

Page 87: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

69

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:

Page 88: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

70

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

El comando <P> admite el parámetro ALIGN, cuyo valor puede ser LEFT, RIGHTo 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>

Page 89: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

71

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>

Page 90: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

72

<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

Page 91: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

73

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>

Page 92: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

74

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:

Page 93: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

75

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

NOTA

Page 94: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

76

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

Page 95: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

77

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.

Page 96: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

78

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

Page 97: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

79

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

Page 98: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

80

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

Page 99: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

81

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 #000000Azul #0000FF Verde #00FF00Ciano #00FFFF Verde mar #238E6BAzul cielo #3299CC Verde oscuro #2F4F2FVioleta #4F2F4F Verde lima #32CC32Gris #C0C0C0 Salmón #6F4242Turquesa #7093DB Marrón #A52A2ARosa #BC8F8F Naranja #CC3232Oro #CC7F32 Rojo #FF0000Magenta #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.

Page 100: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

82

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

Page 101: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

83

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>

Page 102: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

84

</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:[email protected]">Enviar mensaje</A>

Page 103: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

85

Como se pueda apreciar, el valor de HREF es en este caso la palabra MAILTOseguida 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.

Page 104: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

86

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.

Page 105: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

87

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

Page 106: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

88

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>

Page 107: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

89

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

Page 108: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

90

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

Page 109: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

91

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

Page 110: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

92

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>

Page 111: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

93

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

Page 112: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

94

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

Page 113: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

95

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

Page 114: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

96

Figura 3.7 Área de clientes de Cinem@s

Page 115: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

97

Figura 3.8 Formulario para el envío de mensajes al foro

Page 116: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 117: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

99

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

Page 118: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

100

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

Page 119: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

101

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

Page 120: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

102

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.

Page 121: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

103

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.

Page 122: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

104

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

Page 123: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

105

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

NOTA

Page 124: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

106

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

Page 125: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

107

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><?PHPprint(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

Page 126: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

108

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

o

<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

Page 127: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

109

<%...........................................................................%>

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:

<?phpif ($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:

<?phpif ($x<0) { ?><B> Valor negativo </B> <BR> Vuelva a intentarlo <?php

Page 128: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

110

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

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

Page 129: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

111

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.

Page 130: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

112

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.

Page 131: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

113

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.

Page 132: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

114

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;

Page 133: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

115

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.

Page 134: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

116

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.

Page 135: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

117

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; ...........?>...........<?PHP...........$asiento = "F$fila.$num";...........?>

En este caso el documento incluye dos scripts, en el primero se definen dos variables que, al ser globales, pueden ser utilizadas posteriormente en un segundo script.

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 globaldelante de su nombre.

Ejemplo 4.11:

$precio = 4.5;

function calcular_importe($num_entradas) { global $precio; $i = $precio * $num_entradas; return $i; }

Page 136: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

118

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.

Page 137: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

119

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.

Page 138: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

120

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

Page 139: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

121

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)

Page 140: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

122

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.

Page 141: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

123

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

Page 142: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

124

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

Page 143: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

125

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:

$n = 5; $m = ++$n;

En este caso la variable $n tomará el valor 5 mientras que $m tendrá el valor 6, ya que el operador de incremento delante de $n hace que el incremento se realice antes de efectuar la asignación a $m..

$z = 4; $v = 2*$z--; $w = $z;

Los valores finales de las variables serán 4, 8 y 3 para $z, $v y $w, respectivamente. En este caso, en la segunda sentencia se utiliza el operador de decremento después de la variable, por lo que el decremento se produce después de realizar la asignación.

$a = 10; $b = 2*--$a; $c = ++$a-$b--;

Tras ejecutar estas tres sentencias la variable $atendría el valor 10, la variable $b valdría 17 y $cvaldrí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

Page 144: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

126

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

Page 145: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

127

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

Page 146: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

128

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

Page 147: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

129

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

Page 148: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

130

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 $x && $y

Devuelve un valor cierto cuando tanto $xcomo $y tienen el valor cierto (operación Y)

$x or $y $x || $y

Devuelve un valor cierto cuando $x o $ytienen el valor cierto (operación O)

$x xor $y Devuelve un valor cierto cuando $x o $ytienen 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.

Page 149: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

131

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

Page 150: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

132

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:

Page 151: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

133

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

Page 152: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

134

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.

Page 153: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

INTRODUCCIÓN A PHP

135

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:

Page 154: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

136

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

NOTA

Page 155: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

137

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:[email protected]" METHOD="post"> .............................................................................................</FORM>

Page 156: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

138

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.

Page 157: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

139

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

Page 158: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

140

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

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

NOTA

$edad$estudiante Procesar.php

Page 159: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

141

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.

Page 160: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

142

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

Page 161: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

143

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.

Page 162: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

144

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:

Page 163: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

145

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

Page 164: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

146

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

Page 165: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

147

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

Page 166: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

148

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.

Page 167: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

149

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

Page 168: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

150

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

Page 169: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

151

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

Page 170: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

152

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

Page 171: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

153

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

Page 172: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

154

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

Page 173: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHP Y LOS FORMULARIOS DE HTML

155

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.

Page 174: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 175: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

157

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.

Page 176: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

158

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

NOTA

Page 177: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

159

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

Page 178: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

160

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

Page 179: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

161

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.

Page 180: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

162

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.

Page 181: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

163

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;

Page 182: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

164

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 12pero $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 realizar sencillas asignaciones en las que el valor asignado dependa del resultado de una condición.

NOTA

Page 183: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

165

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.

Page 184: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

166

Ejemplo 6.12:

La siguiente estructura condicional asigna diferente valor a la variable $precioen 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 elseif, a pesar de tener diferente significado sintáctico (en el primer caso se estaría

Page 185: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

167

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

NOTA

Page 186: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

168

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

NOTA

Page 187: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

169

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:

Page 188: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

170

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

Page 189: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

171

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

NOTA

Page 190: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

172

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;

Page 191: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

173

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.

Page 192: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

174

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

Page 193: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

175

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.

Page 194: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

176

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;

Page 195: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

177

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

Page 196: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

178

+=

imparesnsinparesnsin

nf2/)13(

2/)(

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

Page 197: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

179

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;

Page 198: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

180

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

Page 199: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

181

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

NOTA

Page 200: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

182

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:

Page 201: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

183

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

Page 202: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

184

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>

Page 203: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

185

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

Page 204: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

186

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

Page 205: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

187

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.

Page 206: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

188

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, LuisBienvenido, PedroBienvenido, AnaBienvenido, 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)

Page 207: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

189

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 $jtome 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 12: 10 9 8 7 6 5 4 3 23: 10 9 8 7 6 5 4 34: 10 9 8 7 6 5 45: 10 9 8 7 6 56: 10 9 8 7 67: 10 9 8 78: 10 9 89: 10 910: 10

Page 208: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

190

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

Page 209: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SENTENCIAS DE CONTROL

191

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.

Page 210: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

192

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)

Page 211: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

193

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

Page 212: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

194

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

Page 213: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

195

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

Page 214: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

196

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

Page 215: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

197

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.

<?PHPfunction GeneraArray($min,$max) {

Page 216: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

198

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

Page 217: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

199

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.

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

Page 218: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

200

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

NOTA

Page 219: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

201

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.

Page 220: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

202

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

Page 221: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

203

print suma(1,5,7,2) . "<BR>"; print suma() . "<BR>";

generarían como resultado:

13150

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.

Page 222: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

204

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

Page 223: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

205

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

Page 224: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

206

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;

Page 225: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

207

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 }

Page 226: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

208

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

Page 227: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

209

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.

Page 228: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

210

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

Page 229: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

211

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.

Page 230: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

212

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

Page 231: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

DEFINICIÓN DE FUNCIONES

213

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.

Page 232: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 233: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

215

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

Page 234: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

216

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

Page 235: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

217

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

Page 236: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

218

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

NOTA

Page 237: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

219

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)

Page 238: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

220

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

Page 239: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

221

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.

Page 240: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

222

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

Page 241: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

223

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.

Page 242: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

224

Figura 8.1 Tabla de distancias kilométricas

<?phpinclude("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];

Page 243: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

225

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

Page 244: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

226

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

Page 245: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

227

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

Page 246: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

228

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

Page 247: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

229

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

Page 248: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

230

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.

Page 249: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

231

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

Page 250: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

232

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:

Page 251: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

233

$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

Page 252: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

234

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.

Page 253: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

235

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

Page 254: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

236

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

Page 255: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

237

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

Page 256: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

238

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

Page 257: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

239

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

Page 258: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

240

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

Page 259: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

241

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

Page 260: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

242

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

Page 261: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

243

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.

Page 262: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

244

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:

Page 263: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

245

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

Page 264: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

246

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

Page 265: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

ARRAYS

247

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 directoresfor($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>";

Page 266: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

248

Figura 8.4 Página con la tabla de películas disponibles

Page 267: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

249

FUNCIONESPREDEFINIDAS

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

Page 268: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

250

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:

Page 269: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

251

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

Page 270: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

252

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)

Page 271: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

253

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.

Page 272: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

254

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): dadauna cadena inicial se obtiene una nueva cadena como resultado de reemplazar la porción delimitada por los argumentos posición y longitud, por el

Page 273: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

255

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.

Page 274: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

256

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

Page 275: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

257

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:

Page 276: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

258

$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"); 3strpos($cadena,"e",14); 16strpos($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)

Page 277: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

259

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.

Page 278: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

260

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

Page 279: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

261

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

Page 280: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

262

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

Page 281: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

263

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

Page 282: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

264

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

Page 283: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

265

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

<?phpinclude("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

Page 284: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

266

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

<?phpinclude("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

<?phpinclude("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.

Page 285: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

FUNCIONES PREDEFINIDAS

267

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,...)min(array)

Obtiene el menor valor de un número determinado de 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,…)max(array)

Obtiene el mayor valor de un número determinado de 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)mt_rand(mín,máx)

Si no toman argumentos, estas funciones devuelven 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

Page 286: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

268

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

Page 287: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

269

PROGRAMACIÓNORIENTADA 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.

Page 288: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

270

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

Page 289: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

271

VARIABLES: • Título• Director• Actores• Año

MÉTODO:• Generar ficha

PELÍCULA

Figura 10.1 Estructura de un objeto Película

VARIABLES: • Día• Hora• Película

MÉTODO:• Asignar película

PROYECCIÓN

Figura 10.2 Estructura de un objeto Proyección

VARIABLES: • Nombre • Edad• Lista proyecciones

MÉTODO:• Adquirir entrada

CLIENTE

Figura 10.3 Estructura de un objeto Cliente

Page 290: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

272

CINE

VARIABLES: • Día del espectador • Tarifa normal • Tarifa reducida • Proyecciones • Clientes

MÉTODOS: • Buscar cliente • Calcular importe • Crear proyección • Crear cliente

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.

Page 291: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

273

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;

Page 292: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

274

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

NOTA

Page 293: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

275

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;

Page 294: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

276

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

Page 295: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

277

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

Page 296: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

278

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 -> variableObjeto -> 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. BogartM. Astor

Page 297: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

279

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

Page 298: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

280

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

Page 299: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

281

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

Page 300: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

282

PELÍCULA

MUSICALPOLICIACA COMEDIA

Figura 10.5 Subclases de la clase película

VARIABLES PROPIAS:• Número de socio • Puntos acumulados

MÉTODOS PROPIOS: • Adquirir entrada (*) • Canjear regalo

SOCIO

VARIABLES: • Nombre • Edad• Lista proyecciones

MÉTODO:• Adquirir entrada

CLIENTE

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.

Page 301: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PROGRAMACIÓN ORIENTADA A OBJETOS

283

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;

Page 302: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

284

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

Page 303: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

285

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,

Page 304: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

286

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)

Page 305: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

COOKIES

287

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>

Page 306: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

288

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;

Page 307: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

COOKIES

289

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

Page 308: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

290

?>........................................................................</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"]

Page 309: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

COOKIES

291

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

Page 310: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

292

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

Page 311: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

COOKIES

293

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.

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

Page 312: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

294

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

Page 313: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

295

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

Page 314: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

296

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

Page 315: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

297

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:

Page 316: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

298

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

Page 317: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

299

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

Page 318: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

300

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:

Page 319: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

301

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

Page 320: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

302

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.

Page 321: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

303

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

Page 322: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

304

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.

Page 323: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

305

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

Page 324: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

306

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/2004Comentario:Deberían hacer un esfuerzo por mejorar la limpieza de los aseos-------------------Fecha: 14/10/2004Comentario: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 {

Page 325: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

MANEJO DE FICHEROS

307

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"

Page 326: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

308

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

Page 327: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

309

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.

Page 328: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

310

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

Page 329: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

311

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

Page 330: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

312

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

NOTA

Page 331: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

313

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

Page 332: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

314

ENTIDAD PELÍCULASNombre de atributo Tipo de datos Descripción

IDPELICULA Número entero Valor numérico que actuará de identificador de cada película

TITULO Cadena de caracteres Título de la película

ACTORES Cadena de caracteres Listado de actores de la película que se presentarán separados por comas

PRODUCCION Cadena de caracteres Productor, o productores, en su caso, de 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

GENERO Cadena de caracteres Género de la película elegido entre una serie de opciones predeterminadas: drama, comedia, acción....

EDAD_RESTRICCION Cadena de caracteres Opción que establece restricciones de 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 Imagen del cartel promocional de la película

Tabla 13.1 Atributos de la entidad Películas

ENTIDAD PROYECCIONESNombre de atributo Tipo de datos Descripción

IDPROY Número entero Valor numérico que actuará de identificador de cada proyección

IDPELICULA Número entero Valor numérico que identifica la película que se proyectará

NUM_SALA Número entero Número de la sala en donde se proyectará la película

HORA Hora Hora de inicio de la proyección FECHA Fecha Fecha de la proyección

TARIFA_REDUCIDA Lógico(verdadero/falso)Indica si la proyección tiene o no una tarifa reducida, por ejemplo, sesiones matinales, proyecciones especiales,...

ESTRENO Lógico(verdadero/falso) Indica si la proyección es emitida como estreno o no

Tabla 13.2 Atributos de la entidad Proyecciones

Page 333: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

315

ENTIDAD SALASNombre de atributo Tipo de datos Descripción

NUM_SALA Número entero Valor numérico identificativo de cada 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

OBSERVACIONES Cadena de caracteres Cadena de caracteres que permitirá almacenar cualquier tipo de observación sobre la sala

Tabla 13.3 Atributos de la entidad Salas

ENTIDAD ENTRADASNombre de atributo Tipo de datos Descripción

NUM_ENTRADA Número entero Valor numérico que actuará de identificador de cada entrada

IDPROY Número entero Valor numérico que identifica la 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 Número entero Valor numérico que identifica al cliente que compra la entrada

RECOGIDA Lógico(verdadero/falso) Indica si la entrada ha sido recogida o no por el cliente

Tabla 13.4 Atributos de la entidad Entradas

ENTIDAD CLIENTESNombre de atributo Tipo de datos Descripción

NUM_CLIENTE Número entero Valor de tipo numérico que actuará de 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

PUNTOS_ACUM Número entero

Valor numérico que almacenará el número total de puntos que va acumulando el espectador por la compra de entradas

CLAVE Cadena de caracteres Indica una clave secreta que el cliente tendrá que utilizar para realizar cualquier operación de compra de entradas

Tabla 13.5 Atributos de la entidad Clientes

Page 334: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

316

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:

Page 335: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

317

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

Page 336: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

318

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

NOTA

Page 337: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

319

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

Page 338: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

320

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,

Page 339: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

321

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

NOTA

Page 340: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

322

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

Page 341: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

323

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,

Page 342: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

324

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

NOTA

Page 343: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

325

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

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', '[email protected]', 0, 'lmr65b');

Page 344: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

326

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 [email protected], 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 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', '[email protected]', '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

NOTA

Page 345: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

327

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.

Page 346: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

328

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 WHEREIDPELICULA = (SELECT IDPELICULA FROM PELICULAS WHERE

TITULO = 'Refugio en el paraíso');

Page 347: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

329

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 =

Page 348: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

330

(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 ó 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] itemsFROM 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:

NOTA

Page 349: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

331

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;

Page 350: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

332

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

Page 351: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

333

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

Page 352: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

334

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;

Page 353: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

335

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

NOTA

Page 354: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

336

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;

Page 355: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

337

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

Page 356: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 357: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

339

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.

Page 358: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

340

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

Page 359: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

341

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 Administrativas, en concreto, el apartado de servicios. NOTA

Page 360: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

342

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

Page 361: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

343

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.

Page 362: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

344

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

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

Una vez dentro del monitor de MySQL, se pueden ejecutar directamente sentencias SQL de manera interactiva.

NOTA

Page 363: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

345

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)

Page 364: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

346

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,

Page 365: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

347

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

Page 366: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

348

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

'SPECIFIED') No

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

Page 367: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

349

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)

Page 368: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

350

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 rootcuando se conecte desde el propio servidor local, la sentencia sería:

Page 369: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

351

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 localhosttiene 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 UPDATEpara 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 mysqladmindesde fuera del monitor MySQL.

Page 370: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

352

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.

Page 371: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

353

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

Page 372: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

354

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

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)

Page 373: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

355

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)

Page 374: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

356

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.

Page 375: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

357

Tipos Enteros

Nombre Rango Almacenamiento Descripción

TINYINT -128 a 127 1 byte Entero pequeño

BIT 0 o 1 1 bit Entero 0 o 1

BOOL 0 o 1 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 9223372036854775807

8 bytes Entero grande

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 TINYINTvariará 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 ZEROFILLautomáticamente se le asignará UNSIGNED.

Page 376: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

358

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 ±3.402823466E+38

4 bytes Coma flotante de precisión

única.

DOUBLE ±1.797693134862315E+308a ±2.2507385850720E-308

8 bytes Coma flotante de precisión

única.

PRECISIONREAL Sinónimos de double

DECIMALNUMERICDEC

Un byte para cada dígito del número

Número de coma flotante almacenado como cadena de

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.

Page 377: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

359

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

Page 378: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

360

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

NOTA

Page 379: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

361

Nombre Longitud máxima de caracteres Almacenamiento Descripción

CHAR 1 1 bytes Un carácter.

CHAR(N) 255 N bytes Cadena de longitud fija de N

caracteres.

VARCHAR(N) 255 N+1 bytes Cadena de longitud variable de

N caracteres.

TINYTEXTTINYBLOB 255 L+1 bytes

Cadenas u objetos binarios de tamaño pequeño

TEXTBLOB 65.535 L+2 bytes

Cadenas u objetos binarios de tamaño normal

MEDIUMTEXTMEDIUMBLOB

16.777.215 (1,6 MB)

L+3 bytes Cadenas u objetos binarios de

tamaño mediano

LONGTEXTLONGBLOB

4.294.967.295 (4,2 GB)

L+4 bytes Cadenas u objetos binarios de

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.

Page 380: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

362

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

NOTA

Page 381: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

363

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

Nombre Rango Tamaño de almacenamiento Descripción

DATE 1000-01-019999-12-31

3 bytes Almacena una fecha con el

formatoYYYY-MM-DD

TIME -838:59:59838:59:59

3 bytes Almacena una hora con el

formatoHH:MM:SS

DATETIME 1000-01-01 00:00:00 9999-12-31 23:59:59

8 bytes Almacena una fecha y una hora

con el formatoYYYY-MM-DD HH:MM:SS

TIMESTAMPTIMESTAMP(M)

1970-01-01 00:00:00 2037-01-01 00:00:00

4 bytes Instante de tiempo, combinación de fecha y hora según diferentes formatos

YEAR(2) 70-69 (de 1970 a 2069) 1 byte Almacena un año con dos dígitos (p.e. 97 corresponde a 1997)

YEARYEAR(4) 1901 - 2155 1 byte

Almacena un año con cuatro 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.

NOTA

Page 382: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

364

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)

Page 383: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

365

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

Page 384: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

366

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

Page 385: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

367

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;

Page 386: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

368

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;

Page 387: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

369

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)

Page 388: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

370

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

NOTA

Page 389: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

371

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 PROYECCIONESquedará identificada como proyecciones_ibfk_2 y la clave foránea IDPELICULA como proyecciones_ibfk_1. Estos identificadores se utilizan

Page 390: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

372

por ejemplo para eliminar la correspondiente clave foránea con la sentencia ALTERTABLE. 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.

Page 391: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

373

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)

Page 392: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

374

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

Page 393: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

375

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)

Page 394: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

376

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)

Page 395: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

377

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)

Page 396: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

378

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)

Page 397: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

379

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.

Page 398: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

380

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

NOTA

Page 399: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

381

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.

Page 400: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

382

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 [email protected] 0 llp70 2 María Anta San Juan 22, Oviedo 1981-11-22 686776612 [email protected] 0 as23b 3 Ana Palacios San Andrés 39, Madrid 1968-5-1 null [email protected] 0 aaa45b 4 Valeria Vázquez Moro 120, Almería 1990-2-13 645162377 [email protected] 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.txtEnter password: ******* cinemas.clientes: Records: 4 Deleted: 0 Skipped: 0Warnings: 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

Page 401: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

383

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.

Page 402: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

384

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,203,240,12,Sala renovada recientemente 4,120,10,Localidades para minusválidos 5,120,126,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:

Page 403: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

385

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.

Page 404: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

386

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

Page 405: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

EL SISTEMA GESTOR DE BASES DE DATOS MYSQL

387

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.

Page 406: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 407: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

389

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

Page 408: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

390

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

Page 409: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

391

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.

Page 410: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

392

15.3. GESTIÓN DE BASES DE DATOS

15.3.1. CONSULTA DE LAS BASES DE DATOSUna 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

Page 411: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

393

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

Page 412: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

394

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.

Page 413: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

395

Figura 15.6 Consulta de los aforos de las salas

Figura 15.7 Resultado de la consulta de aforos

Page 414: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

396

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.

Page 415: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

397

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

Page 416: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

398

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

Page 417: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

399

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

Page 418: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

400

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

Page 419: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

401

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

Page 420: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

402

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

Page 421: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

403

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

Page 422: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

404

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

Page 423: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

405

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

NOTA

Page 424: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

406

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

Page 425: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

407

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

Page 426: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

408

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.

Page 427: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

409

Por ejemplo, supóngase que se desea crear un usuario de nombre cinemasadminque 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).

Page 428: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

410

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

Page 429: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

PHPMYADMIN: ADMINISTRACIÓN DE BASES DE DATOS MYSQL DESDE LA WEB

411

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.

Page 430: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

412

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 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 dbaparecerá 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_privhabrá 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.

NOTA

Page 431: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

413

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

Page 432: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

414

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.

Page 433: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

415

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

Page 434: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

416

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.

Page 435: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

417

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

NOTA

Page 436: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

418

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 =

Page 437: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

419

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

Page 438: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

420

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>

Page 439: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

421

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

Page 440: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

422

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

Page 441: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

423

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

Page 442: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

424

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

NOTA

Page 443: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

425

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:

Page 444: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

426

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

Page 445: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

427

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>

Page 446: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

428

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

Page 447: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

429

<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

Page 448: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

430

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

Page 449: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

431

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.

Page 450: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

432

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

Page 451: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

433

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>

Page 452: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

434

<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

Page 453: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

435

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

Page 454: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

436

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

Page 455: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

437

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

Page 456: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

438

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

Page 457: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

439

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

Page 458: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

440

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><?phpif(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>

Page 459: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

441

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

Page 460: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

442

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:

Page 461: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

443

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>

Page 462: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

444

<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

Page 463: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

445

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

NOTA

Page 464: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

446

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> <?phpfunction 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'

Page 465: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

447

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

Page 466: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

448

} // 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><?phpif (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:";

Page 467: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

449

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>

Page 468: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

450

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

Page 469: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

CONECTIVIDAD A BASES DE DATOS MYSQL DESDE PHP

451

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.

Page 470: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 471: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

453

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.

Page 472: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

454

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.

Page 473: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IMPLEMENTACIÓN DE FOROS

455

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

Page 474: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

456

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

Page 475: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IMPLEMENTACIÓN DE FOROS

457

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

Page 476: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

458

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

Page 477: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IMPLEMENTACIÓN DE FOROS

459

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

Page 478: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

460

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

Page 479: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IMPLEMENTACIÓN DE FOROS

461

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>

Page 480: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

462

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

Page 481: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

IMPLEMENTACIÓN DE FOROS

463

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.

Page 482: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 483: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

465

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

Page 484: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

466

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.

Page 485: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

467

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

Page 486: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

468

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

Page 487: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

469

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.

Page 488: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

470

— Publicacióno 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 opensource. 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

completa gestión de sus contenidos sin tener excesivos conocimientos informáticos.

— Permiten incorporar al sitio web diferentes servicios como foros, chats, encuestas,...

— Facilidad para la modificación del sitio y de los contenidos de forma remota, desde cualquier punto con conexión a Internet.

— Personalización del sitio en función del usuario, creando distintos perfiles.

— Gratuidad y código abierto.

— Dominar una aplicación CMS requiere tiempo y en el caso de grandes empresas, pueden suponer un alto coste en consultores que integren la aplicación con el sistema existente en la organización.

— En algunos casos puede generar un exceso de homogeneidad con otros sitios desarrollados con el mismo CMS.

— El desarrollo y mejoras de la aplicación están vinculados al desarrollo de la comunidad creadora del software.

Tabla 18.1 Ventajas e inconvenientes de los gestores de contenido

Page 489: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

471

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

Page 490: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

472

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

Page 491: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

473

18.3.2. POSTNUKE

Sitio oficial www.postnuke.comwww.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

Page 492: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

474

18.3.3. MAMBO SERVER

Sitio oficial www.mamboserver.comwww.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

Page 493: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

475

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

Page 494: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

476

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

Page 495: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

477

18.3.6. XOOPS

Sitio oficial www.xoops.orgwww.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

Page 496: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

478

18.3.7. DRUPAL

Sitio oficial www.drupal.orgdrupal.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

Page 497: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

479

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

Page 498: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

480

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.

Page 499: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

481

Figura 18.9 Sitio oficial de GEEKLOG

Page 500: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

482

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

Page 501: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

483

B2, B2evolution y WordPress

Sitio oficial www.cafelog.comb2evolution.networdpress.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

Page 502: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

484

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.

Page 503: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

485

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

Page 504: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

486

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

Page 505: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

487

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.

MoodleSitio 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

Page 506: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

488

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

Page 507: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

489

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

Page 508: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

490

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

Page 509: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

491

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

Page 510: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

492

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

Page 511: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

493

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

Page 512: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

494

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

Page 513: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

SOLUCIONES OPEN SOURCE BASADAS EN PHP Y MYSQL

495

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.

Page 514: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

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

496

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.

Page 515: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

497

— · 124!! · 130!= · 128!== · 128

$$_COOKIE · 291$_GET · 142$_POST · 142$_REQUEST · 142$_SERVER · 110$GLOBALS · 208, 265$HTTP_COOKIE_VARS · 290$HTTP_GET_VARS · 143$HTTP_POST_VARS · 143$this · 275

%% · 124

&& · 127, 203&& · 130

.

. · 131

@

@ · 132

[[] · 216^^ · 127‘‘ · 132|| · 127|| · 130~~ · 127+

Índice alfabético

Page 516: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

498

array_diff_assoc · 239array_fill · 237array_filter · 228array_intersect · 239array_intersect_assoc · 239array_key_exists · 230array_keys · 229array_map · 240array_pad · 237array_pop · 237array_push · 237array_rand · 230array_reverse · 245array_search · 231array_shift · 237array_splice · 235array_unique · 237array_unshift · 238array_values · 232array_walk · 242Arrays · 113arrays asociativos · 217arsort · 244ASC · 334asort · 244ASP · 21AVG · 335

B

B · 69BIGINT · 357BINARY · 360BIT · 357BLINK · 69BLOB · 360BLOCKQUOTE · 70BODY · 62BOOL · 357

++ · 124<< · 128<< · 127<= · 128=== · 128=== · 128>> · 128-> · 278>= · 128>> · 127

A

A · 82ACTION · 137ALL · 331ALTER · 318, 321ámbito de las variables · 116and · 130applet · 10Applet · 19argumentoslongitud variable · 201opcionales · 199por referencia · 203por valor · 203valores por defecto · 200argumentos opcionales · 199array · 215, 216multidimensional · 218array_change_key_case · 225array_chunk · 226array_combine · 232array_count_values · 227array_diff · 239

Page 517: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

499

CREATE INDEX · 323CREATE TABLE · 318ctype_alnum · 250ctype_alpha · 250ctype_digit · 250ctype_lower · 250ctype_print · 250ctype_punct · 250ctype_space · 250ctype_upper · 250

D

date · 107, 167, 260DEC · 358DECIMAL · 358default · 170define · 119DELETE · 328DESC · 334DESCRIBE · 347die · 416DISTINCT · 331, 332do...while · 176DOCTYPE · 64DOUBLE · 358DROP · 318

E

each · 221echo · 103eliminación en cascada · 374else · 162elseif · 165empty · 119ENCTYPE · 307endfor · 179endif · 167

borrado en cascada · 324break · 170, 188

C

Cadenas · 113case · 170CASE_LOWER · 225CASE_UPPER · 225CGI · 21

Ch

CHAR · 359checkdate · 260chr · 182

C

class · 273claveajena · 323Cliente · 6cliente/servidor · 5ColdFusion · 22comentarios · 112compact · 232comunidades · 47constructor · 275continue · 188cookie · 285, 286de sesión · 291permanente · 291visibilidad · 294copy · 306count · 223, 227COUNT · 335CREATE · 317CREATE DATABASE · 317

Page 518: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

500

func_get_args · 202func_num_args · 202funciones variables · 211function · 193function_exists · 212fwrite · 303

G

get_defined_functions · 212gettype · 118global · 207GNU · 29GPL · 37GROUP BY · 331, 336

H

HAVING · 331, 336HEAD · 62herencia · 281hipertexto · 5Hn · 68HTML · 7, 57http · 7, 55

I

I · 69if · 158IMG · 79implode · 251in_array · 232include · 209INDEX · 366índices · 322InnoDB · 365INSERT · 325INT · 357

endswitch · 173endwhile · 175ENUM · 361EXIT · 344explode · 251extends · 283EXTR_OVERWRITE · 233EXTR_PREFIX_ALL · 233EXTR_PREFIX_SAME · 233EXTR_SKIP · 233extract · 233

F

fclose · 297feof · 298fgetc · 300fgets · 298file · 299file_exists · 307filesize · 299FLOAT · 358FLUSH PRIVILEGES · 351FONT · 69fopen · 296for · 179foreach · 187, 220Foreign Key · 313FOREIGN KEY · 323FORM · 90fputs · 303FRAME · 86FRAMESET · 85fread · 299free software · 27FROM · 331fscanf · 300FSF · 29func_get_arg · 202

Page 519: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

501

metatags · 62método GET · 144Método GET · 143método POST · 145Método POST · 143métodos · 270MIN · 335mktime · 187, 260MySQL · 339mysql_ free_result · 450mysql_affected_rows · 425, 450MYSQL_ASSOC · 431MYSQL_BOTH · 431mysql_close · 415mysql_connect · 414mysql_db_query · 418mysql_error · 419mysql_fetch_array · 431mysql_fetch_assoc · 431mysql_fetch_row · 424mysql_field_len · 450mysql_field_name · 450mysql_field_type · 450mysql_insert_id · 424MYSQL_NUM · 431mysql_num_rows · 425, 450mysql_pclose · 416mysql_pconnect · 416mysql_query · 417mysql_select_db · 416mysqld · 341mysqldump · 385mysqlimport · 381mysqlshow · 341

N

natcasesort · 245natsort · 245

INTEGER · 357integridad referencial · 364Internet · 3is_array · 118is_float · 118is_int · 118is_object · 118is_string · 118isset · 118

J

Java · 19JavaScript · 18JSP · 21

K

krsort · 244ksort · 244

L

LI · 71list · 221LOAD DATA INFILE · 381localhost · 104

M

mail · 424matriz · 215MAX · 335max_execution_time · 181MAX_FILE_SIZE · 308MEDIUMINT · 357META HTT-EQUIV · 63META NAME · 65metaetiquetas · 62

Page 520: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

502

operador Y · 130operadores aritméticos · 124operadores de bit · 127Operadores de comparación · 128operadores de desplazamiento de bits ·127operadores lógicos · 130OPTION · 92or · 130ORDER BY · 331, 333

P

P · 70PASSWORD · 351PHP · 23, 99phpinfo · 106phpmyadmin · 389PRE · 70PRECISION · 358Primary Key · 313print · 106print_r · 219print_r() · 198prioridad de operadores · 133programación orientada a objetos · 269

Q

QUIT · 344

R

rand · 182range · 234REAL · 358register_globals · 141rename · 307require · 209

new · 277NO ACTION · 324NOT NULL · 325NULL · 325NUMERIC · 358Números en coma flotante · 113Números enteros · 113

O

objetos · 269Objetos · 113OL · 71ON DELETE · 324, 374ON UPDATE · 379open source · 2, 27operación de negación · 130operador asignación · 125operador condicional · 130, 164operador de cast · 116operador de concatenación · 131Operador de conversión de tipo · 133operador de dirección · 203operador de ejecución · 132operador de identidad · 128operador de igualdad · 128operador de negación · 127operador de negación de identidad · 128operador de negación de igualdad · 128operador de supresión de error · 132operador decremento · 124operador diferencia · 124operador división · 124operador incremento · 124operador O · 130operador O exclusivo · 130operador producto · 124operador resto · 124operador suma · 124

Page 521: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

503

strlen · 259strnatcasecmp · 256strnatcmp · 256strpos · 257strrchr · 256strrev · 254strrpos · 257strstr · 110, 257strtok · 258strtolower · 254strtoupper · 254SUB · 69subclases · 281substr · 257substr_count · 257substr_replace · 254SUM · 335SUP · 69switch · 169

T

TABLE · 76TD · 77tempnam · 445TEXT · 360TEXTAREA · 91TH · 76this · 275time · 260TIMESTAMP · 363TINYINT · 357TITLE · 62TR · 76

U

U · 69ucfirst · 255

return · 194rewind · 304rsort · 245

S

S · 69SCRIPT · 108script, insercción · 108secuencias de escape · 120SELECT · 92, 330SELECT INTO OUTFILE · 386Servidor · 5servlets · 21SET · 361SET NULL · 324SET PASSWORD · 350setcookie · 286settype · 116Shareware · 27SHOW COLUMNS · 347show databases · 345SHOW TABLES · 347shutdown · 341SMALLINT · 357sort · 245SOURCE · 369SQL · 316str_pad · 253STR_PAD_BOTH · 253STR_PAD_LEFT · 253STR_PAD_RIGHT · 253str_repeat · 253str_replace · 254str_word_count · 252strcasecmp · 256strchr · 256strcmp · 256stristr · 257

Page 522: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.

504

variables · 114ámbito · 206VBScript · 20

W

W3C · 59web · 1, 4WHERE · 331while · 175wordwrap · 258

X

xor · 130

Z

ZEROFILL · 357

ucwords · 255UL · 73unlink · 307unset · 118, 204UNSIGNED · 357UPDATE · 329USE · 346user · 346

V

valores por defecto · 200var · 273VARCHAR · 359variableestática · 208global · 207local · 206variable global · 117variable local · 117

Page 523: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 524: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 525: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.
Page 526: PHP y MySQL Tecnología para el desarrollo de aplicaciones web.