Manual PHP5 Básico Basico
User Manual:
Open the PDF directly: View PDF .
Page Count: 180
Download | ![]() |
Open PDF In Browser | View PDF |
PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Programación en PHP5. Nivel Básico Carlos Vázquez Mariño Ferrol, Septiembre de 2008 Mi agradecimiento a Enrique Cabanas Olmo, co-autor del manual Programación en PHP. Nivel I, en el que está basado este manual. 3 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO INDICE 1. 2. 3. 4. 5. 6. Introducción a PHP.............................................................................................................................. 9 1.1. Funcionamiento de un Servidor Web ........................................................................................ 9 1.2. Historia de PHP....................................................................................................................... 10 1.3. PHP frente a otros lenguajes ................................................................................................... 13 1.4. Instalación de Apache ............................................................................................................. 14 1.5. Instalación de PHP .................................................................................................................. 19 Características del lenguaje ............................................................................................................... 33 2.1. HTML y PHP .......................................................................................................................... 33 2.2. Comentarios ............................................................................................................................ 34 2.3. Instrucciones ........................................................................................................................... 35 Variables y Constantes ...................................................................................................................... 37 3.1. Conceptos Básicos .................................................................................................................. 37 3.2. Variables predefinidas............................................................................................................. 38 3.3. Ambito de las variables ........................................................................................................... 39 3.4. Existencia y tipo de una variable............................................................................................. 42 3.5. Variables variables .................................................................................................................. 45 3.6. Constantes ............................................................................................................................... 46 Tipos de Datos ................................................................................................................................... 49 4.1. Booleanos................................................................................................................................ 50 4.2. Enteros .................................................................................................................................... 50 4.3. Números en punto flotante ...................................................................................................... 50 4.4. Cadenas ................................................................................................................................... 50 4.4.1. Conversión a cadenas ................................................................................................... 51 4.4.2. Conversión de cadenas a números ................................................................................ 52 4.5. Arrays...................................................................................................................................... 53 4.5.1. Arrays unidimensionales .............................................................................................. 53 4.5.2. Arrays Multidimensionales........................................................................................... 53 4.6. Objetos .................................................................................................................................... 55 4.7. Recursos.................................................................................................................................. 55 4.8. NULL...................................................................................................................................... 55 4.9. Forzado de tipos ...................................................................................................................... 55 Operadores......................................................................................................................................... 59 5.1. Operadores Aritméticos........................................................................................................... 59 5.2. Operadores de Asignación ...................................................................................................... 59 5.3. Operadores de bits................................................................................................................... 60 5.4. Operadores de Comparación ................................................................................................... 60 5.5. Operadores de Control de Errores ........................................................................................... 61 5.6. Operador de ejecución............................................................................................................. 61 5.7. Operadores de Incremento/decremento ................................................................................... 62 5.8. Operadores lógicos.................................................................................................................. 62 5.9. Operador de cadenas de texto.................................................................................................. 63 5.10. Operadores de Matrices........................................................................................................... 63 5.11. Operadores de Tipo ................................................................................................................. 64 5.12. Precedencia y asociatividad de operandos............................................................................... 64 Estructuras de Control ....................................................................................................................... 67 6.1. if .............................................................................................................................................. 67 6.2. else .......................................................................................................................................... 68 6.3. elseif........................................................................................................................................ 68 6.4. while........................................................................................................................................ 69 6.5. do..while.................................................................................................................................. 69 6.6. for............................................................................................................................................ 70 6.7. foreach..................................................................................................................................... 71 6.8. break........................................................................................................................................ 73 6.9. continue................................................................................................................................... 73 6.10. switch ...................................................................................................................................... 74 6.11. declare ..................................................................................................................................... 76 6.12. return....................................................................................................................................... 77 6.13. require()................................................................................................................................... 77 6.14. include() .................................................................................................................................. 78 6.15. require_once() ......................................................................................................................... 80 5 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 6.16. include_once()......................................................................................................................... 81 6.17. Sintaxis Alternativa de Estructuras de Control........................................................................ 81 7. Funciones........................................................................................................................................... 83 7.1. Funciones definidas por el usuario .......................................................................................... 83 7.2. Parámetros de las funciones .................................................................................................... 84 7.3. Pasar parámetros por referencia .............................................................................................. 85 7.4. Parámetros por defecto............................................................................................................ 85 7.5. Lista de longitud variable de parámetros................................................................................. 86 7.6. Devolviendo valores................................................................................................................ 87 7.7. Funciones variables................................................................................................................. 87 7.8. Funciones de tratamiento de cadenas de caracteres................................................................. 88 7.8.1. echo .............................................................................................................................. 88 7.8.2. print .............................................................................................................................. 89 7.8.3. printf ............................................................................................................................. 90 7.8.4. sprintf............................................................................................................................ 93 7.8.5. Adaptar las cadenas al contexto.................................................................................... 94 7.8.6. Limpiar cadenas de caracteres ..................................................................................... 96 7.8.7. Letras mayúsculas y letras minúsculas ......................................................................... 97 7.8.8. Conocer la longitud de una cadena ............................................................................... 98 7.8.9. Repetir una cadena........................................................................................................ 98 7.8.10. Modificar algunos caracteres de una cadena................................................................. 98 7.8.11. Buscar dentro de las cadenas ........................................................................................ 99 7.8.12. Operaciones con subcadenas ........................................................................................ 99 7.8.13. Invertir el texto de una cadena .................................................................................... 100 7.8.14. Comparar cadenas....................................................................................................... 100 7.8.15. Otras funciones de cadena útiles................................................................................. 101 7.9. Funciones de tratamiento de arrays ....................................................................................... 101 7.9.1. Crear e inicializar una matriz...................................................................................... 102 7.9.2. Recorrer los elementos de una matriz unidimensional................................................ 104 7.9.3. Convertir cadenas de caracteres en matrices y viceversa............................................ 106 7.9.4. Ordenar matrices......................................................................................................... 106 7.9.5. Modificar matrices...................................................................................................... 109 7.9.6. Extraer información de las matrices............................................................................ 112 7.9.7. Tratar un array como si fuera una pila ........................................................................ 115 7.10. Funciones de Tratamientos de Fechas ................................................................................... 116 7.10.1. Comprobar la validez de una fecha............................................................................. 116 7.10.2. Dar formato a una fecha y una hora............................................................................ 117 7.10.3. Extraer información de una fecha ............................................................................... 117 7.10.4. Dar formato a una fecha traduciendo los nombres...................................................... 118 8. Entrada y Salida de Datos................................................................................................................ 121 8.1. Entrada de Datos ................................................................................................................... 121 8.1.1. Valores sencillos......................................................................................................... 121 8.1.2. Valores múltiples........................................................................................................ 122 8.2. Salida de datos ...................................................................................................................... 123 8.3. Consideraciones sobre la E/S ................................................................................................ 123 9. Ficheros y Directorios...................................................................................................................... 125 9.1. Abrir y Cerrar Ficheros ......................................................................................................... 125 9.1.1. Abrir un fichero .......................................................................................................... 125 9.1.2. Cerrar un fichero......................................................................................................... 128 9.2. Recorrer ficheros y Leer su Contenido.................................................................................. 128 9.2.1. Recorrer un fichero..................................................................................................... 128 9.2.2. Leer los contenidos de un fichero ............................................................................... 129 9.3. Modificar el contenido de los ficheros .................................................................................. 131 9.4. Copiar, borrar y renombrar ficheros...................................................................................... 131 9.4.1. Copiar un fichero ........................................................................................................ 132 9.4.2. Conocer los atributos, el tipo y el tamaño de un fichero............................................. 133 9.5. Operaciones con directorios .................................................................................................. 134 9.5.1. Establecer el directorio por defecto ............................................................................ 134 9.5.2. Abrir un directorio ...................................................................................................... 134 9.5.3. Cerrar un directorio .................................................................................................... 135 9.5.4. Leer un directorio ....................................................................................................... 135 9.5.5. Mover el puntero de lectura de un directorio .............................................................. 136 9.5.6. Crear un directorio...................................................................................................... 136 9.5.7. Borrar un directorio ................................................................................................... 137 9.5.8. Subir ficheros al servidor, usarlos y validarlos ........................................................... 137 9.5.9. Permisos y propietarios............................................................................................... 139 10. Apéndice HTML ........................................................................................................................ 141 6 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 10.1. Introducción .......................................................................................................................... 141 10.1.1. Elementos llenos......................................................................................................... 141 10.1.2. Elementos vacíos ........................................................................................................ 142 10.1.3. Elementos con argumento........................................................................................... 142 10.2. Estructura de un documento HTML...................................................................................... 143 10.3. Cabecera (HEAD) de un documento HTML......................................................................... 144 10.4. Cuerpo (BODY) de un documento........................................................................................ 145 10.4.1. Tamaños y tipos de letra en HTML ............................................................................ 146 10.4.2. Texto en color............................................................................................................. 148 10.4.3. Cambios de párrafo y de línea. Divisiones de texto. ................................................... 149 10.4.4. Otros efectos en el texto ............................................................................................. 152 10.4.5. Listas y menús ............................................................................................................ 153 10.4.6. Tablas ......................................................................................................................... 158 10.4.7. Códigos hexadecimales de color................................................................................. 158 10.4.8. Creación de enlaces (links) ......................................................................................... 159 10.4.9. Insertar imágenes........................................................................................................ 163 10.4.10. Introducción a los formularios.................................................................................... 166 10.4.11. ¿Cómo se escriben los formularios ? .......................................................................... 167 10.4.12. Qué son los frames ..................................................................................................... 176 10.5. ¿Por qué hay que usar códigos? ............................................................................................ 179 7 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 1. Introducción a PHP ® ® ® ® ® Funcionamiento de un Servidor Web Historia de PHP PHP frente a otros lenguajes Instalación de Apache Instalación de PHP 1.1. Funcionamiento de un Servidor Web Dado que en este curso se va a tratar el desarrollo de sitios web dinámicos mediante PHP, antes de entrar en porque elegir PHP y no otro lenguaje de programación, y como funciona dicho lenguaje, hemos de comprender como funciona un servidor web cuando un usuario solicita una de esas páginas que nosotros vamos a construir con PHP. Vamos a comenzar explicando como funciona un servidor web (como Apache, IIS, PWS, ...) cuando un usuario solicita una página HTML estática que contiene 5 imágenes en su contenido. Para resolver dicha petición, el navegador del usuario debe establecer una conexión HTTP distinta para cada elemento que se desea solicitar al servidor web, es decir, una conexión HTTP para la página HTML y 5 conexiones HTTP adicionales para las imágenes (una por imagen). Es decir, la situación vendría a ser como se muestra a continuación: Petición HTTP SERVIDOR Archivo HTML veces 55veces CLIENTE Petición HTTP 1 imagen SERVIDOR CLIENTE Archivo imagen Si en lugar de páginas estáticas, las páginas son dinámicas, es decir muestran información obtenida de ficheros, bases de datos, u otras fuentes, pero que varía en función de una serie de parámetros sin la intervención del programador web, se nos presentan distintas alternativas para dar el carácter dinámico a las páginas: bien darles dinamismo en la parte de clientes (por ejemplo usando applets), o bien darles dinamismo en la parte del servidor (usando CGI, SERVLETS o lenguajes como PHP, ASP O JSP). Si optamos por dar dinamismo en la parte del cliente, el funcionamiento cuando el usuario solicita una página que contiene un APPLET es bastante similar al visto para las páginas estáticas, es decir, se tendrá que realizar una conexión HTTP para obtener la página y tantas conexiones HTTP como APPLETS contenga dicha página. Un APPLET, que es un programa escrito en el lenguaje JAVA, se ejecuta en la propia 9 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO máquina del cliente, con las consiguientes desventajas de acceso a recursos ubicados en el servidor, y con la desventaja de que se tiene que ejecutar en una JVM (Java Virtual Machine) que hay que tener instalada en la máquina en la que se sitúa el cliente. Su uso se reduce a dotar a las páginas de efectos visuales y sonoros, textos en movimiento, pequeñas utilidades para incluir en la página como un reloj, pequeños programas educativos, pequeños juegos interactivos, presentaciones multimedia, etc Sin embargo, si optamos por dar dinamismo en la parte del servidor el funcionamiento es un poco diferente. Desde el punto de vista del usuario que solicita una página el funcionamiento es el ya visto, es decir, el usuario solicita una página y se le devuelve un archivo HTML (lo que genera una conexión HTTP al servidor) y tantas imágenes o elementos como tenga incluidos la página (una conexión HTTP por cada uno de estas imágenes o elementos). Petición HTTP SERVIDOR CLIENTE Archivo HTML Pero desde el punto de vista del servidor la cosa es un poco más compleja. Cuando se solicita una pagina web que contiene código denominado script, es decir, incluido dentro de la página HTML, escrito en PHP, ASP, JSP o cualquier otro lenguaje similar, el servidor web antes de devolver dicha página HTML, solicita al interprete de scripts que ejecute ese código como si de un programa se tratase y le devuelva un resultado. Ese resultado incrustado en el documento HTML original constituye el documento HTML devuelto al usuario. El interprete de scripts para ejecutar dicho código script y devolver un resultado puede acceder a multitud de recursos del servidor (bases de datos, ficheros, servicios de correo, ftp, news, ....) u de otros servidores. De esta forma el esquema anterior se complica para quedar de la siguiente forma: Petición HTTP CLIENTE SERVIDOR Archivo HTML Obtener recurso Ejecutar Script SCRIPT Devolver resultado RECURSOS Devolver recurso 1.2. Historia de PHP PHP/FI PHP es el heredero de un producto anterior, llamado PHP/FI. PHP/FI fue creado por Rasmus Lerdorf en 1995, inicialmente como un simple conjunto de scripts de Perl para controlar los accesos a su trabajo online. Llamó a ese conjunto de scripts 'Personal Home Page Tools'. Según se requería más funcionalidad, Rasmus fue escribiendo una implementación C mucho mayor, que era capaz de comunicarse con bases de datos, y 10 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO permitía a los usuarios desarrollar sencillas aplicaciones Web dinámicas. Rasmus eligió liberar el código fuente de PHP/FI para que cualquiera pudiese utilizarlo, así como arreglar errores y mejorar el código. PHP/FI, que se mantuvo para páginas personales y como intérprete de formularios, incluía algunas de las funcionalidades básicas de PHP tal y como lo conocemos hoy. Tenía variables como las de Perl, interpretación automática de variables de formulario y sintaxis embebida HTML. La sintaxis por sí misma era similar a la de Perl, aunque mucho más limitada, simple y algo inconsistente. Por 1997, PHP/FI 2.0, la segunda escritura de la implementación en C, tuvo un seguimiento estimado de varios miles de usuarios en todo el mundo, con aproximadamente 50.000 dominios informando que lo tenían instalado, sumando alrededor del 1% de los dominios de Internet. Mientras había mucha gente contribuyendo con bits de código a este proyecto, era todavía en su mayor parte el proyecto de una sola persona. PHP/FI 2.0 no se liberó oficialmente hasta Noviembre de 1997, después de gastar la mayoría de su vida en desarrollos beta. Fue sucedido en breve tiempo por las primeras versiones alfa de PHP 3.0. PHP 3 PHP 3.0 era la primera versión que se parecía fielmente al PHP tal y como lo conocemos hoy en día. Fue creado por Andi Gutmans y Zeev Zuraski en 1997 rescribiéndolo completamente, después de que encontraran que PHP/FI 2.0 tenía pocas posibilidades para desarrollar una aplicación comercial que estaban desarrollando para un proyecto universitario. En un esfuerzo para cooperar y empezar a construir sobre la base de usuarios de PHP/FI existente, Andi, Rasmus y Zeev decidieron cooperar y anunciar PHP 3.0 como el sucesor oficial de PHP/FI 2.0, interrumpiéndose en su mayor parte el desarrollo de PHP/FI 2.0. Una de las mejores características de PHP 3.0 era su gran extensibilidad. Además de proveer a los usuarios finales de una sólida infraestructura para muchísimas bases de datos, protocolos y APIs, las características de extensibilidad de PHP 3.0 atrajeron a docenas de desarrolladores a unirse y enviar nuevos módulos de extensión. Sin duda, ésta fue la clave del enorme éxito de PHP 3.0. Otras características clave introducidas en PHP 3.0 fueron el soporte de sintaxis orientado a objetos y una sintaxis de lenguaje mucho más potente y consistente. Todo el nuevo lenguaje fue liberado bajo un nuevo nombre, que borraba la implicación de uso personal limitado que tenía el nombre PHP/FI 2.0. Se llamó 'PHP' a secas, con el significado de ser un acrónimo recursivo - PHP: Hypertext Preprocessor. A finales de 1998, PHP creció hasta una base de instalación de decenas de millares de usuarios (estimados) y cientos de miles de sitios Web informando de su instalación. En su apogeo, PHP 3.0 estaba instalado en aproximadamente un 10% de los servidores Web en Internet. PHP 3.0 se liberó oficialmente en Junio de 1998, después de haber gastado unos 9 meses en pruebas públicas. 11 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO PHP 4 En el invierno de 1998, poco después del lanzamiento oficial de PHP 3.0, Andi Gutmans y Zeev Suraski comenzaron a trabajar en la reescritura del núcleo de PHP. Los objetivos de diseño fueron mejorar la ejecución de aplicaciones complejas, y mejorar la modularidad del código base de PHP. Estas aplicaciones se hicieron posibles por las nuevas características de PHP 3.0 y el apoyo de una gran variedad de bases de datos y APIs de terceros, pero PHP 3.0 no fue diseñado para el mantenimiento tan complejo de aplicaciones eficientemente. El nuevo motor, apodado 'Motor Zend' (comprimido de sus apellidos, Zeev y Andi), alcanzó estos objetivos de diseño satisfactoriamente, y se introdujo por primera vez a mediados de 1999. PHP 4.0, basado en este motor, y acoplado con un gran rango de nuevas características adicionales, fue oficialmente liberado en Mayo de 2000, casi dos años después que su predecesor, PHP 3.0. Además de la mejora de ejecución de esta versión, PHP 4.0 incluía otras características clave como el soporte para la mayoría de los servidores Web, sesiones HTTP, buffers de salida, formas más seguras de controlar las entradas de usuario y muchas nuevas construcciones de lenguaje. El día 13 de julio de 2007 se anunció la suspensión del soporte y desarrollo de la versión 4 de PHP, a pesar de lo anunciado se ha liberado una nueva versión con mejoras de seguridad, la 4.4.8 publicada el 13 de Enero del 2008. Según se ha anunciado se dará soporte a fallos críticos hasta el 2008-08-08. PHP 5 El 13 de julio de 2004, fue lanzado PHP 5, utilizando el motor Zend Engine II (o Zend Engine 2). La versión más reciente de PHP es la 5.2.6 (1 de Mayo de 2008), que incluye todas las ventajas que provee el nuevo Zend Engine 2 como: Ö Mejor soporte para la Programación Orientada a Objetos, que en versiones anteriores era extremadamente rudimentario, con PHP Data Objects. Ö Mejoras de rendimiento. Ö Mejor soporte para MySQL con extensión completamente reescrita. Ö Mejor soporte a XML (XPath, DOM, etc. ). Ö Soporte nativo para SQLite. Ö Soporte integrado para SOAP. Ö Iteradores de datos. Ö Manejo de excepciones. PHP 6 Está previsto el lanzamiento en breve de la rama 6 de PHP. Cuando se lance esta nueva versión quedarán solo dos ramas activas en desarrollo (PHP 5 y 6), pues se abandonó el desarrollo y soporte de PHP 4 el 13 de julio de 2007. Las diferencias que encontraremos frente a PHP 5.* serán: Ö Ö Ö Ö 12 Soportará Unicode. Limpieza de funcionalidades obsoletas como register_globals, safe_mode... PECL. Mejoras en orientación a objetos. PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 1.3. PHP frente a otros lenguajes Para seleccionar un lenguaje de Script las cuatro grandes características que debe cumplir son: Velocidad, estabilidad, seguridad y simplicidad. • • • • Velocidad: No sólo la velocidad de ejecución, la cual es importante, sino además no crear demoras en la máquina. Por esta razón no debe requerir demasiados recursos de sistema. PHP se integra muy bien junto a otro software, especialmente bajo ambientes Unix, cuando se configura como módulo de Apache, esta listo para ser utilizado. Estabilidad: La velocidad no sirve de mucho si el sistema se cae cada cierta cantidad de ejecuciones. Ninguna aplicación es 100% libre de bugs, pero teniendo de respaldo una increíble comunidad de programadores y usuarios es mucho mas difícil para lo bugs sobrevivir. PHP utiliza su propio sistema de administración de recursos y dispone de un sofisticado método de manejo de variables, conformando un sistema robusto y estable. Seguridad: El sistema debe poseer protecciones contra ataques. PHP provee diferentes niveles de seguridad, estos pueden ser configurados desde el archivo .ini Simplicidad: Se les debe permitir a los programadores generar código productivamente en el menor tiempo posible. Usuarios con experiencia en C y C++ podrán utilizar PHP rápidamente. Bueno otra característica a tener en cuenta seria la conectividad. PHP dispone de una amplia gama de librerías, y agregarle extensiones es muy fácil. Esto le permite al PHP ser utilizado en muchas áreas diferentes, tales como encriptado, gráficos, XML y otras. Ventajas adicionales de PHP • • • • • • PHP corre en (casi) cualquier plataforma utilizando el mismo código fuente, pudiendo ser compilado y ejecutado en algo así como 25 plataformas, incluyendo diferentes versiones de Unix, Windows (95,98,NT,ME,2000,XP,...) y Macs. Como en todos los sistemas se utiliza el mismo código base, los scripts pueden ser ejecutados de manera independiente al OS. La sintaxis de PHP es similar a la del C, por esto cualquiera con experiencia en lenguajes del estilo C podrá entender rápidamente PHP. Entre los lenguajes del tipo C incluimos al Java y Javascript, de hecho mucha de la funcionalidad del PHP se la debe al C en funciones como fread() o srtlen(), así que muchos programadores se sentirán como en casa. PHP es completamente expandible. Está compuesto de un sistema principal (escrito por Zend), un conjunto de módulos y una variedad de extensiones de código. Muchas interfaces distintas para cada tipo de servidor. PHP actualmente se puede ejecutar bajo Apache 1.3 y 2.X, IIS, Lighttpd, Netscape servers (Sun Java System, Sun One, iPlanet, …),… . Otra alternativa es configurarlo como modulo CGI. Puede interactuar con muchos motores de bases de datos tales como MySQL, MS SQL, Oracle, Informix, PostgreSQL, y otros muchos. Siempre podrás disponer de ODBC para situaciones que lo requieran. Una gran variedad de módulos cuando un programador PHP necesite una interfase para una librería en particular, fácilmente podrá crear una API para esta. Algunas de 13 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • • las que ya vienen implementadas permiten manejo de gráficos, archivos PDF, Flash, Cybercash, calendarios, XML, IMAP, POP, etc. Rapidez. PHP generalmente es utilizado como modulo de Apache, lo que lo hace extremadamente veloz. Esta completamente escrito en C, así que se ejecuta rápidamente utilizando poca memoria. PHP es Open Source, lo cual significa que el usuario no depende de una compañía específica para arreglar cosas que no funcionan, además no estás forzado a pagar actualizaciones anuales para tener una versión que funcione. Algunas desventajas • • El manejo de errores no es tan sofisticado como otros lenguajes (ASP.Net, …) . No existe IDE o Debugger consolidado. Aunque en la actualidad existen proyectos varios entre los mas destacados está Eclipse (gratuito) o Zend Studio (de pago). Cuando debes utilizar PHP y cuando debes utilizar otro lenguaje Si estás desarrollando bajo una plataforma UNIX o Linux, debes elegir entre Perl y PHP, ambos excelentes. Para mucha gente PHP es más simple a la hora de escribir scripts, haciéndolo más productivo en proyectos. En ambientes Windows compite muy de cerca con ASP.Net , aquí la elección se basa en asuntos un poco más técnicos y en la política que desee utilizarse para el sitio. ASP.Net junto a IIS es probablemente más estable que PHP con IIS. Pero en términos puramente técnicos, PHP bajo Windows Server es mucho más estable (además de ser más rápido y utilizar menos recursos). De cualquier manera ASP.Net ofrece una mejor integración con este ambiente sobre todo si se desea utilizar COM+. 1.4. Instalación de Apache ¿Que requerimientos necesitamos? En este manual nos referimos a la instalación bajo sistemas operativos de la familia Windows, que será sensiblemente igual en toda la familia, aunque la configuración es común a prácticamente cualquier S.O. Necesitamos un ordenador con un procesador de la familia x86 (cualquiera desde el 386 a la familia Pentium), y el protocolo TCP/IP instalado. La documentación nos indica que bajo Windows 95 necesitamos tener instaladas las winsock 2. Obteniendo el software Apache es un proyecto Open Source de la fundación apache.org. Puedes obtener el programa en su sitio web, http://www.apache.org/. Aunque se trata de un proyecto orientado al sistema operativo unix/linux, existen versiones del servidor web para Windows. Apache mantiene tres líneas de su servidor web: 1.x, 2.0 y 2.2. En sistemas Windows la propia fundación aconseja usar un servidor web de la línea Apache 2, reescrito para adaptarse a las peculiaridades de Windows. El uso de cualquiera de las líneas de Apache 2 vendrá determinado por los requisitos 14 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO específicos que se le exijan al servidor web, en nuestro caso podemos usar un servidor de cualquiera de las dos líneas: Apache 2.0 o Apache 2.2. Instalando los archivos La versión binaria de apache para Windows viene, desde la versión 1.3.17, en formato msi; se trata de un instalador de Microsoft, incorporado de serie en Windows Me y Windows 2000. Para otros sistemas operativos Windows, hay que bajarse previamente el MSI INSTALLER. Por ejemplo, para Windows 95 o 98 se puede obtener (gratis) en esta dirección: http://download.microsoft.com/download/platformsdk/wininst/1.1/W9X/EN-US/InstMsi.exe La instalacion de los archivos en nuestro disco duro tiene nula dificultad. La única precaución destacable es la de desinstalar cualquier versión previa de apache que tengamos, lo que conseguimos fácilmente desde inicio/panel de control/instalar desinstalar programas. Bajamos el ejecutable de la red a un directorio temporal, por ejemplo c:\temp, y una vez allí lo ejecutamos con un doble click de ratón, comenzando un proceso típico de instalación, en el que apenas habremos de intervenir: tras aceptar los términos de la licencia y pasar un readme file, nos solicita que introduzcamos el nombre de la red, nombre del servidor y email del webmaster; si tienes un nombre de dominio y las dns correctamente configuradas (es decir, si tu apache va a operar en internet) puedes meter aqui los datos pertinentes. Si aun no sabes de quelocal estamos hablando al referirnos a las DNS, o simplemente piensas usar apache como servidor de pruebas, puedes especificar localhost como nombre del dominio y del servidor, y cualquier email como direccion del webmaster. Seleccionamos que se instale Apache para todos los usuarios en el puerto 80. A continuación corresponde elegir el tipo de instalación que queremos, es decir, "tipica", que instala todo menos el código fuente (es decir, el programa y la documentación) o "custom", que permite por ejemplo no instalar la documentación. Elegimos la opción personalizada (“custom”). Lo siguiente que nos pregunta es la carpeta donde queremos que se instale. Por defecto, apache crea una carpeta en c:\Archivos de programa, siendo la ruta completa C:\Archivos de programa\Apache Group\Apache, aunque podemos elegir otro destino. Para el curso elegimos C:\WAMP\Apache22 suponiendo que en C: ya existe la carpeta WAMP. Los directorios de apache Un servidor apache tiene dos directorios esenciales, o tres, segun la instalación elegida: 15 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • • • ServerRoot es el directorio donde están los programas que ejecutan el servidor. Por defecto se instala en C:\Archivos de programa\Apache Group\Apache, con sus subdirectorios correspondientes. En nuestro curso C:\WAMP\Apache22 DocumentRoot es el directorio donde se instalan los archivos que serán servidos a los visitantes; las páginas web. Por defecto está en C:\Archivos de programa\Apache Group\Apache\htdocs. En nuestro curso C:\WAMP\Apache22\htdocs Source tree es el directorio donde está el código fuente del servidor, si lo hemos instalado (en C:\Archivos de programa\Apache Group\Apache\src ). Nosotros no lo hemos instalado. Prueba de funcionamiento Apache se instala por defecto como un servicio denominado Apache2.2 , de modo que podemos comenzar a operar directamente con él, aunque luego veremos alguna configuración básica. Apache se ejecuta y controla en modo dos, por lo que abriremos una sesion MSDOS y nos movemos al directorio de apache, y escribimos httpd -t: C:\WAMP\Apache22\bin>httpd -t Syntax OK Donde la primera línea es la entrada que tecleamos nosotros (httpd -t) y la segunda la respuesta del servidor (syntax OK). Bueno, y esto esta muy bien, pero no nos dice nada. Hagamos para asegurarnos de que todo está bien, una prueba con el navegador: iniciamos el servidor. Hay distintas formas de hacerlo, pero ya que estamos en una sesión DOS, escribimos C:\Archivos de programa\Apache Group\Apache>apache –k start En nuestro caso esto último no es necesario pues el servidor ya está funcionando como servicio. Si todo ha sido correcto nuestro servidor Apache está ejecutandose !!. Abrimos nuestro navegador favorito, y en la dirección escribimos: http://localhost/ y deberemos visualizar una página que nos informa que la instalación funciona (mostrará el mensaje It Works!). ¿Que cual es esa dirección que hemos dado? es el nombre por defecto de nuestro ordenador, lo que nos permite usar el servidor para testear páginas incluso desconectados de internet. Configurando el servidor Apache crea al instalarse un directorio llamado conf (ruta completa C:\Archivos de programa\Apache Group\Apache\conf en una instalación por defecto y C:\WAMP\Apache22\conf en nuestro curso), dentro del cual están los archivos de 16 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO configuración del servidor, archivos que tendremos que modificar para adecuar a nuestro sistema. El archivo que nos interesa es httpd.conf (que encontramos en el directorio conf). Apache no sobreescribe los archivos de instalación, si encuentra alguno. Por ejemplo, si ya existe un httpd.conf, no se borra, y mantiene la versión existente de instalaciones anteriores. Dentro de la carpeta conf hay una carpeta denominada original que tiene una copia de los ficheros de configuración en su estado inicial por si fuese necesario volver a usarlos. Se trata de un archivo de texto, que podemos manejar con cualquier editor capaz de guardar texto sin formato (notepad, por ejemplo). Veremos un montón de lineas. Todas las que empiezan por el carácter # son comentarios orientadores de las distintas opciones, o incluso opciones deshabilitadas (se activan "descomentándolas"). Las directivas más importantes son: ServerAdmin you@your.adress La dirección de correo del administrador. Esta dirección es la que aparecerá en páginas generadas por el servidor (por ejemplo si indica algun error) y permite a los usuarios informarte de problemas. Escribimos nuestra dirección, por ejemplo: ServerAdmin webmaster@misitio.com #ServerName new.host.name El nombre del servidor; útil principalmente para redireccionamientos de url; advierte que por defecto viene comentado, luego no es esencial para el funcionamiento (si no hay un nombre de servidor especificado, apache toma la dirección IP de nuestro ordenador). Podemos escribir el nombre de nuestro dominio (www.midominio.com) o nuestra IP, o localhost: ServerName localhost DocumentRoot “C:/WAMP/Apache22/htdocs” La carpeta raíz de los archivos del sitio web. Esta carpeta es donde se deben colocar las páginas y archivos que queremos que sirva nuestro servidor web. Cambiamos la ubicación de dicha carpeta, por ejemplo: DocumentRoot “C:/WAMP/www” Habrás observado que en determinados sitios web, para acceder al contenido, basta con teclear el nombre del dominio (por ejemplo http://www.google.es nos sirve la pagina principal del buscador), mientras que en otros casos hemos de teclear asimismo el nombre de la página (por ejemplo http://www.mipagina/index.html). 17 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Tambien habrás observado que en ocasiones al teclear solo el nombre del dominio, sin la página, obtenemos un listado del directorio de archivos disponibles, o sencillamente obtienes un mensaje de error. Todos estos comportamientos obedecen a concretas configuraciones de servidor, que ahora vamos a ver: Indexes Si incluimos esta opción, todo aquel que teclee solo nuestro nombre de dominio obtendrá un listado de los archivos disponibles, en lugar de la página principal. Por defecto Apache establece la opcion Indexes para el directorio htdocs, que como sabemos es el raiz de nuestro servidor: Options indexes FollowSymLinks MultiViews Si no queremos que salga este listado, sencillamente borramos la palabra Indexes. Ahora, quien escriba nuestro nombre de dominio, por ejemplo http://www.irvnet.com/ no obtendrá el listado de archivos, obtendrá un mensaje de error. DirectoryIndex Con esta opción evitamos ese error, indicando al servidor la página que ha de servir si el usuario no escribe ninguna. Por defecto es la siguiente: DirectoryIndex index.html y nosotros podemos añadir varias separandolas con un espacio. La preferencia la determina el orden de izquierda a derecha: DirectoryIndex index.html index.htm indice.htm index.php Manejando el servidor Como hemos dicho, Apache se ejecuta en modo consola, por lo que hemos de teclear las instrucciones siguientes para controlar su funcionamiento si no se ha configurado como un servicio. Los comandos básicos son: • • • • • apache -s apache -k start apache -k shutdown apache -k restart apahce –k install inicia el servidor inicia el servidor apaga el servidor reinicia el servidor instala el servidor como un servicio Cuando no se ejecuta como servicio el principal inconveniente es el de dejar abierta la ventana de DOS donde se está ejecutando Apache, y la necesidad de abrir una 18 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO sesion de DOS nueva para reiniciar o cerrar el servidor. En un momento dado, es fácil que la barra de tareas de tu pantalla quede llena de ventanas de aplicaciones. Se pueden manejar el servidor con un pequeño icono situado en el systray denominado Apache Monitor, desde el cual ponerlo en marcha, apagarlo o reiniciarlo, y lo que es más importante, haciendo desaparecer las ventanas DOS del escritorio. Con esto ya hemos cubierto los pasos básicos y tenemos el servidor operativo. No olvides cambiar la página de bienvenida de apache en C:\Archivos de programa\Apache Group\Apache\htdocs (C:\WAMP\Apache22\htdocs en nuestro curso) por tu propio contenido. 1.5. Instalación de PHP Obteniendo los archivos Las diferentes versiones de PHP se suceden sin parar. La que nosotros usamos aqui es la última de Mayo de 2008, PHP 5.2.6, que obtienes en el archivo php-5.2.6Win32.zip, de aprox. 9,29 megas, directamente de php.net. Instalando PHP Con un programa descompresor, como winzip, ejecutamos el archivo obtenido, descomprimiendo su contenido a un nuevo directorio que podemos llamar, por ejemplo, C:\WAMP\PHP526. Accedemos a ese directorio y hacemos dos operaciones: • • Copiar el archivo php5ts.dll desde el directorio de instalación de PHP al directorio de windows (c:\windows o c:\winnt o c:\win2000 o c:\winxp). Renombramos el archivo php.ini-recommended a php.ini. Preparando Apache para PHP5 Podemos instalar PHP como módulo de Apache o como CGI. La instalación como CGI se considera más estable y más segura, aunque como módulo se supone más rápida. Veremos en este manual las dos formas: PHP como CGI/FastCGI Recuperamos y editamos el archivo httpd.conf, que por defecto se halla en C:\Archivos de programa\Apache Group\Apache\conf\ y en nuestro curso en C:\WAMP\Apache22\conf\ Dentro del apartado "IfModule alias_module", vemos que apache se ocupa de los ScriptAlias. Introducimos la siguiente línea nueva: ScriptAlias /php/ "C:/WAMP/PHP526" 19 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO A continuacion buscamos otra sección que comienza diciendo “IfModule mime_module” y escribimos: AddType application/x-httpd-php .php Y una última modificación justo a continuación. Action application/x-httpd-php /php/php-cgi.exe Dado que Apache debe poder acceder al directorio donde se haya instalado PHP, debemos dotar, en el archivo de configuración de Apache, a dicho directorio de los permisos pertinentes. Para ello:AllowOverride None Options None Order allow,deny Allow from all Partimos de que has instalado php en c:\WAMP\PHP526; si no fuera asi, sustituye la ruta por la tuya propia (advierte que en el archivo de configuracion de Apache las barras son siempre invertidas /) Probando la instalación Abrimos nuestro editor de texto y escribimos: guardamos este archivo como prueba.php dentro de C:\Archivos de programa\Apache Group\Apache\htdocs (con una configuración por defecto) o en nuestro caso en C:\WAMP\www, que como sabemos es donde apache guarda los documentos a servir. Arrancamos Apache, y abrimos el navegador. Escribimos la dirección: http://localhost/prueba.php. Si todo funciona correctamente se abrirá una página con información de los parámetros de php. Si el navegador abre la dirección, pero en lugar de visualizar la página, ofrece guardarla en disco, revisa de nuevo que hayas modificado correctamente el archivo httpd.conf. PHP como módulo apache La instalación varía ligeramente. Los pasos son los siguientes: • • 20 movemos la libreria php5ts.dll desde el directorio de instalación de PHP al directorio de windows. (Este paso ya se hizo en la instalación como CGI) en lugar de las líneas que habiamos añadido a nuestro archivo httpd.conf de Apache en la instalación como CGI (que eliminamos pues ya no son necesarias, añadimos las siguientes: PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Dentro del apartado "Dynamic Shared Object (DSO) Support", añadimos el módulo de PHP5 para Apache 2.2, poniendo especial cuidado en poner la ruta a la DLL correctamente. LoadModule php5_module “c:/wamp/php526/php5apache2_2.dll A continuacion buscamos otra sección que comienza diciendo “IfModule mime_module” y escribimos: AddType application/x-httpd-php .php Y por último para que se carge el fichero de configuración de PHP, al final del archivo httpd.conf ponemos su ruta: PHPIniDir "C:/wamp/php526" Para verificar que todo esta correcto, ejecutamos de nuevo nuestro archivo de prueba (phpinfo) y veremos al comienzo el nuevo dato: Server API Apache 2.0 Handler Añadiendo módulos a php La distribución de php para windows viene con alguna de las extensiones necesarias ya incorporadas, por lo que normalmente no necesitaremos añadir ninguna extensión más. Pero en caso de necesitarlo, veremos como es el proceso para activarlas. Vamos a poner como ejemplo la extensión gd, que no viene instalada por defecto, y es necesaria para que php pueda generar gráficos "al vuelo": • Editamos nuestro php.ini, y buscamos en la sección de extensiones (Dynamic Extensions). Veremos que hay una lista de las disponibles, todas ellas comentadas (línea comenzando por ;). Buscamos la que nos interesa: ;extension=php_gd.dll, eliminamos el punto y coma inicial, guardamos el archivo. ;extension=php_gd.dll, • Copiamos la libreria php_gd.dll desde el directorio donde se encuentre (en la instalación por defecto, se encuentra en el directorio ext dentro de la instalación de PHP) al directorio que hayamos especificado en la directiva extension_dir que en nuestro php.ini). Otra opción muy recomendable es apuntar dicha directiva (extensión_dir) a la carpeta donde vienen instaladas las extensiones por defecto: extension_dir = "c:/wamp/php526/ext/" • Si la instalación de PHP es como módulo de Apache es necesario reiniciar el servidor web para que los cambios en el archivo php.ini tengan efecto. Si la instalación es como CGI no es necesario. ¿Que es el archivo php.ini? El archivo php.ini es el que contiene nuestra configuración de PHP, con el que podemos controlar muchos aspectos de su funcionamiento. A continuación se explica 21 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO para que sirve cada una de sus instrucciones y cual es la mejor forma de configurarlo. La explicación sigue el mismo orden interior de php.ini, aunque puede que haya ligeras diferencias con tu copia, debidas a pequeños cambios entre versiones. La configuración aqui contemplada es la que corresponde a las versiones php 5.2.x. Este archivo sirve para indicar una serie de valores que determinan el comportamiento del intérprete PHP. Lo encontramos dentro de la distribución php en el directorio raiz bajo el nombre php.ini-recommended o php.ini-dist. Se trata de un archivo de texto, que podemos abrir con cualquier editor que trabaje con texto simple (*.txt). Lo primero que debemos hacer es en efecto editar una de las dos versiones disponibles, configurarla de acuerdo a nuestras necesidades, y guardarla con el nombre php.ini. ¿Cual escoger? las dos son el mismo archivo, con distintos valores por defecto. Dentro de este archivo, todo lo que comienza con un punto y coma es un comentario, y es ignorado. El texto marcado con corchetes, como [PHP] indica una cabecera de sección. Las instrucciones se llaman directivas, y estan formadas por una pareja compuesta por la clave y su valor, por ejemplo: asp_tags = Off. Y ten cuidado, porque diferencia entre mayusculas y minusculas. No es lo mismo asp_tags que Asp_tags. También verás que algunas directivas comienzan con ; lo que quiere decir que estan comentadas ya que no son necesarias por defecto. Debes desactivarlas sin necesitas esa funcionalidad. Otro dato más a tener en cuenta. En windows las rutas o paths se escriben con la barra invertida (c:\windows) mientras que unix utiliza la barra (/usr/local/bin/...). En php.ini deberas indicar algunas rutas. Los formatos admisibles son: • • • C:\directorio\directorio \directorio\directorio /directorio/directorio/ Si no especificas la letra de la unidad, se presupone que es la unidad actual (esto es, donde tengas php.exe). ¿Como trabaja el archivo php.ini? Antes que nada aclarar que el proceso de instalación de PHP en tu ordenador NO crea el archivo php.ini. Una vez instalado PHP debes escoger uno de los archivos proporcionados como ejemplo y renombrarlos a php.ini Si tenemos PHP como módulo del servidor, el archivo php.ini se lee cada vez que se reinicia. Por lo tanto tienes que reiniciar para que actualice los cambios. Si PHP está instalado como CGI se leerá el php.ini en cada llamada a PHP. En ambos casos, lo primero a tener en cuenta será, pues, donde archivar php.ini. El servidor lo buscará sucesivamente -y por este orden- en el propio directorio php (c:/wamp/php526 si usas la instalacion por defecto). Si no lo encuentra alli lo buscará en la ruta definida como variable de entorno y finalmente en el directorio de sistema (c:/windows) 22 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Lo aconsejado es mover php.ini a tu directorio de sistema (c:\windows habitualmente). Cuida no dejar ninguna version antigua de php.ini en el directorio php, porque podría ser leida con preferencia a la que hayas movido a /windows/. Y *recuerda* que para que cualquier cambio que realices en el php.ini surta efecto, debes reiniciar tu servidor. Los problemas mas comunes que encontrarás con PHP pasan casi siempre por una incorrecta configuración de php.ini, y en muchos casos, por tener el archivo mal ubicado o duplicado, leyendose un archivo distinto del que tu estas configurando. Si haces un cambio en php.ini y este no se refleja en el funcionamiento de PHP, comprueba la sintaxis que has usado; que has reiniciado el servidor correctamente y que este lee el php.ini deseado. Controla siempre tus copias de php.ini Es altamente recomendable que tengas preparada una pagina con la función phpinfo() para ver como queda la configuración de tu php: Guarda esta página como info.php o como se te ocurra, y tenla a mano para comprobar la configuración en cuanto tengas tu php listo. Los dos php.ini En la carpeta PHP verás que hay dos archivos php.ini: uno php.ini-recommended y otro php.ini-dist. Los dos tienen las mismas directivas, pero configuradas de distinta forma. La version recomendada es mas exigente en cuestiones de seguridad (esencialmente la directiva registrar globales esta off y mostrar errores tambien off) mientras que dist, aunque menos segura, posiblemente permitirá funcionar a la mayoria de los scripts que puedas bajarte de internet, sin necesidad de adaptaciones. Las directivas Veremos a continuación cada una de las directivas y su significado, siguiendo el orden que podriamos ver en nuestro php.ini. Muchas directivas vienen con valores por defecto, o sin valor determinado, o comentadas (inactivas). Una buena política es dejarlas como estan, salvo que sepas exactamente que estas haciendo. Los valores que indicamos en esta página son indicativos. Lo que pretendemos es explicar el valor de cada directiva (al menos las que conocemos), no proponer un php.ini modélico. Opciones de lenguaje En esta primera sección encontramos algunas instrucciones generales sobre el funcionamiento de PHP: • engine = On - activa la interpretación de scripts php (si php está cargado como módulo de apache). Esta directiva, en unión de httpd.conf, permite habilitar o deshabilitar php en directorios determinados. 23 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • zend.ze1_compatibility_mode = Off -Habilita el modo de compatibilidad con el Motor Zend 1 (PHP 4). Afecta el modo de trabajar con los objetos. • short_open_tag = Off - Permite usar en tus scripts etiquetas php abreviadas , y el atajo para imprimir variables <%= $valor %>. Si el valor es off, deberas usar la forma o ) están siempre disponibles; el resto pueden ser configuradas en el fichero de php.ini para ser o no aceptadas por el intérprete. Mientras que el formato corto de etiquetas (short-form tags) y el estilo ASP (ASP-style tags) pueden ser convenientes, no son portables como la versión de formato largo de etiquetas. Además, si se pretende embeber código PHP en XML o XHTML, será obligatorio el uso del formato para la compatibilidad con XML. Las etiquetas soportadas por PHP son: Formas de escapar de HTML como aquí
"); "); ?> Esto es una abreviatura de ""
<% echo ("Opcionalmente, puedes usar las etiquetas ASP
"); %> <%= $variable; # Esto es una abreviatura de "<% echo . . ." %> El método primero, , es el más conveniente, ya que permite el uso de PHP en código XML como XHTML. El método segundo no siempre está disponible. El formato corto de etiquetas está disponible con la función short_tags() (sólo PHP 3), activando el parámetro del fichero de configuración de PHP short_open_tag, o compilando PHP con la opción -enable-short-tags del comando configure. Está activa por defecto en php.ini-dist. 33 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO El método cuarto sólo está disponible si se han activado las etiquetas ASP en el fichero de configuración: asp_tags. Nota: El soporte de etiquetas ASP se añadió en la versión 3.0.4. Nota: No se debe usar el formato corto de etiquetas cuando se desarrollen aplicaciones o librerías con intención de redistribuirlas, o cuando se desarrolle para servidores que no están bajo nuestro control, porque puede ser que el formato corto de etiquetas no esté soportado en el servidor. Para generar código portable y redistribuíble, asegúrate de no usar el formato corto de etiquetas. La etiqueta de fin de bloque incluirá tras ella la siguiente línea si hay alguna presente. Además, la etiqueta de fin de bloque lleva implícito el punto y coma; no necesitas por lo tanto añadir el punto y coma final de la última línea del bloque PHP. PHP permite estructurar bloques como: This is true. This is false. Este ejemplo realiza lo esperado, ya que cuando PHP encuentra las etiquetas ?> de fin de bloque, empieza a escribir lo que encuentra tal cual hasta que encuentra otra etiqueta de inicio de bloque. El ejemplo anterior es, por supuesto, inventado. Para escribir bloques grandes de texto generamente es más eficiente separalos del código PHP que enviar todo el texto mediante las funciones echo(), print() o similares. 2.2. Comentarios Una vez visto como se introduce código PHP dentro del código HTML, lo siguiente es ver como se puede comentar el código PHP. PHP soporta el estilo de comentarios de 'C', 'C++' y de la interfaz de comandos de Unix. Por ejemplo: Los estilos de comentarios de una línea (es decir, // y #) actualmente sólo comentan hasta el final de la línea o el bloque actual de código PHP, lo primero que ocurra.Esto es un ejemplo.
La cabecera de arriba dice 'Esto es un ejemplo.'. 34 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Hay que tener cuidado con no anidar comentarios de estilo 'C', algo que puede ocurrir al comentar bloques largos de código. Los estilos de comentarios de una linea actualmente sólo comentan hasta el final de la linea o del bloque actual de código PHP, lo primero que ocurra. Esto implica que el código HTML tras // ?> será impreso: ?> sale del modo PHP, retornando al modo HTML, el comentario // no le influye. 2.3. Instrucciones Un fragmento de código PHP va a estar compuesto por una o varias instrucciones. En PHP la separación de instrucciones se hace de la misma manera que en C o Perl - terminando cada instrucción con un punto y coma. La etiqueta de fin de bloque (?>) implica el fin de la instrucción, por lo tanto no es necesario un punto y coma después de la última instrucción. Como se ve en el ejemplo donde los dos fragmentos siguientes son equivalentes: Todo script PHP se compone de una serie de sentencias o instrucciones. Una sentencia puede ser una asignación, una llamada a función, un bucle, una sentencia condicional e incluso una sentencia que no haga nada (una sentencia vacía). Las sentencias normalmente acaban con punto y coma como se ha dicho anteriormente. Además, las sentencias se pueden agrupar en grupos de sentencias encapsulando un grupo de sentencias con llaves. Un grupo de sentencias es también una sentencia. Para construir las sentencias o instrucciones se necesitan distintos elementos: variables y constantes, operadores, estructuras de control, funciones, ... A continuación se irán viendo cada uno de estos elementos que permiten construir los scripts de PHP. 35 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 3. Variables y Constantes ® ® ® ® ® ® ® Conceptos Básicos Variables predefinidas Ambito de las variables Existencia y tipo de las variables Variables variables Variables externas a PHP Constantes 3.1. Conceptos Básicos En PHP las variables se representan como un signo de dólar seguido por el nombre de la variable. El nombre de la variable es sensible a minúsculas y mayúsculas. Los nombres de variables siguen las mismas reglas que otras etiquetas en PHP. Un nombre de variable valido tiene que empezar con una letra o una raya (underscore), seguido de cualquier número de letras, números y rayas. Como expresión regular se podría expresar como: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' Nota: En nuestro caso, una letra es a-z, A-Z, y los caracteres ASCII del 127 al 255 (0x7f-0xff). // imprime "Bob, Joe" // inválido; comienza con un número // valido; comienza con un subrayado // valido; 'ä' es ASCII 228 (Extendido) En PHP, las variables siempre se asignan por valor. Esto significa que cuando se asigna una expresión a una variable, el valor íntegro de la expresión original se copia en la variable de destino. Esto quiere decir que, por ejemplo, después de asignar el valor de una variable a otra, los cambios que se efectúen a una de esas variables no afectará a la otra. PHP ofrece otra forma de asignar valores a las variables: asignar por referencia. Esto significa que la nueva variable simplemente referencia (en otras palabras, "se convierte en un alias de" ó "apunta a") la variable original. Los cambios a la nueva variable afectan a la original, y viceversa. Esto también significa que no se produce una copia de valores; por tanto, la asignación ocurre más rápidamente. De cualquier forma, cualquier incremento de velocidad se notará sólo en los bucles críticos cuando se asignen grandes matrices u objetos. Para asignar por referencia, simplemente se antepone un signo ampersand "&" al comienzo de la variable cuyo valor se está asignando (la variable fuente). Por ejemplo, el siguiente trozo de código produce la salida 'Mi nombre es Bob' dos veces: = &$foo; // Referencia $foo vía $bar. = "Mi nombre es $bar"; // Modifica $bar... $foo; // $foo también se modifica. $bar; Algo importante a tener en cuenta es que sólo las variables con nombre pueden ser asignadas por referencia. No es necesario inicializar variables en PHP, sin embargo, es una muy buena práctica. Las variables no inicializadas tienen un valor predeterminado de acuerdo a su tipo - FALSE, cero, una cadena vacía o una matriz vacía. La función isset() se puede usar para detectar si una variable ya ha sido inicializada. 3.2. Variables predefinidas PHP proporciona una gran cantidad de variables predefinidas a cualquier script que se ejecute. De todas formas, muchas de esas variables no pueden ser completamente documentadas ya que dependen de sobre qué servidor se esté ejecutando, la versión y configuración de dicho servidor, y otros factores. Algunas de estas variables no estarán disponibles cuando se ejecute PHP desde la línea de comandos. Para obtener una lista de estas variables se puede consultar la sección Variables predefinidas reservadas de la ayuda de PHP. A partir de PHP 4.1.0, PHP ofrece un conjunto adicional de matrices predefinidas, conteniendo variables del servidor web, el entorno y entradas del usuario. Estas nuevas matrices son un poco especiales porque son automáticamente globales. Por esta razón, son conocidas a menudo como "autoglobales" ó "superglobales". Las superglobales existentes más usadas se detallan a continuación; sin embargo para una lista de sus contenidos y más información sobre variables dichas predefinidas en PHP, se pueden consultar la sección Variables predefinidas reservadas de la ayuda de PHP. • $GLOBALS : Contiene una referencia a cada variable disponible en el espectro de las variables del script. Las claves de esta matriz son los nombres de las variables globales. 38 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • $_SERVER : Variables definidas por el servidor web o directamente relacionadas con el entorno en donde el script se esta ejecutando. Análoga a la antigua matriz $HTTP_SERVER_VARS (la cual está todavía disponible, aunque no se use). echo $_SERVER['SERVER_NAME']; • $_GET : Variables proporcionadas al script por medio de HTTP GET. Análoga a la antigua matriz $HTTP_GET_VARS (la cual está todavía disponible, aunque no se use). Si el usuario ha visitado la siguiente dirección http://example.com/?nombre=Juan echo '¡Hola ' . • • $_POST : Variables proporcionadas al script por medio de HTTP POST. Análoga a la antigua matriz $HTTP_POST_VARS (la cual está todavía disponible, aunque no se use). $_COOKIE : Variables proporcionadas al script por medio de HTTP cookies. Análoga a la antigua matriz $HTTP_COOKIE_VARS (la cual está todavía disponible, aunque no se use). echo '¡Hola ' . • • $_GET["nombre"] . '!'; $_COOKIE["nombre"] . '!'; $_FILES : Variables proporcionadas al script por medio de la subida de ficheros via HTTP . Análoga a la antigua matriz $HTTP_POST_FILES (la cual está todavía disponible, aunque no se use). $_ENV : Variables proporcionadas al script por medio del entorno. Análoga a la antigua matriz $HTTP_ENV_VARS (la cual está todavía disponible, aunque no se use). echo '¡Mi nombre de usuario es ' . $_ENV["USER"] . '!'; • • $_REQUEST : Variables proporcionadas al script por medio de cualquier mecanismo de entrada del usuario ($_GET, $_POST, $_COOKIE) y por lo tanto no es recomendable su uso. La presencia y el orden en que aparecen las variables en esta matriz es definido por la directiva de configuración variables_order. Esta matriz no tiene un análogo en versiones anteriores a PHP 4.1.0. $_SESSION : Variables registradas en la sesión del script. Análoga a la antigua matriz $HTTP_SESSION_VARS (la cual está todavía disponible, aunque no se use). 3.3. Ambito de las variables El ámbito de una variable es el contexto dentro del que la variable está definida. La mayor parte de las variables PHP sólo tienen un ámbito simple. Este ámbito simple también abarca los ficheros incluidos y los requeridos. Por ejemplo: 39 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Aquí, la variable $a será visible dentro del script incluido b.inc. De todas formas, dentro de las funciones definidas por el usuario aparece un ámbito local a la función. Cualquier variable que se use dentro de una función está, por defecto, limitada al ámbito local de la función. Por ejemplo: Este script no producirá salida, ya que la orden echo utiliza una versión local de la variable $a, a la que no se ha asignado ningún valor en su ámbito. Puede que se note que hay una pequeña diferencia con el lenguaje C, en el que las variables globales están disponibles automáticamente dentro de la función a menos que sean expresamente sobreescritas por una definición local. Esto puede causar algunos problemas, ya que la gente puede cambiar variables globales inadvertidamente. En PHP, las variables globales deben ser declaradas globales dentro de la función si van a ser utilizadas dentro de dicha función mediante el modificador global. Veamos un ejemplo: El script anterior producirá la salida "3". Al declarar $a y $b globales dentro de la función, todas las referencias a tales variables se referirán a la versión global. No hay límite al número de variables globales que se pueden manipular dentro de una función. Un segundo método para acceder a las variables desde un ámbito global es usando la matriz $GLOBALS. El ejemplo anterior se puede reescribir así: La matriz $GLOBALS es una matriz asociativa con el nombre de la variable global como clave y los contenidos de dicha variable como el valor del elemento de la matriz. $GLOBALS existe en cualquier ámbito, esto pasa porque $GLOBALS es una superglobal. A continuación un ejemplo que demuestra el poder de las superglobales: Otra característica importante del ámbito de las variables es el modificador static. Una variable estática existe sólo en el ámbito local de la función, pero no pierde su valor cuando la ejecución del programa abandona este ámbito. Consideremos el siguiente ejemplo: Esta función tiene poca utilidad ya que cada vez que es llamada asigna a $a el valor 0 y representa un "0". La sentencia $a++, que incrementa la variable, no sirve para nada, ya que en cuanto la función termina la variable $a desaparece. Para hacer una función útil para contar, que no pierda la pista del valor actual del conteo, la variable $a debe declararse como estática: Ahora, cada vez que se llame a la función Test(), se representará el valor de $a y se incrementará. Las variables estáticas también proporcionan una forma de manejar funciones recursivas. Una función recursiva es la que se llama a sí misma. Se debe tener cuidado al escribir una función recursiva, ya que puede ocurrir que se llame a sí misma 41 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO indefinidamente. Hay que asegurarse de implementar una forma adecuada de terminar la recursión. La siguiente función cuenta recursivamente hasta 10, usando la variable estática $count para saber cuándo parar: Las variables estáticas pueden ser declaradas como se ha visto en los ejemplos anteriores. Al tratar de asignar valores a estas variables que sean el resultado de expresiones, causará un error de análisis sintáctico. 3.4. Existencia y tipo de una variable Hemos visto que en PHP el tratamiento de las variables es muy flexible, a la vez que impreciso. Su tiempo de vida también es breve. En ocasiones, antes de volver a usarla, es necesario conocer si una variable está definida y, si lo está, qué valor tiene. Puede ser que en el transcurso de un programa que llame a varias páginas web la variable haya sido eliminada de la memoria o que haya adquirido el valor nulo. Para conocer estos dos datos, PHP dispone de las dos funciones siguientes: 1. empty(), que devuelve el valor verdadero si la variable no está definida o lo está, pero tiene un valor nulo. Por ejemplo, si a la variable $num le asignamos el valor 10, las instrucciones if (!empty($num)) echo "La variable \$num contiene $num."; else echo "La variable \$num no está definida."; genera la página La variable $num contiene 10. En cambio, si no hubiéramos definido la variable, devolvería La variable $num no está definida. 42 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 2. isset(), que devuelve el valor verdadero si la variable ha sido inicializada con un valor y falso si no lo ha sido. Por ejemplo, si inicializamos la variable $num con valor 10, las instrucciones if (isset($num)) echo "La variable \$num ha sido inicializada y contiene $num."; else echo "La variable \$num no ha sido inicializada o definida."; genera La variable $num ha sido inicializada y contiene 10. En cambio, si no hubiéramos definido la variable, devolvería La variable $num no ha sido inicializada o definida. Cómo obtener información sobre el tipo de una variable A veces, también necesitamos saber de qué tipo son las variables. PHP dispone con este fin de un conjunto de funciones que empiezan por is_ y que devuelven verdadero si el tipo de variable es el que se indique y falso si no lo es. Son las siguientes: 1. is_array(): Devuelve verdadero si el tipo de la variable es una matriz y falso si no lo es. 2. is_bool(): Devuelve verdadero si el tipo de la variable es booleano y falso si no lo es. 3. is_float() o is_double() o is_real(): Devuelve verdadero si el tipo de la variable es un número en coma flotante y falso si no lo es. 4. is_int() o is_integer() o is_long(): Devuelve verdadero si el tipo de la variable es un número entero y falso si no lo es. 5. is_object(): Devuelve verdadero si el tipo de la variable es un objeto y falso si no lo es. 6. is_resource(): Devuelve verdadero si el tipo de la variable es un recurso y falso si no lo es. 7. is_scalar(): Devuelve verdadero si el tipo de la variable es un escalar (integer, float, string o booleano) y falso si no lo es. 8. is_string(): Devuelve verdadero si el tipo de la variable es una cadena de caracteres y falso si no lo es. 9. is_null():Devuelve verdadero si el tipo de la variable es el valor NULL y falso si no lo es. 43 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 10. is_numeric(): Devuelve verdadero si la variable es un número o una cadena numérica o falso si no lo es. 11. gettype(): Esta última función, más directa que las anteriores, devuelve directamente el tipo de la variable que se le pasa como argumento. Los tipos posibles son integer, double, string, array, object y unknown (desconocido). Si sólo se necesita saber de qué tipo es una variable, esta última función es la más directa y recomendable. En cambio, si se necesita que una variable sea de un determinado tipo para operar con ella, es más directo y recomendable utilizar la correspondiente anterior. Cómo modificar una variable PHP dispone también de funciones para realizar estas operaciones: 1. Eliminar una variable de la memoria. Recordamos que todas las variables se eliminan por sí mismas al acabar la interpretación de un programa, por lo cual no es necesario eliminarlas explícitamente. Esta operación sólo es recomendable cuando se comprueba que dentro de un mismo script php se consumen innecesariamente muchos recursos, como cuando hay muchas variables definidas que ya no se usan. En este caso, podemos utilizar la función unset(), que elimina una variable definida previamente. El nombre de la variable que debe eliminarse se pasa a la función como parámetro. Por ejemplo, si queremos que $casa ya no esté definida, podemos escribir unset($casa). Si la operación se ha llevado a cabo con éxito, la función devuelve el valor verdadero; de lo contrario, devuelve falso. 2. Asignar un tipo concreto a una variable. La función settype() permite, igualmente, forzar que una variable sea del tipo especificado. Por ejemplo, si queremos que la variable $cosa sea de tipo cadena, debemos escribir: settype($cosa, "string"); . Como puede observarse, el primer argumento es el nombre de la variable y el segundo (entre comillas dobles) es el tipo de dato que debe tener: boolean, integer, float, string, array, object, null. // $bar es ahora "1" (string) Separar el contenido de una variable El contenido de una variable de cadena puede contener letras y números. PHP dispone de diferentes funciones que permiten separar los números del texto y asignarlos a las variables correspondientes de su tipo. Por ejemplo, si tenemos la cadena “89.53Pepe es madrileño”, es posible separar el contenido numérico de este texto: 89.53. Veamos cómo se hace estudiando cada una de las funciones siguientes: 1. floatval(): Devuelve el número de coma flotante que haya en la frase. Conviene advertir que esto sólo ocurre si el número de coma flotante aparece al principio de la frase. De no se así, se devuelve 0. 2. intval(): Devuelve el número entero que haya en la cadena o 0 si no lo hay. 3. strval(): Devuelve una cadena de caracteres utilizando el contenido de la variable. Ver el contenido de variables no escalares Si se desea ver el contenido de una variable no escalar (arrays, objetos), no se puede hacer uso de las funciones echo() y print(). Para ver el contenido de variables de estos tipos podemos usar las funciones print_r() y var_dump(). $a = array ('a' => 'manzana', 'b' => 'banano', 'c' => array ('x', 'y', 'z ')); print_r ($a); $a = array(1, 2, array("a", "b", "c")); var_dump ($a); 3.5. Variables variables A veces es conveniente tener nombres de variables variables. Dicho de otro modo, son nombres de variables que se pueden establecer y usar dinámicamente. Una variable normal se establece con una sentencia como: Una variable variable toma el valor de una variable y lo trata como el nombre de una variable. En el ejemplo anterior, hello, se puede usar como el nombre de una variable utilizando dos signos de dólar. p.ej. 45 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO En este momento se han definido y almacenado dos variables en el árbol de símbolos de PHP: $a, que contiene "hello", y $hello, que contiene "world". Es más, esta sentencia: produce el mismo resultado que: p.ej. ambas producen el resultado: hello world. Para usar variables variables con matrices, hay que resolver un problema de ambigüedad. Si se escribe $$a[1] el intérprete necesita saber si nos referimos a utilizar $a[1] como una variable, o si se pretendía utilizar $$a como variable y el índice [1] como índice de dicha variable. La sintaxis para resolver esta ambiguedad es: ${$a[1]} para el primer caso y ${$a}[1] para el segundo. Aviso Hay que tener en cuenta que variables variables no pueden usarse con Matrices superglobales. Esto significa que no se pueden hacer cosas como ${$_GET}. 3.6. Constantes Una constante es un identificador para expresar un valor simple. Como el nombre sugiere, este valor no puede variar durante la ejecución del script. (Las constantes especiales __FILE__ y __LINE__ son una excepción a esto, ya que actualmente no lo son). Una constante es sensible a mayúsculas por defecto. Por convención, los identificadores de constantes suelen declararse en mayúsculas. El nombre de una constante sigue las mismas reglas que cualquier etiqueta en PHP. Un nombre de constante válido empieza con una letra o un caracter de subrayado, seguido por cualquier número de letras, números, o subrayados. Se podrían expresar mediante la siguiente expresión regular: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* El alcance de una constante es global, es decir, es posible acceder a ellas sin preocuparse por el ámbito de alcance. Se puede definir una constante usando la función define(). Una vez definida, no puede ser modificada ni eliminada. La sintaxis de define() es la siguiente: int define(string nombre, mixed valor [, int noMayusculas]) Solo se puede definir como constantes valores escalares (boolean, integer, float y string ). 46 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Para obtener el valor de una constante solo es necesario especificar su nombre. A diferencia de las variables, no se tiene que especificar el prefijo $. También se puede utilizar la función constant(), para obtener el valor de una constante, en el caso de que queramos expresarla de forma dinámica se debe usar la función get_defined_constants() parar obtener una lista de todas las constantes definidas. Nota: Las constantes y las variables (globales) se encuentran en un espacio de nombres distinto. Esto implica que por ejemplo TRUE y $TRUE son diferentes. Si se usa una constante todavía no definida, PHP asume que se está refiriendo al nombre de la constante en si. Se lanzará un aviso si esto sucede. Se debe usar la función defined() para comprobar la existencia de dicha constante. Estas son las diferencias entre constantes y variables: • • • • • Las constantes no van precedidas por un símbolo de dolar ($) Las contantes solo pueden ser definidas usando la función define() , nunca por simple asignación Las constantes pueden ser definidas y se accede a ellas sin tener en cuenta las reglas de alcance del ámbito. Las constantes no pueden ser redefinidas o eliminadas después de establecerse; y Las constantes solo puede albergar valores escalares world."); "Hello world." "Constant" y imprime una alerta. // Imprime lo mismo que la anterior 47 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 4. Tipos de Datos ® ® ® ® ® ® ® ® ® Booleanos Enteros Números en punto flotante Cadenas Arrays Objetos Recursos NULL Forzado de tipos PHP soporta ocho tipos primitivos: • • • • • • • • booleanos enteros números en punto flotante cadenas matrices objetos recursos (resource) NULL El tipo de una variable normalmente no lo indica el programador; en su lugar, lo decide PHP en tiempo de ejecución dependiendo del contexto en el que se utilice esa variable. Si desea conocer el tipo y valor de una expresión, se puede usar la función var_dump(). Para obtener una representación legible para humanos del tipo de una variable para propósitos de depuración, se puede usar la función gettype(). Para comprobar si una variable es de un cierto tiepo, no se debe usar gettype(), si no las funciones is_tipo. Si se quisiese obligar a que una variable se convierta a un tipo concreto, se podría forzar la variable o usar la función settype() para ello. 49 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Nótese que una variable se puede comportar de formas diferentes en ciertas situaciones, dependiendo de qué tipo sea en ese momento. 4.1. Booleanos Este es el tipo más simple. Un booleano expresa un valor de verdad. Puede ser TRUE o FALSE. Para especificar un literal booleano, use alguna de las palabras clave TRUE o FALSE. Ambas son insensibles a mayúsculas y minúsculas. $foo = True; // asigna el valor TRUE a $foo 4.2. Enteros Los enteros se pueden especificar usando una de las siguientes sintaxis: $a $a $a $a = = = = 1234; -123; 0123; 0x12; # # # # número decimal un número negativo número octal (equivalente al 83 decimal) número hexadecimal (equivalente al 18 decimal) 4.3. Números en punto flotante Los números en punto flotante (double) se pueden especificar utilizando cualquiera de las siguientes sintaxis: $a = 1.234; $a = 1.2e3; $a = 7E-10; 4.4. Cadenas Las cadenas de caracteres se pueden especificar usando uno de dos tipos de delimitadores. Si la cadena está encerrada entre dobles comillas ("), las variables que estén dentro de la cadena serán expandidas (sujetas a ciertas limitaciones de interpretación). Como en C y en Perl, el carácter de barra invertida ("\") se puede usar para especificar caracteres especiales: secuencia \n \r \t \\ \$ \" significado Nueva línea Retorno de carro Tabulación horizontal Barra invertida Signo del dólar Comillas dobles la secuencia de caracteres que coincida con la expresión regular es un carácter en \[0-7]{1,3} notación octal la secuencia de caracteres que coincida con la expresión regular es un carácter en \x[0-9A-Fa-f]{1,2} notación hexadecimal 50 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Se puede proteger cualquier otro carácter, pero se producirá una advertencia en el nivel de depuración más alto. La segunda forma de delimitar una cadena de caracteres usa el carácter de comilla simple (‘). Cuando una cadena va encerrada entre comillas simples, los únicos caracteres de escape que serán comprendidos son \\ y \'. Esto es por convenio, así que se pueden tener comillas simples y barras invertidas en una cadena entre comillas simples. Las variables no se expandirán dentro de una cadena entre comillas simples. Las cadenas se pueden concatenar usando el operador . (punto). Nótese que el operador + (suma) no sirve para esto. Se puede acceder a los caracteres dentro de una cadena tratándola como un array de caracteres indexado numéricamente, usando una sintaxis similar a la de C. Vea un ejemplo más abajo. Número: 9
' */ $num = 9; $str = "Número: $num
"; /* Esta será 'Número: $num
' */ $num = 9; $str = 'Número: $num
'; /* Obtener el primer carácter de una cadena $str = 'Esto es una prueba.'; $first = $str[0]; */ /* Obtener el último carácter de una cadena. */ $str = 'Esto es aún una prueba.'; $last = $str[strlen($str)-1]; ?> 4.4.1. Conversión a cadenas Un valor puede ser convertido a cadena usando el moldeamiento (string) o la función strval(). Un valor booleano TRUE es convertido a la cadena "1", el valor FALSE se representa como "" (la cadena vacía). De esta forma, se puede convertir de ida y vuelta entre valores booleanos y de cadena. Un número integer o de punto flotante (float) es convertido a una cadena que representa el número textualmente (incluyendo la parte del exponente para los números de punto flotante). Los números de punto flotante pueden ser convertidos usando la notación exponencial (4.1E+6). 51 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Las matrices son siempre convertidas a la cadena "Array"; por esta razón, echo() y print() no pueden por su cuenta mostrar los contenidos de un valor array. Para ver un elemento sencillo, use una construcción como echo $arr['foo']. Los objetos a partir de PHP 4 son convertidos siempre a la cadena "Object". Por eso, al igual que pasa con las matrices echo() y print() no pueden por su cuenta mostrar los contenidos de un valor objecto. Los recursos son siempre convertidos a cadenas con la estructura "Resource id #1" en donde 1 es el número único del valor recurso asignado por PHP en tiempo de ejecución. No se debe escribir código que dependa de esta estructura; está sujeta a cambios. NULL se convierte siempre a una cadena vacía. Como se ha indicado anteriormente, convertir directamente un valor tipo array, object, o resource a un string no ofrece información útil sobre los valores más allá de su tipo. Si desea inspeccionar el contenido de estos tipos debe usar las funciones print_r() y var_dump(). La mayoría de valores PHP pueden ser convertidos también a string para su almacenamiento permanentemente. Este método es conocido como serialización (seriación), y es efectuado por la función serialize(). 4.4.2. Conversión de cadenas a números Cuando una cadena se evalúa como un valor numérico, el valor resultante y el tipo se determinan como sigue. La cadena se evaluará como un doble si contiene cualquiera de los caracteres '.', 'e', o 'E'. En caso contrario, se evaluará como un entero. El valor viene dado por la porción inicial de la cadena. Si la cadena comienza con datos de valor numérico, este será el valor usado. En caso contrario, el valor será 0 (cero). Los datos numéricos válidos son un signo opcional, seguido por uno o más dígitos (que opcionalmente contengan un punto decimal), seguidos por un exponente opcional. El exponente es una 'e' o una 'E' seguidos por uno o más dígitos. Cuando la primera expresión es una cadena, el tipo de la variable dependerá de la segunda expresión. $foo $foo $foo $foo $foo $foo $foo $foo = = = = = = = = 1 + "10.5"; 1 + "-1.3e3"; 1 + "bob-1.3e3"; 1 + "bob3"; 1 + "10 Cerditos"; 1 + "10.0 Cerditos"; "10.0 cerdos " + 1; "10.0 cerdos " + 1.0; // // // // // // // // $foo $foo $foo $foo $foo $foo $foo $foo es es es es es es es es doble (11.5) doble (-1299) entero (1) entero (1) entero (11) double (11) double (11) double (11) Si quisiera probar cualquiera de los ejemplos de esta sección, puede cortar y pegar los ejemplos e insertar la siguiente línea para ver por sí mismo lo que va ocurriendo: 52 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO echo "\$foo==$foo; el tipo es " . gettype( $foo ) . "
\n"; 4.5. Arrays Los arrays actualmente actúan tanto como tablas hash (arrays asociativos) como arrays indexados (vectores). 4.5.1. Arrays unidimensionales PHP soporta tanto arrays escalares como asociativos. De hecho, no hay diferencias entre los dos. Se puede crear una array usando las funciones list() o array(), o se puede asignar el valor de cada elemento del array de manera explícita. $a[0] = "abc"; $a[1] = "def"; $b["foo"] = 13; $matriz = array("foo" => "bar", 12 => true); También se puede crear un array simplemente añadiendo valores al array. Cuando se asigna un valor a una variable array usando corchetes vacíos, el valor se añadirá al final del array. $a[] = "hola"; // $a[2] == "hola" $a[] = "mundo"; // $a[3] == "mundo" Los arrays se pueden ordenar usando las funciones asort(), arsort(), ksort(), rsort(), sort(), uasort(), usort(), y uksort() dependiendo del tipo de ordenación que se desee. Se puede contar el número de elementos de un array usando la función count(). Se puede recorrer un array usando las funciones next() y prev(). Otra forma habitual de recorrer un array es usando la función each(). 4.5.2. Arrays Multidimensionales Los arrays multidimensionales son bastante simples actualmente. Para cada dimensión del array, se puede añadir otro valor [clave] al final: $a[1] $a["foo"] = $f; = $f; $a[1][0] = $f; $a["foo"][2] = $f; $a[3]["bar"] = $f; # ejemplos de una sola dimensión # bidimensional # (se pueden mezclar índices numéricos y asociativos) # (se pueden mezclar índices numéricos y asociativos) $a["foo"][4]["bar"][0] = $f; # tetradimensional! En PHP3 no es posible referirse a arrays multidimensionales directamente dentro de cadenas. Por ejemplo, lo siguiente no tendrá el resultado deseado: $a[3]['bar'] = 'Bob'; echo "Esto no va a funcionar: $a[3][bar]"; 53 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO En PHP3, lo anterior tendrá la salida Esto no va a funcionar: Array[bar]. De todas formas, el operador de concatenación de cadenas se puede usar para solucionar esto: $a[3]['bar'] = 'Bob'; echo "Esto va a funcionar: " . $a[3][‘bar’]; A partir de PHP4, sin embargo, todo el problema se puede solucionar encerrando la referencia al array (dentro de la cadena) entre llaves: $a[3]['bar'] = 'Bob'; echo "Esto va a funcionar: {$a[3][‘bar’]}"; Se pueden "rellenar" arrays multidimensionales de muchas formas, pero la más difícil de comprender es cómo usar el comando array() para arrays asociativos. Estos dos trozos de código rellenarán el array unidimensional de la misma manera: # Ejemplo 1: $a["color"] $a["sabor"] $a["forma"] $a["nombre"] $a[3] = = = = = "rojo"; "dulce"; "redondeada"; "manzana"; 4; # Ejemplo 2: $a = array( "color" => "rojo", "sabor" => "dulce", "forma" => "redondeada", "nombre" => "manzana", 3 => 4 ); La función array() se puede anidar para arrays multidimensionales: "color" "sabor" "forma" ), "naranja" => "color" "sabor" "forma" ), "plátano" => "color" "sabor" "forma" ) ); array( => "rojo", => "dulce", => "redondeada" array( => "naranja", => "ácido", => "redondeada" array( => "amarillo", => "paste-y", => "aplatanada" echo $a["manzana"]["sabor"]; ?> # devolverá "dulce" Siempre deben usarse comillas alrededor de un índice de matriz tipo cadena literal. Por ejemplo, $foo['bar'] es correcto, mientras que $foo[bar] no lo es. Funciona pero no es correcto. Funciona porque PHP automáticamente convierte una cadena pura (una cadena sin comillas que no corresponda con símbolo conocido alguno) en una cadena que contiene la cadena pura. Por ejemplo, si no se ha definido una constante llamada bar, entonces PHP reemplazará su valor por la cadena 'bar' y usará ésta última. 54 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 4.6. Objetos Para inicializar un objeto, se usa la sentencia new para instanciar el objeto a una variable. class foo { function do_foo () { echo "Haciendo foo."; } } $bar = new foo; $bar->do_foo(); 4.7. Recursos Un valor tipo resource es una variable especial, que contiene una referencia a un recurso externo. Los recursos son creados y usados por funciones especiales. Gracias al sistema de conteo de referencias introducido con el Motor Zend de PHP 4, un recurso que ya no es referenciado es detectado automáticamente, y es liberado por el recolector de basura. Por esta razón, rara vez se necesita liberar la memoria manualmente. Los enlaces persistentes con bases de datos son una excepción a esta regla. Estos no son destruidos por el recolector de basura. 4.8. NULL El valor especial NULL representa una variable que no tiene valor. NULL es el único valor posible del tipo NULL. Una variable es considerada como null si: Ö se le ha asignado la constante NULL. Ö no ha sido definida con valor alguno. Ö ha sido eliminada con unset(). Existe un solo valor de tipo null, y ese es la palabra clave NULL, insensible a mayúsculas y minúsculas. $var = NULL; Hay varias funciones interesantes para trabajar con el valor null: is_null() y unset(). 4.9. Forzado de tipos PHP no requiere (o soporta) la declaración explícita del tipo en la declaración de variables; el tipo de una variable se determina por el contexto en el que se usa esa variable. Esto quiere decir que si se asigna un valor de cadena a la variable var, var se convierte en una cadena. Si después se asigna un valor entero a la variable var, se convierte en una variable entera. 55 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Un ejemplo de conversión de tipo automática en PHP es el operador suma '+'. Si cualquiera de los operandos es un flotante, entonces todos los operandos se evalúan como flotantes, y el resultado será un flotante. En caso contrario, los operandos se interpretarán como enteros, y el resultado será también un entero. Nótese que esto NO cambia los tipos de los operandos propiamente dichos; el único cambio está en cómo se evalúan los operandos. $foo = "0"; // $foo es una cadena (ASCII 48) $foo++; // $foo es la cadena "1" (ASCII 49) convertido a entero (1) $foo += 1; // $foo ahora es un entero (2) $foo = $foo + 1.3; // $foo ahora es un doble (3.3) $foo = 5 + "10 Cerditos Pequeñitos"; // $foo es entero (15) $foo = 5 + "10 Cerditos"; // $foo es entero (15) Si se desea obligar a que una variable sea evaluada con un tipo concreto se puede realizar un forzado de tipos. Si se desea cambiar el tipo de una variable se puede usar la función settype(). Si quisiese probar cualquiera de los ejemplos de esta sección, puede cortar y pegar los ejemplos e insertar la siguiente línea para ver por sí mismo lo que va ocurriendo o usar la función var_dump(): echo "\$foo==$foo; el tipo es " . gettype( $foo ) . "
\n"; Nota: La posibilidad de una conversión automática a array no está definida actualmente. $a = 1; $a[0] = "f"; // $a es un entero // $a se convierte en un array, en el que $a[0] vale "f" Aunque el ejemplo anterior puede parecer que claramente debería resultar en que $a se convierta en un array, el primer elemento del cual es 'f', consideremos esto: $a = "1"; $a[0] = "f"; // $a es una cadena // ¿Qué pasa con los índices de las cadenas? ¿Qué ocurre? Dado que PHP soporta indexación en las cadenas vía offsets usando la misma sintaxis que la indexación de arrays, el ejemplo anterior nos conduce a un problema: ¿debería convertirse $a en un array cuyo primer elemento sea "f", o debería convertirse "f" en el primer carácter de la cadena $a? El forzado de tipos en PHP funciona como en C: el nombre del tipo deseado se escribe entre paréntesis antes de la variable a la que se pretende forzar. $foo = 10; // $foo es un entero $bar = (double) $foo; // $bar es un doble Los forzados de tipo permitidos son: (int), (integer) - fuerza a entero (integer) (bool),(bolean) – fuerza a booleano (real), (double), (float) - fuerza a doble (double) (string) - fuerza a cadena (string) (array) - fuerza a array (array) (object) - fuerza a objeto (object) 56 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Nótese que las tabulaciones y espacios se permiten dentro de los paréntesis, así que los siguientes ejemplos son funcionalmente equivalentes: $foo = (int) $bar; $foo = ( int ) $bar; Puede no ser obvio que ocurrirá cuando se fuerce entre ciertos tipos. Por ejemplo, lo siguiente debería ser tenido en cuenta. Cuando se fuerza el cambio de un escalar o una variable de cadena a un array, la variable se convertirá en el primer elemento del array: $var = 'ciao'; $arr = (array) $var; echo $arr[0]; // produce la salida 'ciao' Cuando se fuerza el tipo de una variable escalar o de una cadena a un objeto, la variable se convertirá en un atributo del objeto; el nombre del atributo será 'scalar': $var = 'ciao'; $obj = (object) $var; echo $obj->scalar; // produce la salida 'ciao' Cuando se fuerza el tipo de una variable a booleano, el valor de la variable será FALSE si: es el valor booleano FALSE, si es el entero 0, si es el flotante 0.0 si es la cadena vacía o la cadena “0”, si es un array con cero elementos, si es NULL; en cualquier otro caso el valor será TRUE. 57 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 5. Operadores ® ® ® ® ® ® ® ® ® ® ® ® Operadores Aritméticos Operadores de Asignación Operadores de Bits Operadores de Comparación Operadores de Control de Errores Operador de Ejecución Operadores de Incremento/decremento Operadores Lógicos Operador de cadenas de texto Operadores de Matrices Operadores de Tipo Precedencia y asociatividad de operandos 5.1. Operadores Aritméticos Disponemos de los clásicos operadores aritméticos: Operación $a + $b $a - $b $a * $b $a / $b $a % $b -$a Nombre Suma Resta Multiplicación División Módulo Negación Resultado Suma de $a y $b. Diferencia entre $a y $b. Producto de $a y $b. Cociente de $a y $b. Resto de la operación $a / $b. El opuesto de $a 5.2. Operadores de Asignación El operador básico de asignación es "=". A primera vista podrías pensar que es el operador de comparación "igual que". Pero no. Realmente significa que el operando de la izquierda toma el valor de la expresión a la derecha, (esto es, "toma el valor de"). El valor de una expresión de asignación es el propio valor asignado. Esto es, el valor de "$a = 3" es 3. Esto permite hacer cosas curiosas como $a = ($b = 4) + 5; // ahora $a es igual a 9, y $b vale 4. Además del operador básico de asignación, existen los "operadores combinados" para todas las operaciones aritméticas y de cadenas que sean binarias. Este operador combinado permite, de una sola vez, usar una variable en una expresión y luego establecer el valor de esa variable al resultado de la expresión. Por ejemplo: $a $a $b $b = 3; += 5; // establece $a a 8, como si hubiésemos escrito: $a = $a + 5; = "Hola "; .= "Ahí!"; // establece $b a "Hola Ahí!", igual que si hiciésemos $b = $b . "Ahí!"; Al igual que en C, C++ y Java, en PHP se dispone de estos operadores combinados para, en una sola operación, operar sobre una variable y asignarle a esa misma variable el resultado. 59 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Las operaciones susceptibles de ser usadas con estos operadores son: + - * / % & ^ . >> y << resultando en los nuevos signos de operación-asignación: += -= *= /= %= &= ^= .= >>= y <<= Ejemplos de uso: $var1 += 3; $var2 /= 2; $var3 >>= 1; // $var1 = $var1 + 3; // $var2 = $var2 / 2; // $var3 = $var3 >> 1; Fíjese en que la asignación realiza una nueva copia de la variable original (asignación por valor), por lo que cambios a la variable original no afectan a la copia. Esto puede tener interés si necesitas copiar algo como un array con muchos elementos dentro de un bucle que se repita muchas veces (cada vez se realizará una nueva copia del array). PHP soporta asignación por referencia, usando la sintaxis $var = &$othervar; , pero esto no es posible en PHP3. 'Asignación por referencia' quiere decir que ambas variables acabarán apuntando al mismo dato y que nada es realmente copiado. A partir de PHP5 los objetos son asignados por referencia a menos que explícitamente se diga lo contrario con la nueva palabra clave clone. 5.3. Operadores de bits Veamos ahora los operadores BIT a BIT de que dispone PHP: Operación Nombre $a & $b Y $a | $b O O Exclusivo $a ^ $b (XOR) ~ $a No $a << $b Desp. Izq. $a >> $b Desp. Drch. Resultado Se ponen a 1 los bits que están a 1 en $a y $b. Se ponen a 1 los bits que están a 1 en $a o $b. Se ponen a 1 los bits que están a 1 en $a o $b, pero no en ambos. Se invierten los bits (se cambian 1 por 0 y viceversa.) Desplaza $b posiciones a la izquierda todos los bits de $a (cada posición supone multiplicar por dos). Desplaza $b posiciones a la derecha todos los bits de $a (cada posición supone dividir por dos). 5.4. Operadores de Comparación Los operadores de comparación, como su nombre indica, permiten comparar dos valores. Operación Nombre $a == $b Igualdad $a === $b Identidad $a != $b No igual $a !== $b No idéntico $a < $b Menor que 60 Resultado Compara si el valor de los dos operandos es el mismo. Compara si el valor es el mismo y, además, el tipo coincide (A partir de PHP4). Cierto si el valor de $a no es igual al de $b. Cierto si $a no es igual a $b, o si no tienen el mismo tipo. Cierto si $a es estrictamente menor que $b. PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Operación $a > $b $a <= $b $a >= $b $a <> $b Nombre Mayor que Menor o igual que Mayor o igual que No igual Resultado Cierto si Cierto si Cierto si Cierto si $a $a $a el es estrictamente mayor que $b. es menor o igual que $b. es mayor o igual que $b. valor de $a no es igual al de $b Si se compara un entero con una cadena, la cadena es convertida a un número. Si se compara dos cadenas numéricas, son comparadas como enteros. Estas reglas también se aplican a la sentencia switch. Otro operador condicional es el operador "?:" (o ternario), que funciona como en C y otros muchos lenguajes. (expr1) ? (expr2) : (expr3); La expresión toma el valor expr2 si expr1 se evalúa a cierto, y expr3 si expr1 se evalúa a falso. $cad = $a > $b ? “a es mayor que b” : “a no es mayor que b”; 5.5. Operadores de Control de Errores PHP ofrece soporte para un operador de control de errores: el signo de arroba (@). Cuando es colocado al comienzo de una expresión en PHP, cualquier mensaje de error que pudiera generarse a causa de esa expresión será ignorado. Si la característica track_errors está habilitada, cualquier mensaje de error generado por la expresión será almacenado en la variable $php_errormsg. La variable será sobrescrita en cada instancia de error, así que realice sus chequeos de forma temprana si quiere usarla. Puede usar el operado @ al inicio de variables, llamadas a funciones y sentencias include(), constantes. No puede usarlo sobre definiciones de función o clase, ni sobre estructuras condicionales como if y foreach. 5.6. Operador de ejecución PHP soporta un operador de ejecución: la comilla invertida (`). ¡Fíjese que no son comillas normales! PHP intentará ejecutar la instrucción contenida dentro de las 61 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO comillas invertidas como si fuera un comando del shell; y su salida devuelta como el valor de esta expresión (i.e., no tiene por qué ser simplemente volcada como salida; puede asignarse a una variable). El uso de este operados es idéntico a la función shell_exec(). $output = `dir /a-d`; echo "$output"; 5.7. Operadores de Incremento/decremento PHP soporta los operadores de pre y post decremento y incremento al estilo de C. Estos operadores no afectan a valores booléanos y incrementar NULL resulta en 1. Operación Nombre ++$a Pre-incremento $a++ Post-incremento --$a $a-- Pre-decremento Post-decremento Resultado Incrementa $a en 1, y devuelve $a (ya incrementado) Devuelve $a (sin incrementar), y después lo incrementa en 1. Decrementa $a en 1, y después lo devuelve. Devuelve $a, y después lo incrementa en 1. He aquí un listado de ejemplo: Postincremento"; $a = 5; echo "Debería ser 5: " . $a++ . "
\n"; echo "Debería ser 6: " . $a . "
\n"; echo $a = echo echo "Preincremento
"; 5; "Debería ser 6: " . ++$a . "
\n"; "Debería ser 6: " . $a . "
\n"; echo $a = echo echo "Postdecremento
"; 5; "Debería ser 5: " . $a-- . "
\n"; "Debería ser 4: " . $a . "
\n"; echo $a = echo echo ?> "Predecremento
"; 5; "Debería ser 4: " . --$a . "
\n"; "Debería ser 4: " . $a . "
\n"; 5.8. Operadores lógicos Los operadores lógicos realizan operaciones dependiendo del valor booleano de los operandos. 62 Operación $a and $b $a or $b Nombre Y O $a xor $b O Exclusivo. ! $a $a && $b $a || $b No Y O Resultado Cierto si $a y $b son ciertos. Cierto si $a o $b es cierto. Cierto si $a o $b es cierto, pero no ambos. Cierto si $a es falso. Cierto si $a y $b son ciertos. Cierto si $a o $b es cierto. PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La razón de que haya dos operadores distintos para las operaciones Y y O lógicas es que tienen distinta precedencia. 5.9. Operador de cadenas de texto Para operar con cadenas sólo disponemos de un operador: la concatenación de cadenas representada por el punto ‘.’. Por ejemplo: $a = 1; $b = 2; $c = “El resultado de “ . $a . “ + “ . $b . “ es “ . ($a + $b); Que dejaría en $c la cadena “El resultado de 1 + 2 es 3”. Antes de cada concatenación se realizarán las conversiones de tipo que fueran necesarias (en el ejemplo, los enteros se convierten a cadenas.) 5.10. Operadores de Matrices Ejemplo Nombre $a + $b Unión $a == $b Igualdad $a=== $b Identidad Noigualdad No$a <> $b igualdad No$a!== $b identidad $a != $b Resultado Unión de $a y $b. Cierto si $a y $b tienen las mismas parejas llave/valor. Cierto si $a y $b tienen las mismas parejas llave/valor en el mismo orden y de los mismos tipos. Cierto si $a no es igual a $b. Cierto si $a no es igual a $b. Cierto si $a no es idéntico a $b. El operador + adiciona elementos de las claves restantes de la matriz del lado derecho a aquella al lado izquierdo, al mismo tiempo que cualquier clave duplicada NO es sobrescrita. "manzana", "b" => "banano"); $b = array("a" => "pera", "b" => "fresa", "c" => "cereza"); $c = $a + $b; // Unión de $a y $b echo "Unión de \$a y \$b: \n"; var_dump($c); $c = $b + $a; // Unión de $b y $a echo "Unión de \$b y \$a: \n"; var_dump($c); ?> Cuando sea ejecutado, este script producirá la siguiente salida: Unión de $a y $b: array(3) { ["a"]=> string(7) "manzana" ["b"]=> 63 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO string(6) "banano" ["c"]=> string(6) "cereza" } Unión de $b array(3) { ["a"]=> string(4) ["b"]=> string(5) ["c"]=> string(6) } y $a: "pera" "fresa" "cereza" Los elementos de las matrices son considerados equivalentes en la comparación si éstos tienen la misma clave y valor. "banano", "0" => "manzana"); var_dump($a == $b); // bool(true) tiene las mismas clave-valor var_dump($a === $b); // bool(false) pero en orden distinto ?> 5.11. Operadores de Tipo instanceof es usado para determinar si una variable PHP es una instancia de objeto de cierta clase: El resultado del ejemplo sería: bool(true) bool(false) El operador instanceof fue introducido en PHP5. Anteriormente se usaba la función is_a() pero desde la introdución del operados instanceof, la función anterior se considera obsoleta. 5.12. Precedencia y asociatividad de operandos La precedencia de los operandos resuelve el orden en el que se evalúa una expresión múltiple que no ha sido delimitada con paréntesis. Por ejemplo, 1 + 5 * 3 en PHP daría como resultado 1 + (5 * 3) = 16 y no (1 + 5) * 3 = 18 ya que el producto tiene mayor precedencia que la suma. 64 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La tabla muestra la asociatividad de los operandos en PHP, y está ordenada en orden creciente de precedencia (los más prioritarios al final): Asociatividad izquierda izquierda izquierda izquierda Derecha izquierda izquierda izquierda izquierda izquierda izquierda no-asociativo no-asociativo izquierda izquierda izquierda derecha no-asociativo no-asociativo izquierda no-asociativo Operandos , or xor and = += -= *= /= .= %= &= |= ^= ~= <<= >>= ? : || && | ^ & == != === !== < <= > >= << >> + - . * / % ! ~ - (int) (float) (string) (array) (bool) @ ++ -[ clone new (object) La asociatividad de izquierda quiere decir que la expresión es evaluada desde la izquierda a la derecha, la asociatividad de derecha quiere decir lo contrario. $a = 5, $b = 5 ?> 65 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 6. Estructuras de Control ® ® ® ® ® ® ® ® ® ® ® ® ® ® ® ® ® if else elseif while do..while for foreach break continue switch declare return require() include() require_once() include_once() Sintaxis Alternativa de Estructuras de Control Todo script PHP se compone de una serie de sentencias. Una sentencia puede ser una asignación, una llamada a función, un bucle, una sentencia condicional e incluso una sentencia que no haga nada (una sentencia vacía). Las sentencias normalmente acaban con punto y coma. Además, las sentencias se pueden agrupar en grupos de sentencias encapsulando un grupo de sentencias con llaves. Un grupo de sentencias es también una sentencia. En este capítulo se describen los diferentes tipos de sentencias. 6.1. if La construcción if es una de las más importantes características de muchos lenguajes, incluido PHP. Permite la ejecución condicional de fragmentos de código. PHP caracteriza una estructura if que es similar a la de C: Como se describe en la sección sobre expresiones, expr se evalúa a su valor condicional (boolean). Si expr se evalúa como TRUE, PHP ejecutará la sentencia, y si se evalúa como FALSE - la ignorará. Se puede encontrar más información sobre los valores evaluados como FALSE en la sección sobre el tipo de datos booleano. El siguiente ejemplo mostraría a es mayor que b si $a fuera mayor que $b: $b) print "a es mayor que b";?> A menudo, se desea tener más de una sentencia ejecutada de forma condicional. Por supuesto, no hay necesidad de encerrar cada sentencia con una cláusula if. En vez de eso, se pueden agrupar varias sentencias en un grupo de sentencias. Por ejemplo, este 67 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO código mostraría a es mayor que b si $a fuera mayor que $b, y entonces asignaría el valor de $a a $b: $b) { print "a es mayor que b"; $b = $a; } ?> Las sentencias if se pueden anidar indefinidamente dentro de otras sentencias if, lo cual proporciona una flexibilidad completa para ejecuciones condicionales en las diferentes partes de tu programa. 6.2. else A menudo queremos ejecutar una sentencia si se cumple una cierta condicion, y una sentencia distinta si la condición no se cumple. Esto es para lo que sirve else. else extiende una sentencia if para ejecutar una sentencia en caso de que la expresión en la sentencia if se evalúe como FALSE. Por ejemplo, el siguiente código mostraría a es mayor que b si $a fuera mayor que $b, y a NO es mayor que b en cualquier otro caso: $b) { print "a es mayor que b"; } else { print "a NO es mayor que b"; } ?> La sentencia else se ejecuta solamente si la expresión if se evalúa como FALSE, y si hubiera alguna expresión elseif - sólo si se evaluaron también a FALSE (Ver elseif). 6.3. elseif elseif, como su nombre sugiere, es una combinación de if y else. Como else, extiende una sentencia if para ejecutar una sentencia diferente en caso de que la expresión if original se evalúa como FALSE. No obstante, a diferencia de else, ejecutará esa expresión alternativa solamente si la expresión condicional elseif se evalúa como TRUE. Por ejemplo, el siguiente código mostraría a es mayor que b, a es igual a b o a es menor que b: $b) print "a } elseif ($a print "a } else { print "a } ?> { es mayor que b"; == $b) { es igual que b"; es mayor que b"; Puede haber varios elseif dentro de la misma sentencia if. La primera expresión elseif (si hay alguna) que se evalúe como TRUE se ejecutaría. En PHP, también se puede escribir 'else if' (con dos palabras) y el comportamiento sería idéntico al de un 'elseif' (una sola palabra). El significado sintáctico es ligeramente distinto (si estas 68 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO familiarizado con C, es el mismo comportamiento) pero la línea básica es que ambos resultarían tener exactamente el mismo comportamiento. La sentencia elseif se ejecuta sólo si la expresión if precedente y cualquier expresión elseif precedente se evalúan como FALSE, y la expresión elseif actual se evalúa como TRUE 6.4. while Los bucles while son los tipos de bucle más simples en PHP. Se comportan como su contrapartida en C. La forma básica de una sentencia while es: while (expr) sentencia El significado de una sentencia while es simple. Le dice a PHP que ejecute la(s) sentencia(s) anidada(s) repetidamente, mientras la expresión while se evalúe como TRUE. El valor de la expresión es comprobado cada vez al principio del bucle, así que incluso si este valor cambia durante la ejecución de la(s) sentencia(s) anidada(s), la ejecución no parará hasta el fin de la iteración (cada vez que PHP ejecuta las sentencias en el bucle es una iteración). A veces, si la expresión while se evalúa como FALSE desde el principio de todo, la(s) sentencia(s) anidada(s) no se ejecutarán ni siquiera una vez. Como con la sentencia if, se pueden agrupar multiples sentencias dentro del mismo bucle while encerrando un grupo de sentencias con llaves. El siguiente ejemplo imprime números del 1 al 10: 6.5. do..while Los bucles do..while son muy similares a los bucles while, excepto que las condiciones se comprueban al final de cada iteración en vez de al principio. La principal diferencia frente a los bucles regulares while es que se garantiza la ejecución de la primera iteración de un bucle do..while (la condición se comprueba sólo al final de la iteración), mientras que puede no ser necesariamente ejecutada con un bucle while regular (la condición se comprueba al principio de cada iteración, si esta se evalúa como FALSE desde el principio la ejecución del bucle finalizará inmediatamente). Hay una sola sintaxis para los bucles do..while: 0);?> 69 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO El bucle de arriba se ejecutaría exactamente una sola vez, después de la primera iteración, cuando la condición se comprueba, se evalúa como FALSE ($i no es más grande que 0) y la ejecución del bucle finaliza. Los usuarios avanzados de C pueden estar familiarizados con un uso distinto del bucle do..while, para permitir parar la ejecución en medio de los bloques de código, encapsulandolos con do..while(0), y usando la sentencia break. El siguiente fragmento de código demuestra esto: 6.6. for Los bucles for son los bucles más complejos en PHP. Se comportan como su contrapartida en C. La sintaxis de un bucle for es: for (expr1; expr2; expr3) sentencia La primera expresión (expr1) se evalúa (ejecuta) incondicionalmente una vez al principio del bucle. Al comienzo de cada iteración, se evalúa expr2 . Si se evalúa como TRUE, el bucle continúa y las sentencias anidadas se ejecutan. Si se evalúa como FALSE, la ejecución del bucle finaliza. Al final de cada iteración, se evalúa (ejecuta) expr3. Cada una de las expresiones puede estar vacía. Que expr2 esté vacía significa que el bucle debería correr indefinidamente (PHP implicitamente lo considera como TRUE, al igual que C). Esto puede que no sea tan inútil como se podría pensar, puesto que a menudo se quiere salir de un bucle usando una sentencia break condicional en vez de usar la condición de for. Considere los siguientes ejemplos. Todos ellos muestran números del 1 al 10: 10) { break; } print $i; } /* ejemplo 3 */ $i = 1; for (;;) { if ($i > 10) { break; } print $i; $i++; } /* ejemplo 4 */ for ($i = 1; $i <= 10; print $i, $i++) ; ?> Por supuesto, el primer ejemplo parece ser el mas elegante (o quizás el cuarto), pero uno puede descubrir que ser capaz de usar expresiones vacías en bucles for resulta útil en muchas ocasiones. Otros lenguajes poseen una sentencia foreach para traducir un array o una tabla hash. PHP3 no posee tal construcción; PHP4 sí (ver foreach). En PHP3, se puede combinar while con las funciones list() y each() para conseguir el mismo efecto. 6.7. foreach PHP 4 (PHP3 no) incluye una construcción foreach, tal como perl y algunos otros lenguajes. Esto simplemente da un modo fácil de iterar sobre matrices. foreach funciona solamente con matrices y devolverá un error si se intenta utilizar con otro tipo de datos ó variables no inicializadas. Hay dos sintaxis; la segunda es una extensión menor, pero útil de la primera: foreach(expresion_array as $value) sentencia foreach(expresion_array as $key => $value) sentencia La primera forma recorre el array dado por expresion_array. En cada iteración, el valor del elemento actual se asigna a $value y el puntero interno del array se avanza en una unidad (así en el siguiente paso, se estará mirando el elemento siguiente). La segunda manera hace lo mismo, salvo que la clave del elemento actual será asignada a la variable $key en cada iteración. Nota: Cuando foreach comienza su primera ejecución, el puntero interno a la matriz se reinicia automáticamente al primer elemento de la matriz. Esto significa que no se necesita llamar a reset() antes de un bucle foreach. Nota: Hay que tener en cuenta que foreach trabaja con una copia de la matriz especificada y no la lista en si, por ello el puntero de la lista no es modificado como en la función each(), y los cambios en el elemento de la matriz retornado no afectan a la matriz original. De todas maneras el puntero interno a la matriz original avanza al procesar la matriz. 71 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Suponiendo que bucle foreach se ejecuta hasta el final, el puntero interno a la matriz estará al final de la matriz. Nota: foreach no soporta la caracteristica de suprimir mensajes de error con '@'. Puede haber observado que las siguientes son funcionalidades idénticas: \n"; } foreach ($arr as $value) { echo "Value: $value
\n"; } ?> Las siguientes también son funcionalidades idénticas: \n"; } foreach( $arr as $key => $value ) { echo "Key: $key; Valor: $value
\n"; } ?> Algunos ejemplos más para demostrar su uso: \n"; } /* foreach ejemplo 2: valor (con clave impresa para ilustrar) */ $a = array(1, 2, 3, 17); $i = 0; /* sólo para propósitos demostrativos */ foreach($a as $v) { print "\$a[$i] => $v.
\n"; $i++; } /* foreach ejemplo 3: clave y valor */ $a = array( "uno" => 1, "dos" => 2, "tres" => 3, "diecisiete" => 17 ); foreach($a as $k => $v) { print "\$a[$k] => $v.
\n"; } /* foreach unset($a); $a[0][0] = $a[0][1] = $a[1][0] = 72 ejemplo 4: matriz multi-dimensional */ "a"; "b"; "y"; PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO $a[1][1] = "z"; foreach($a as $k1 => $v1) { foreach ($v1 as $k2 => $v2) { print "$k1,$k2 => $v2
\n"; } } /* foreach ejemplo 5: matriz dinámica */ foreach(array(1, 2, 3, 4, 5) as $v) { print "$v
\n"; } ?> 6.8. break break sale de la estructuras de control iterante (bucle) actuales for, while, o switch. break accepta un parámetro opcional, el cual determina de cuantas estructuras de control hay que salir. \n"; } /* Usando el argumento opcional. */ $i = 0; while (++$i) { switch ($i) { case 5: echo "En el 5
\n"; break 1; /* Sale solo del switch. */ case 10: echo "En el 10; saliendo
\n"; break 2; /* Sale del switch y del while. */ default: break; } } ?> 6.9. continue continue se usa dentro de la estructura del bucle para saltar el resto de la iteración actual del bucle y continuar la ejecución al comienzo de la siguiente iteración. Nota: Tener en cuenta que en PHP la declaración switch es considerada una estructura de bucle por continue. continue accepta un parámetro opcional, el cual determina cuantos niveles (bluces) hay que saltar antes de continuar con la ejecución. \n"; } $i = 0; while ($i++ < 5) { echo "Externo
\n"; while (1) { echo " Medio
\n"; while (1) { echo " Interno
\n"; continue 3; } echo "Esto nunca se imprime.
\n"; } echo "Y esto tampoco.
\n"; } ?> 6.10. switch La sentencia switch es similar a una serie de sentencias if en la misma expresión. En muchas ocasiones, se quiere comparar la misma variable (o expresión) con nuchos valores diferentes, y ejecutar una parte de código distinta dependiendo de a qué valor es igual. Para ello sirve la sentencia switch. Nota: Tener en cuenta que al contrario que otros lenguajes de programación, continue se aplica a switch y funciona de manera similar a break. Si teneis un switch dentro de un bucle y deseais continuar con el paso siguiente en el bucle externo, usar continue 2. Los siguientes dos ejemplos son dos modos distintos de escribir la misma cosa, uno usa una serie de sentencias if, y el otro usa la sentencia switch: \n"; 1) { igual a 1
\n"; 2) { igual a 2
\n"; switch ($i) { case 0: print "i es igual a 0
\n"; break; case 1: print "i es igual a 1
\n"; break; case 2: print "i es igual a 2
\n"; break; } ?> Es importante entender cómo se ejecuta la sentencia switch para evitar errores. La sentencia switch ejecuta línea por línea (realmente, sentencia a sentencia). Al comienzo, no se ejecuta código. Sólo cuando se encuentra una sentencia case con un valor que coincide con el valor de la expresión switch PHP comienza a ejecutar las sentencias. PHP continúa ejecutando las sentencias hasta el final del bloque switch, o la primera vez que vea una sentencia break. Si no se escribe una sentencia break al final de una lista de sentencias case, PHP seguirá ejecutando las sentencias del siguiente case. Por ejemplo: 74 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Aquí, si $i es igual a 0, ¡PHP ejecutaría todas las sentecias print! Si $i es igual a 1, PHP ejecutaría las últimas dos sentencias print y sólo si $i es igual a 2, se obtendría la conducta 'esperada' y solamente se mostraría 'i es igual a 2'. Así, es importante no olvidar las sentencias break (incluso aunque pueda querer evitar escribirlas intencionadamente en ciertas circunstancias). En una sentencia switch, la condición se evalúa sólo una vez y el resultado se compara a cada sentencia case. En una sentencia elseif, la condición se evalúa otra vez. Si tu condición es más complicada que una comparación simple y/o está en un bucle estrecho, un switch puede ser más rápido. La lista de sentencias de un case puede también estar vacía, lo cual simplemente pasa el control a la lista de sentencias del siguiente case. Un caso especial es el default case. Este case coincide con todo lo que no coincidan los otros case. Por ejemplo: es igual a 0"; es igual a 1"; es igual a 2"; no es igual a 0, 1 o 2"; La expresión case 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 texto. No se pueden usar aquí ni arrays ni objetos a menos que se conviertan a un tipo simple. 75 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 6.11. declare La construcción declare es usada para definir directivas de ejecución para un bloque de código. La sintaxis de declare es similar a la de las otras estructuras de control: declare (directiva) sentencia Directiva permite asignar el comportamiento del bloque declare. Actualmente una sola directiva es reconocida: la directiva ticks La sentencia es lo que se ejecuta -- Como se ejecuta y que efectos secundarios tiene depende de la directiva definida en la directiva. El constructor declare se puede usar tambien globalmente, afectando a todo el código que le sigue. Un "tick" es un evento que ocurre por cada N sentencias de bajo nivel ejecutadas dentro del bloque declare. El valor de N es especificado por ticks=N como directiva dentro de declare. El evento que ocurre en cada "tick" es especificado usando la función register_tick_function(). ;"; 76 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO } } // Muestra el contenido del perfil print_r (profile (TRUE)); ?> Este ejemplo perfila el código PHP dentro del bloque 'declare', grabando la hora, una sentencia si y otra no, cuando fue ejecutada. Esta información puede ser usada para encontrar areas en donde el codigo es lento. Este proceso se puede implementar de diferentes maneras: usando "ticks" es más conveniente y facil de implementar. "Ticks" es una manera muy buena de eliminar errores, implementando simples trabajos en paralelo, I/O en modo desatendido y otras tareas. 6.12. return Si se llama desde una función, return() termina inmediatamente la ejecución de la función y retorna su argumento como valor de la función. return() tambien terminará la ejecución de una sentencia eval() ó un script PHP. Si el script actual ha sido incluido ó requerido con include() ó require(), el control es transferido al script que llamo al script incluido. Además, si el script actual fue incluido, el valor dado a return() será retornado como el valor de la llamada include(). Si return() es invocado desde el script principal, la ejecución terminara inmediatamente. Nota: Tener en cuenta que ya que return() es un constructor del lenguaje y no una función, los paréntesis alrededor de sus argumentos, no son necesarios, es más no se suelen utilizar tan a menudo, aunque funciona igual de una manera u otra. 6.13. require() La sentencia require() incluye y evalua el archivo especificado. require() incluye y evalua el archivo especificado. Información detallada de como esta inclusión funciona se puede encontrar en la documentación de la función include(). require() y include() son idénticas en todos los aspectos excepto en el modo de actuar ante un error. include() produce un Warning mientras que require() produce un Error Fatal. En otras palabras, no dude en utilizar require() si quiere que un fichero no encontrado cuelgue el procesamiento de la página. include() no se comporta de esta manera, el script seguirá funcionando de todas maneras. Asegurarse que include_path este configurado bien. 77 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Nota: Con anterioridad a PHP 4.0.2, se aplica lo siguiente: require() siempre intentará leer el fichero a incluir, incluso si la linea donde se encuentra require() nunca es ejecutada. Sin embargo, si la linea donde se encuentra require() no es ejecutada, tampoco lo hará el código incluido. 6.14. include() La sentencia include() incluye y evalúa el archivo especificado. Esta documentación también se aplica a la función require(). require() y include() son idénticas en todos los aspectos excepto en el modo de actuar ante un error. include() produce un Warning mientras que require() produce un Error Fatal. En otras palabras, no dude en utilizar require() si quiere que un fichero no encontrado cuelgue el procesamiento de la página. include() no se comporta de esta manera, el script seguirá funcionando de todas maneras. Asegurarse que include_path este configurado bien. Cuando un fichero es incluido, el código que contiene hereda el ámbito de variables de la línea en donde el include ocurre. Cualquier variable disponible en esa línea en el fichero desde donde se hace la inclusión estará disponible en el fichero incluido a partir de ese momento. apar614_02.php apar614_01.php Si la inclusión ocurre dentro de una función en el fichero donde se incluye, todo el código contenido en el fichero incluido se comportará como si hubiese sido definido dentro de esta función. Cuando un fichero es incluido, el intérprete sale del modo PHP y entra en modo HTML al principio del archivo referenciado, y vuelve de nuevo al modo PHP al final. Por esta razón, cualquier código dentro del archivo referenciado que debiera ser ejecutado como código PHP debe ser encerrado dentro de etiquetas válidas de comienzo y fin de PHP. Si "URL fopen wrappers" esta activada en PHP (como está en la configuración inicial), se puede especificar el fichero que se va a incluir usando una URL (via HTTP u otro mecanismo soportado) en vez de un fichero local. Si el servidor destino interpreta el fichero destino como código PHP, se puede mandar variables al fichero incluido usando una cadena URL de petición, tal como se hace con HTTP GET. Esto no es lo mismo que incluir un fichero y que este fichero herede las variables del fichero padre; el script es ejecutado en el servidor remoto y el resultado es incluido en en script local. Versiones de PHP para Windows anteriores a la versión 4.3.0, no soportan el acceso remoto a ficheros en esta función, no funcionará incluso activando allow_url_fopen. Ya que include() y require() son contructores especiales del lenguaje, se deben de incluir dentro del bloque de una sentencia, si están dentro de un bloque condicional. 79 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Es posible ejecutar una sentencia return dentro de un archivo incluido para terminar el procesado de ese archivo y volver al archivo de comandos que lo llamó. Tambien es posible retornar valores de ficheros incluidos. Se puede coger el valor de la llamada "include" como se haría con una función normal. Nota: En PHP3, return no puede aparecer dentro de un bloque a menos que sea un bloque de función, en el cual return se aplica a esa función y no al archivo completo. return.php noreturn.php apar614_05.php $bar es igual a 1 porque la inclusión salio bien. Se debe prestar atención a la diferencia entre los dos ejemplos anteriores. El primero usa return() dentro del fichero incluido y el segundo no. Otras maneras de incluir ficheros en variables es con fopen(), file() ó usando include() con Funciones de control de salida. 6.15. require_once() La función require_once() incluye y evalua el fichero especificado durante la ejecución del script. Se comporta de manera similar a require(), con la única diferencia que si el código ha sido ya incluido, no se volverá a incluir. Consultar la documentación de la función require() para obtener más información. require_once() debería de usarse en casos en los que un mismo fichero puede ser incluido y evaluado más de una vez durante la ejecución de un script, y se quiere estar seguro que se incluye una sola vez para evitar problemas con redefiniciones de funciones, valores de funciones, etc. Nota: El comportamiento de de require_once() y include_once() puede que no sea el esperado en sistemas operativos en los que mayúsculas y minúsculas se traten igual (como en Windows) 80 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 6.16. include_once() La función include_once() incluye y evalua el fichero especificado durante la ejecución del script. Se comporta de manera similar a include(), con la única diferencia que si el código ha sido ya incluido, no se volverá a incluir. include_once() debería de usarse en casos en los que, un mismo fichero puede ser incluido y evaluado más de una vez durante la ejecución de un script, y se quiere estar seguro que se incluye una sola vez para evitar problemas con redefiniciones de funciones, valores de funciones, etc. Nota: El comportamiento de de include_once() y require_once() puede que no sea el esperado en sistemas operativos en los que mayúsculas y minúsculas se traten igual (como en Windows) 6.17. Sintaxis Alternativa de Estructuras de Control PHP ofrece una sintaxis altenativa para alguna de sus estructuras de control; a saber, if, while, for, y switch. En cada caso, la forma básica de la sintaxis alternativa es cambiar abrir-llave por dos puntos (:) y cerrar-llave por endif;, endwhile;, endfor;, or endswitch;, respectivamente. A es igual a 5 En el ejemplo de arriba, el bloque HTML "A es igual 5" se anida dentro de una sentencia if escrita en la sintaxis alternativa. El bloque HTML se mostraría solamente si $a fuera igual a 5. La sintaxis alternativa se aplica a else y también a elseif. La siguiente es una estructura if con elseif y else en el formato alternativo: Como con la sentencia if, se pueden agrupar multiples sentencias dentro del mismo bucle while encerrando un grupo de sentencias con llaves, o usando la sintaxis alternativa: while (expr): sentencia ... endwhile; 81 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Los siguientes ejemplos son idénticos, y ambos imprimen números del 1 al 10: PHP también soporta la "sintaxis de dos puntos" alternativa para bucles for. for (expr1; expr2; expr3): sentencia; ...; endfor; La sintaxis alternativa para las estructuras de control está también soportada con switch. 82 es igual 0"; es igual a 1"; es igual a 2"; no es igual a 0, 1 o 2"; PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 7. Funciones ® ® ® ® ® Funciones definidas por el usuario Parámetros de las funciones Devolviendo valores Funciones variables Funciones de tratamiento de cadenas de caracteres 7.1. Funciones definidas por el usuario Las funciones de usuario son bloques de código que pueden ser utilizados en cualquier momento dentro del código PHP. Se define una función con la sentencia function seguida del nombre de la función y de las líneas de instrucciones. Estas últimas deben ir entre las llaves {...}. Si la función tiene que devolver un valor a la línea de código donde se invocó, como última instrucción hay que poner la orden return seguida del valor que se devuelve. Si no se devuelve un valor, sino que sólo se ejecutan instrucciones dentro del código de la propia función, puede prescindirse de la sentencia return. Las funciones, en la mayoría de los casos, tienen parámetros o argumentos entre paréntesis, a través de los cuales se pasan los datos con los que hay que realizar operaciones. Una función se puede definir con la siguiente sintaxis: Cualquier instrucción válida de PHP puede aparecer en el cuerpo de la función, incluso otras funciones y definiciones de clases. En PHP3, las funciones deben definirse antes de que se referencien. A partir de PHP4 no existe tal requerimiento. Excepto cuando una función es definida condicionalmente como en los ejemplos siguientes. Cuando una función es definida condicionalmente como se puede ver en estos dos ejemplos, su definición debe ser procesada antes que sea llamada. PHP no soporta la redefinición de funciones previamente declaradas. Nota: Los nombres de funciones se pueden llamar con mayusculas o minusculas, aunque es una buena costumbre el llamar a las funciones tal y como aparecen en su definición. PHP3 no soporta un número variable de parámetros, aunque sí soporta parámetros por defecto. A partir de PHP4 se soporta ambos. 7.2. Parámetros de las funciones La información puede suministrarse a las funciones mediante la lista de parámetros, una lista de variables y/o constantes separadas por comas. PHP soporta pasar parámetros por valor (el comportamiento por defecto), por referencia, y parámetros por defecto. Las listas de longitud variable de parámetros sólo están soportadas en PHP4 y posteriores. Un efecto similar puede conseguirse en PHP3 pasando un array de parámetros a la función: 84 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 7.3. Pasar parámetros por referencia Por defecto, los parámetros de una función se pasan por valor (de manera que si cambias el valor del argumento dentro de la función, no se ve modificado fuera de ella). Si deseas permitir a una función modificar sus parámetros, debes pasarlos por referencia. Si quieres que un parámetro de una función siempre se pase por referencia, puedes anteponer un ampersand (&) al nombre del parámetro en la definición de la función: 7.4. Parámetros por defecto Una función puede definir valores por defecto para los parámetros escalares estilo C++: La salida del fragmento anterior es: Hacer una taza de cappucino. Hacer una taza de espresso. El valor por defecto tiene que ser una expresión constante, y no una variable, un miembro de una clase ó una llamada a una función. Destacar que cuando se usan parámetros por defecto, estos tienen que estar a la derecha de cualquier parámetro sin valor por defecto; de otra manera las cosas no funcionarán de la forma esperada. Considera el siguiente fragmento de código donde se usa incorrectamente parámetros por defecto en funciones: 85 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La salida del ejemplo anterior es: Warning: Missing argument 2 in call to makeyogurt()called in C:\WAMP\www\Capitulo_07\apar74_02.php on line 6 and defined in C:\WAMP\www\Capitulo_07\apar74_02.php on line 2 Y ahora, compárese con: // funciona como se esperaba La salida de este ejemplo es: Haciendo un bol de acidophilus mora. 7.5. Lista de longitud variable de parámetros A partir de PHP4 se soportan las listas de longitud variable de parámetros en las funciones definidas por el usuario. No se necesita ninguna sintaxis especial, y las listas de parámetros pueden ser escritas en la llamada a la función y se comportarán de la manera esperada. Es realmente fácil, usando las funciones func_num_args(), func_get_arg(), y func_get_args(): • • proporcionadas por PHP Func_num_args(): Devuelve el número de parámetros pasados a una función de parámetros variable. (El índice de un parámetro dentro de una función va desde 0 hasta n-1, donde n representa el número de parámetros de la función) Func_get_arg(): Devuelve el valor de un parámetro en particular. Por ejemplo, para retornar el valor del primer parámetro de una función de parámetros variable, podemos escribir: $arg1 = func_get_arg(0); • Func_get_args(): Retorna todos los parámetros pasados a la función en forma de array. Un ejemplo del uso de funciones de parámetros variable es: 7.6. Devolviendo valores Los valores se retornan usando la instrucción opcional return. Puede devolverse cualquier tipo de valor, incluyendo listas y objetos. No puedes devolver múltiples valores desde una función, pero un efecto similar se puede conseguir devolviendo un array. Para retornar una referencia desde una función, se tiene que usar el operador de referencias & tanto en la declaración de la función como en la asignación del valor de retorno a una variable; 7.7. Funciones variables PHP soporta el concepto de funciones variable, esto significa que si una variable tiene unos paréntesis añadidos al final, PHP buscará una función con el mismo nombre que la evaluación de la variable, e intentará ejecutarla. Entre otras cosas, esto te permite implementar retrollamadas (callbacks), tablas de funciones y demás. Las funciones variables no funcionarán con construcciones del lenguaje, tal como echo(), print(), unset(), isset(), empty(), include(), require() y derivados. Se necesitará usar una función propia para utilizar cualquiera de estos constructores como funciones variables. 87 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO \n"; } function bar($arg = '') { echo "En bar(); el argumento es '$arg'.
\n"; } function echoit($string) { echo $string; } $func = 'foo'; $func(); // Llama a foo() $func = 'bar'; $func('test'); // Llama a bar() $func = 'echoit'; $func('test'); // Llama a echoit() ?> También se puede llamar a un método de un objeto usando la característica variable de las funciones. $name(); // Esto llama al método Bar() } function Bar() { echo "Esto es Bar"; } } $foo = new Foo(); $funcname = "Var"; $foo->$funcname(); // Esto llama a $foo->Var() ?> 7.8. Funciones de tratamiento de cadenas de caracteres En este apartado vamos a abordar con mayor detalle las diferentes operaciones que se pueden llevar a cabo con este tipo de datos estudiando las principales funciones que permiten hacerlo. Algunas de las funciones más usadas para mostrar información son: 7.8.1. echo Ya hemos visto varios ejemplos de este comando. Tiene esta sintaxis: echo argumento 88 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO donde la información que se muestra (argumento) puede ser una cadena de caracteres entre comillas o una variable. También puede usarse la sintaxis echo (argumento1, argumento2,...) Si el argumento es una cadena entre comillas dobles, debemos tener en cuenta que las variables incluidas en ese texto se expanden, es decir, muestran su contenido, no su nombre. Sin embargo, las funciones no se expanden. ¿Cómo podemos conseguir que las variables no se expandan y las funciones sí lo hagan? Veamos el ejemplo siguiente donde mostramos en letras mayúsculas el contenido de una variable: $x = "el amor es libre"; echo "La variable $x contiene el texto strtoupper($x) en letras mayúsculas."; Ejecutando estas dos instrucciones aparece en la pantalla: La variable el amor es libre contiene el texto strtoupper(el amor es libre) en letras mayúsculas. Observamos que, aunque esté dentro de una cadena, la variable $x se ha expandido, es decir, ha mostrado su texto; en cambio, la función strtoupper (string to upper, convertir el texto de la cadena en letras mayúsculas) no se ha expandido. Pero nosotros queremos que en la página web aparezca: La variable $x contiene el texto EL AMOR ES LIBRE en letras mayúsculas. Para conseguirlo, hay que utilizar esta otra sintaxis: $x = “el amor es libre”; echo “La variable \$x contiene el texto”.strtoupper($x). “en letras mayúsculas.”; Si nos fijamos en esta última sintaxis, podemos observar que hemos utilizado la barra hacia la izquierda (\) delante de la variable, para que no expanda su contenido. Además, hemos sacado la función de las comillas y la hemos concatenado con el texto anterior y posterior usando el operador de concatenación (.). 7.8.2. print Esta orden es prácticamente igual que echo, hasta el punto de que se pueden intercambiar sin problemas. Veamos un ejemplo en que se usa la orden print en lugar de echo.Curso de PHP Uso de la orden print. Funciona como echo. "; /* Mostramos el texto anterior con un tamaño de letra grande y centrado.*/ $pares=0; 89 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO /* Abrimos un bucle para repetir la operación 20 veces. En la Unidad 2 se estudia esta estructura de control.*/ for (;$pares<40;) { print " -- $pares "; // Observa que la variable se expande. if ($pares==40) // Si la variable $pares vale 40... break; // Salimos del bucle. $pares+=2; // Sumamos 2 al valor actual de la variable. } print "
Relación de los 20 primeros números pares.
"; /* Mostramos el texto anterior con un tamaño de letra pequeño. Como HTML sólo respeta un espacio en blanco, con el comando hacemos que la frase deje 5 espacios a la izquierda. */ /* Aquí acaba el código PHP. No podemos poner este comentario a continuación del signo ?>, pues estaría fuera del código PHP.*/ ?> 7.8.3. printf Es una función que permite mostrar información formateada según los valores que aparezcan en una cadena de formato integrada por caracteres fijos y por una directiva %. Su sintaxis es: printf ("cadena de formato", argumento1, argumento2,...) En los argumentos se incluye la información que se quiere mostrar, como con echo o con print. En la cadena de formato, entre comillas, puede ponerse un texto, que aparece tal cual lo escribamos, con expansión de las variables si no usamos el signo \, y el valor de una variable según se establezca en la directiva %. Veamos en un ejemplo sencillo cómo se comporta esta función: Nueva línea "; ?> %d \n", $i); Si ejecutamos este código, en la pantalla aparece la página web siguiente: Valor de la variable $i= 15 Nueva línea Si editamos el código HTML que ha recibido el usuario, vemos cómo es: 90 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Valor de la variable $i=Nueva línea 15 En este sencillo ejemplo podemos apreciar varias cosas que debemos conocer. Son las siguientes: • • El segundo argumento de la función printf(), que es $i, aparece con la información que tiene esta variable. El primer argumento determina el formato de salida de esa información y está integrado por un texto literal (Valor de la variable \$i=), que se muestra tal como lo hemos escrito, por una directiva (%d), que establece que el valor de $i ha de aparecer como número decimal (en base 10) entero. Y así lo hace. En este ejemplo hay que observar también varias cosas que debemos tener en cuenta: 1. Conviene recordar que en el texto literal hemos tenido que utilizar el signo \ delante de $i para que la variable no se expandiera. No confundirlo con el comando \n que sirve para que se produzca un salto de línea. 2. La directiva %d lleva detrás el comando del código PHP \n. Puede llevar también otro literal. El comando \n sirve para que, una vez mostrado el resultado de la variable $i, se produzca un salto de línea dentro del código HTML, como ya hemos dicho. 3. En el código fuente PHP hemos dejado hasta cinco espacios en blanco después del primer literal y antes de la directiva, pero en la página web sólo aparece uno. Hay que tener en cuenta que HTML sólo muestra un espacio, no todos los que haya repetidos en el código. Dentro de la cadena de formato nos interesa ver cómo se configura una directiva y qué significa cada uno de los caracteres que la integran. Toda directiva debe iniciarse por un signo %. Si se quiere anular el efecto de % de forma que la directiva se vea como un literal, hay que poner delante otro signo %. Por ejemplo, la orden printf("Valor de la variable \$i= %%d \n", $i); muestra el texto Valor de la variable $i= %d sin el valor de $i ya que no hemos precisado su formato. Así pues, si queremos que en la página web aparezca la frase La variable $i con la directiva %d aparece como 15 debemos escribir la función de esta forma: printf("La variable \$i con la directiva %%d aparece como %d \n", $i); La directiva % puede estar integrada hasta por cinco elementos: 91 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 1. Un carácter de relleno, para que ocupe las posiciones vacías cuando lo que ha de mostrarse no completa todas. Si no se pone, se supone que las posiciones vacías han de ser espacios en blanco. En el caso de números, puede indicarse que se rellenen con ceros o con otro carácter (escribir entre comillas simples) como primer integrante de la directiva. 2. El carácter opcional ‘-‘, para alinear un número por la izquierda. 3. El número mínimo de posiciones que ha de ocupar la salida. Si su contenido no ocupa tantas posiciones, los espacios vacíos se completan con el carácter que se haya indicado en el componente primero. Por ejemplo, la instrucción printf("La variable \$i con la directiva %%05d aparece como %05d \n", $i); muestra en la página el texto La variable $i con la directiva %05d aparece como 00015 donde el 0 primero indica el carácter de relleno, el 5 es el número de posiciones que debe ocupar la salida y la d, como veremos, indica que ha de mostrarse en formato decimal (base 10). Cuando la salida es un número, este guarismo sólo se refiere a la parte entera, no a la decimal, cuya longitud de salida se fija con el elemento siguiente, separando ambos elementos por un punto. 4. El número de decimales que deben mostrarse cuando los haya, es decir, cuando trabajemos con números de coma flotante. Este número debe ir separado del número entero anterior por un punto ( .). Por ejemplo, si la varible $i vale 11.3456, la instrucción printf("La variable \$i con la directiva %%09.5f aparece como %09.5f \n", $i); muestra en la página el texto La variable $i con la directiva %09.5f aparece como 011.34560 5. Especificación del tipo de salida. Este último es el más importante, hasta el punto de que la mayoría de las veces es el único que sigue al signo de directiva %. Puede ser una sola de las letras que aparecen en la tabla siguiente: LETRA b c d f 92 FORMATO DE SALIDA. LA VARIABLE $I CONTIENE 15. La salida numérica aparece en formato binario (base 2). Orden: printf("\$i con %%b aparece como %b", $i); Muestra: $i con %b aparece como 1111 La salida completa aparece como un carácter que se indica detrás de la c. Orden: printf("\$i con %%cZ aparece como %cZ", $i); Muestra: $i con %CZ aparece como Z La salida numérica aparece en formato decimal (base 10). Orden: printf("\$i con %%d aparece como %d", $i); Muestra: $i con %b aparece como 15 La salida numérica aparece en formato de coma flotante. PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Orden: printf("\$i con %%f aparece como %f", $i); Muestra: $i con %b aparece como 15.000000 La salida numérica aparece en formato octal (base 8). Orden: printf("\$i con %%o aparece como %o", $i); Muestra: $i con %b aparece como 17 La salida, aunque sea numérica, aparece como una cadena. Orden: printf("\$i con %%s aparece como %s cadena con números", $i); Muestra: $i con %s aparece como 15 cadena con números La salida numérica aparece en formato hexadecimal (base 16) con las letras en minúscula. Orden: printf("\$i con %%04x aparece como %04x", $i); Muestra: $i con %04x aparece como 000f La salida numérica aparece en formato hexadecimal (base 16) con las letras en mayúscula. Orden: printf("\$i con %%04X aparece como %04X", $i); Muestra: $i con %04x aparece como 000F o s x X En el ejemplo siguiente se muestra cómo usar la orden printf().
Curso de PHP 7.8.4. sprintf Esta función nos permite dar formato a una cadena de texto exactamente igual que con printf, y guardar, además el resultado en una variable, para utilizarlo posteriormente. 93 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Su sintaxis es la siguiente: $cadena=sprintf(“cadena de formato”, argumento 1, argumento 2,...) Siguiendo el último ejemplo de la tabla anterior, podíamos escribir: Nueva línea"; ?> El resultado es la página web siguiente: $i con %04X aparece como 000F Nueva línea Aunque la cadena de formato parezca inicialmente algo complicada, con la práctica resultará de gran utilidad. Una vez vistas las funciones necesarias para mostrar información en forma de cadena de caracteres veamos algunas de las funciones de cadenas más frecuentes y necesarias. Por otra parte, en el Capítulo CLXI. Funciones de Cadenas del Manual de PHP aparecen todas las funciones de cadena de caracteres. En este apartado nos vamos a limitar a explicar brevemente las más frecuentes y necesarias. 7.8.5. Adaptar las cadenas al contexto Al mezclarse el código HTML y PHP es preciso ocasionalmente que el intérprete sepa distinguir los signos propios de cada lenguaje que puedan aparecer en el interior de una cadena. Las funciones que permiten adaptar el contenido de una cadena al contexto de cada código son las siguientes: La función addSlashes() devuelve una cadena con barras invertidas delante de los caracteres que necesitan marcarse en consultas de bases de datos y en otras operaciones en las que intervienen esos caracteres. Nos estamos refiriendo a la comilla simple ('), a la comilla doble ("), a la barra invertida (\) y a NUL (byte nulo). La forma de proteger estos caracteres, para que no sean interpretados por el Shell o por PHP como caracteres significativos, es poner una barra invertida (Slash) delante de los mismos. Por ejemplo, si a la variable $consulta le asignamos el valor "WHERE nom = ‘Ana’", las comillas simples interiores serán interpretadas como caracteres significativos, pero necesitamos que sean interpretados como comillas. Así pues, con la función addSlashes() lo conseguimos de esta forma: $consulta="WHERE nom = 'Ana'"; 94 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO // Así la variable $consulta contendrá WHERE nom = ‘Ana’ $consulta=addSlashes($consulta); // Así la variable $consulta contendrá WHERE nom = \‘Ana\’ La función stripSlashes() devuelve una cadena sin barras invertidas delante de la comilla simple ('), la comilla doble ("), la barra invertida (\) y el valor NUL. Esta función, pues, realiza la función inversa de la función anterior. Siguiendo con el ejemplo anterior podemos usarla de esta forma: $consulta="WHERE nom = 'Ana'"; // Así la variable $consulta contendrá WHERE nom = 'Ana' $consulta=addSlashes($consulta); // Así la variable $consulta contendrá WHERE nom = \'Ana\' $consulta=stripSlashes($consulta); // Así la variable $consulta contendrá WHERE nom = 'Ana' La función urlencode() devuelve una cadena en la que todos los caracteres no alfanuméricos, excepto -, _, y., son reemplazados por un signo de porcentaje (%) seguido por dos dígitos hexadecimales. Los espacios son sustituidos por signos positivos (+). Es conveniente usar esta función para escribir una cadena de texto que va a ser usada dentro del código HTML como parte de una consulta de una URL. También es una forma adecuada de pasar variables a la página siguiente. Lo más frecuente es que la usemos para que HTML respete los espacios en blanco que haya dentro del texto. Veamos en un ejemplo cómo se producen las conversiones: $b='"; /* Aquí se muestra la misma cadena que hemos escrito entre comillas simples. */ echo urlencode($b); /* Aquí se muestra la cadena %3CA+HREF+%3D+_+++%22Po%F1w%3F.jura+1+%29+%23+%26+%2F%2F */ Conviene observar que los espacios se representan con el signo +, las letras, excepto la ñ, y los números se dejan igual, y los demás signos, como <, =, ), etcétera, son sustituidos por el signo % seguido de dos dígitos en base hexadecimal. La función urldecode() realiza la operación inversa de la anterior. Por ejemplo, si escribimos las instrucciones $c='SELECT+ALL+FROM+tabla+WHERE+nombre%3D%22JUANA%22'; $d=urldecode($c); echo $d." TABLA DE LOS 20 PRIMEROS NÚMEROS EN DIFERENTES BASES
Decimal Binario Octal Hexadecimal "; // Salto de línea para dejar un espacio entre // el título y la tabla. /* Abrimos un bucle para repetir la operación 20 veces. En la Unidad 2 se estudia esta estructura de control.*/ for ($a=0;$a<21;$a++) { echo ""; // Nueva fila de tabla. printf(" "; } /* Aquí acaba el código PHP. No podemos poner este comentario a continuación del signo ?>, pues estaría fuera del código PHP.*/ ?>%02d %06b %02o %02X " ,$a,$a,$a,$a); /* Observa que en la cadena de formato, entre paréntesis, hemos incluido los códigos HTML (... ) y la directiva (%02d, %06b, %02o y %02X) de cada una de las formas de presentar el valor de la varible $a. */ print ""; la página muestra la cadena original SELECT ALL FROM tabla WHERE nombre="JUANA" Las funciones rawurlencode() y rawurldecode() (código puro para URL) se comportan prácticamente igual que las dos anteriores, con la diferencia de que éstas no convierten en código HTML las letras, los números y el carácter de subrayado (_), pero sí codifican en el mismo los signos -, y. Usando las primeras se consiguen efectos más amplios, por lo que recomendamos su uso preferente. La función nl2br() se utiliza también para dar formato a las salidas en HTML. Esta función transforma los códigos de salto de línea de los ficheros de texto en códigos 95 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO de salto de línea propios de HTML conservando los anteriores. Se utiliza principalmente para organizar el texto introducido en TEXTAREA de un formulario. Cambia, pues, la orden \n (salto de línea en un fichero de texto) en
(salto de línea en código XHTML) produciendo un salto de línea real, tanto en el código HTML devuelto al interpretarse el código PHP como en la página web que se muestra. Por ejemplo, si escribimos las siguientes instrucciones $frase="Primero \n Segundo \n Tercero"; echo "
\n"; echo "Sin aplicar saldo de línea HTML: \"$frase\""; echo "
\n"; $frase=nl2br($frase); echo "Aplicando salto de línea HTML: \"$frase\""; se devuelve al siguiente código HTML
Sin aplicar salto de línea HTML: "Primero Segundo Tercero"
Aplicando salto de línea HTML: "Primero
Segundo
Tercero" y se genera la siguiente página: Sin aplicar saldo de línea HTML: "Primero Segundo Tercero" Aplicando salto de línea HTML: "Primero Segundo Tercero" Se puede observar que los saltos de línea del fichero de texto \n mediante la función nl2br() han sido sustituidos en el código XHTML por saltos de línea
. 7.8.6. Limpiar cadenas de caracteres La función chop() elimina los espacios en blanco que haya al final de una cadena de caracteres, incluyendo los códigos de fin de línea si los hubiere. Por ejemplo, las instrucciones $f="La ciencia es un conjunto de verdades \n "; $g=chop($f); echo "La variable \$f contiene ".strlen($f)." caracteres de los que ".(strlen($f)-strlen($g)). "son espacios en blanco o saltos de línea."; echo "En cambio, si usamos la función chop() la variable \$f contiene sólo ".strlen($g). "caracteres.
"; generan la página siguiente: La variable $f contiene 44 caracteres de los que 7 son espacios en blanco o saltos de línea. En cambio, si usamos la función chop() la variable $f contiene sólo 37 caracteres. 96 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Algo más adelante se verá que la función strlen() devuelve el número de caracteres que tiene una cadena. La función ltrim() elimina los espacios en blanco que haya al principio de una cadena de caracteres. Por ejemplo, las instrucciones $h=" La ciencia es un conjunto de verdades"; $i=ltrim($h); echo "La variable \$h contiene ".strlen($h)." caracteres de los que ".(strlen($h)-strlen($i))."son espacios en blanco.
"; echo "En cambio, si usamos la función ltrim() la variable \$i contiene sólo ".strlen($i)." caracteres.
Ha perdido los espacios en blanco iniciales.
"; generan la página siguiente: La variable $h contiene 42 caracteres de los que 5 son espacios en blanco. En cambio, si usamos la función ltrim() la variable $h contiene sólo 37 caracteres. Ha perdido los espacios en blanco iniciales. La función trim() es una combinación de las dos anteriores: elimina los espacios en blanco que haya al principio y al final de una cadena. Por ejemplo, si $limpia trim($limpia) devuelve "casa". contiene " casa ", la instrucción echo La función strip_tags() elimina las etiquetas HTML de una cadena. Por ejemplo, las instrucciones siguientes $quita_html="
Texto grande
Negrita"; echo $quita_html."
"; echo strip_tags($quita_html); generan esta página Texto grande Negrita Texto grande Negrita Puede observarse que en el primer echo se ejecutan los códigos HTML. En cambio, en el segundo, al eliminarse estos controles con strip_tags(), se muestra el texto sin ellos. 7.8.7. Letras mayúsculas y letras minúsculas Algunas funciones permiten convertir todos o sólo algunos caracteres de una cadena en mayúsculas o minúsculas según nos convenga. Son muy fáciles de usar. Resumimos las más importantes. 1. Función strtoupper(): devuelve la misma cadena convirtiendo todos sus caracteres en mayúsculas. 97 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Ejemplo: si $a contiene "Pepe", echo strtoupper($a); devuelve "PEPE". 2. Función strtolower(): devuelve la misma cadena convirtiendo todos sus caracteres en minúsculas. Ejemplo: si $M contiene "PEPe", echo strtolower($M); devuelve "pepe". 3. Función ucfirst(): devuelve la misma cadena convirtiendo su primer carácter en mayúscula si es una letra. Ejemplo: si $M1 contiene "diosa", echo ucfirst($M1); devuelve "Diosa". Para que esta función tenga en cuenta el alfabeto completo español en mayúsculas, sobre todo si las letras tienen tilde, como "Águila", hay que establecer su configuración previamente con la función setlocale (LC_ALL,"spanish");. Estos valores son los formatos de hora, moneda, alfabeto, separador de decimales, etcétera. 4. Función ucwords(): devuelve la misma cadena convirtiendo el primer carácter de todas las palabras en mayúscula. Ejemplo: si $M_pal contiene "diosa de la antigüedad egipcia", la instrucción echo ucwords($M_pal); devuelve "Diosa De La Antigüedad Egipcia". 7.8.8. Conocer la longitud de una cadena Función strlen(): devuelve la longitud de una cadena expresada en valor numérico entero. Cuenta todas las posiciones, aunque sean espacios en blanco. Ya hemos visto cómo se usa en las funciones chop(), ltrim() y trim(). Ejemplo: si instrucción 7.8.9. $largo contiene "diosa de la antigüedad egipcia", la echo strlen($largo); devuelve el valor numérico 30. Repetir una cadena Función str_repeat(): devuelve la misma cadena que toma como primer argumento repetida tantas veces como se indique en el segundo argumento. Ejemplo: si $repe contiene "diosa
", echo str_repeat($repe,3); devuelve la cadena "diosa" repetida tres veces en distintas líneas. 7.8.10. Modificar algunos caracteres de una cadena Función strtr(): devuelve la misma cadena sustituyendo los caracteres de la misma que se indiquen en el segundo argumento por los que se indiquen en el tercer argumento haciéndolos equivaler uno a uno. Ejemplo: si $cambia contiene "Los días perdidos en verano" y necesitamos sustituir las as por us y las os por as, podemos escribir la sentencia siguiente: echo strtr($cambia,"ao","ua"); La función devolverá la cadena "Las díus perdidas en veruna". 98 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 7.8.11. Buscar dentro de las cadenas Hay funciones que permiten buscar dentro de una cadena. No se usan con frecuencia, por lo cual quien lo necesite puede obtener información en el manual oficial de PHP sobre las mismas. Nos limitamos a enumerar las principales y a indicar para qué sirven: 1. strcspn(): devuelve el número de caracteres del primer segmento de la primera cadena (primer argumento) que no contiene caracteres de la segunda cadena (segundo argumento). 2. strspn(): devuelve el número de caracteres del primer segmento de la cadena pasada como primer argumento que aparecen en la cadena pasada como segundo argumento. 3. strpos(): devuelve el número de la posición del primer carácter de la primera cadena (primer argumento) que coincida con la segunda cadena completa (segundo argumento). Se cuenta desde 0 en adelante. Admite un tercer argumento, que es el número a partir del cual debe buscarse el texto de la segunda cadena en la primera. 4. strrpos(): devuelve el número de la posición del último carácter de la primera cadena (primer argumento) que coincida con la segunda cadena completa (segundo argumento). Se cuenta desde 0 en adelante. 5. strrchr(): devuelve la subcadena que comprende el fragmento de la primera cadena (primer argumento) que va desde la última aparición del carácter pasado como segundo argumento hasta el final de la primera cadena. 6. strstr(): devuelve una subcadena de la cadena pasada como primer argumento que comprende desde la primera aparición de la cadena pasada como segundo argumento hasta el final de la primera cadena. 7.8.12. Operaciones con subcadenas La función substr() devuelve una subcadena de la cadena que se pasa como primer argumento. Esta subcadena contiene los caracteres de la cadena desde la posición que se indica en el segundo argumento, que debe ser un número entero, hasta el número que se indique en el tercer argumento. Por ejemplo, echo substr("Memorias de África",3,4) devuelve la subcadena "oria". Conviene observar que la cuenta empieza desde 0. La sintaxis de esta función puede ser variada: • El segundo argumento indica la posición a partir de la cual se empieza a extraer la subcadena. Si el argumento es positivo la extracción empieza en la posición indicada contando a partir del primer carácter de la cadena. Sin embargo si el argumento es negativo se cuenta a partir del último carácter de la cadena. echo echo echo echo substr("Hello”,1); // retorna ello substr("Hello”,2); // retorna llo substr("Hello”,-1); // retorna o substr("Hello”,-2); // retorna lo 99 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • El tercer argumento indica la longitud de la subcadena extraída. Si el argumento es positivo se recupera el número de caracteres especificado a partir de la posición de inicio. Sin embargo si es negativo se recuperan todos los caracteres a partir de la posición de inicio menos los especificados en longitud. echo echo echo echo substr("ABCDE”,1,-1) // retorna BCD substr("ABCDE”,2,2) // retorna CD substr("ABCDE”,-3,1) // retorna C substr("ABCDE”,-3,-1) // retorna CD La función substr_replace() sustituye una subcadena de la cadena que se pasa como primer argumento con la subcadena que se pasa como segundo argumento desde la posición de inicio que se pasa como tercer argumento tantos caracteres como se indique en el cuarto argumento. Es una función existente a partir de PHP 4. Por ejemplo, echo substr_replace("Memorias de África","en",9,2) devuelve la cadena como "Memorias en África". En la sintaxis de esta función también pueden darse las circunstancias explicadas en la funcion substr. La función strtok() separa una cadena de texto (primer argumento) en bloques según el separador indicado en el segundo argumento. La función parse_str() trata una cadena de caracteres como si su información se pasase a otra página mediante la URL. Conviene observar que esa cadena debe tener el formato adecuado. Por ejemplo, las sentencias $variables="nom=Nacho&ape1=Roa&ape2=Bastos", parse_str($variables); define las variables $nom, $ape1 y $ape2, y les asigna los valores "Nacho", "Roa" y "Bastos", respectivamente. Así puede pasarlas a otra página. 7.8.13. Invertir el texto de una cadena La función strrev() recibe una cadena de caracteres y la devuelve al revés. Por ejemplo, la sentencia 7.8.14. echo strrev("paseo"); devuelve "oesap". Comparar cadenas La función strcasecmp() compara dos cadenas pasadas como argumentos sin distinguir entre letras mayúsculas y minúsculas y devuelve un número entero, que es un cero si son iguales, un número mayor que cero si la primera es mayor que la segunda y un número menor que cero si la primera es menor que la segunda. Por ejemplo, la instrucción strcasecmp("ABC","abc") devuelve 0, la instrucción strcasecmp("CAB","abc") devuelve 2 y la instrucción strcasecmp("ABC","cab") devuelve -2. 100 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La función strcmp() compara dos cadenas pasadas como argumentos distinguiendo entre letras mayúsculas y minúsculas y devuelve los mismos valores que la función anterior con la salvedad indicada. En el mismo ejemplo anterior, las tres instrucciones siempre devolverían -1. 7.8.15. Otras funciones de cadena útiles La función chr() recibe un número entero y devuelve el carácter correspondiente del código ASCII. Por ejemplo, echo chr(65); devuelve la letra A mayúscula. La función ord() recibe un carácter del código ASCII y devuelve el número entero correspondiente. Por ejemplo, echo ord("A"); devuelve el número 65. La función number_format() permite formatear un número como nos convenga. Recibe un número de coma flotante como primer argumento y devuelve una cadena con un determinado número de decimales fijado en el segundo argumento, separado de la parte entera por un signo especificado en el argumento tercero y un separador de los miles que se fija en el argumento cuarto. Por ejemplo, si la variable $numero contiene el valor 1234.5678 (el punto es el separador decimal), la instrucción echo number_format($numero,3,",","."); devuelve la cadena 1.234,567. Es importante saber cómo están definidos los valores de configuración local de PHP para los puntos decimales. En la función siguiente se explica este asunto. La función setlocale() establece los valores de distintas categorías que pueden ser diferentes para distintas configuraciones locales, como la conversión y clasificación de caracteres en los diversos idiomas, los separadores de decimales, el formato de fecha y hora, así como la comparación de cadenas y de monedas. Por ejemplo, la instrucción setlocale(LC_ALL,"spanish") fija todas las categorías disponibles (LC_ALL: conversión y clasificación de caracteres en los diferentes idiomas, separadores de decimales y formato de fecha y hora) para el entorno español, que en la mayoría de las categorías es igual al europeo. 7.9. Funciones de tratamiento de arrays Hemos visto que una variable tiene un nombre que debe iniciarse por el signo dólar ($) y un valor de uno de los tipos que soporta PHP. Pero en una variable sólo podemos introducir un valor. ¿Hay alguna forma de asignar más de un valor a un identificador? Sí, pero hay que usar arrays, que son conjuntos de datos de diferentes tipos que se asignan a un solo nombre. Un array o matriz se caracteriza por tres cosas: • Está integrado por múltiples elementos (elements). 101 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • Tiene un índice (key o index) para referirse a cada uno de sus elementos. Este índice, también llamado subíndice, puede ser de tipo numérico entero o de tipo cadena. En PHP el índice del primer elemento tiene el valor 0, si es de tipo numérico entero. • Cada elemento tiene un contenido (value), que puede ser de diferente tipo que el resto de los elementos. 7.9.1. Crear e inicializar una matriz En PHP, como en la mayoría de los lenguajes informáticos, hay varias formas de crear un matriz y de asignar valores a cada uno de sus elementos. $persona["nombre"] = "Josefa"; $persona["apellido1"] = "Pérez"; $persona["apellido2"] = "Rubio"; $persona["edad"] = 60; En las cuatro instrucciones anteriores hemos creado la matriz $persona, que tiene cuatro elementos que se referencian por cuatro índices de tipo cadena. Pero también podíamos haber creado e inicializado esta matriz así: $persona[] $persona[] $persona[] $persona[] = = = = "Josefa"; "Pérez"; "Rubio"; 60; En este segundo caso, PHP asigna los índice 0, 1, 2 y 3 a cada elemento secuencialmente. Lo mismo hubiéramos conseguido igualmente con la sintaxis: $persona[0] $persona[1] $persona[2] $persona[3] = = = = "Josefa"; "Pérez"; "Rubio"; 60; aunque habría resultado más largo e innecesario. No es preciso asignar índices que sean valores numéricos enteros consecutivos, si bien es preciso conocer el número o el nombre de los índices para poder, después, referirse a los elementos correspondientes. Otra forma de crear la misma matriz con índices de cadena es la siguiente: $persona = array("nombre"=> "Josefa","apellido1"=> "Pérez", "apellido2"=> "Rubio","edad"=>60); Como puede verse, esta sintaxis utiliza la palabra reservada array, pone entre comillas los índices de cadena y usa el signo => para asignar el valor a los elementos. Para crear una matriz bidimensional con las calificaciones obtenidas por una alumna en las tres evaluaciones de Matemáticas, Lengua y Dibujo usando índices alfanuméricos, podemos escribir lo siguiente: $notas["Mat"]["Pri"] $notas["Mat"]["Seg"] $notas["Mat"]["Ter"] $notas["Len"]["Pri"] $notas["Len"]["Seg"] $notas["Len"]["Ter"] $notas["Dib"]["Pri"] $notas["Dib"]["Seg"] $notas["Dib"]["Ter"] 102 = = = = = = = = = "Suficiente"; "Bien"; "Notable"; "Sobresaliente"; "Sobresaliente”; "Notable"; "Notable"; "Bien"; "Suficiente"; PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Con la misma filosofía de índices, podíamos haberlo hecho de la forma siguiente: $notas = array("Mat"=>array("Pri"=>"Suficiente", "Seg"=>"Bien", "Ter"=>"Notable"), "Len"=>array("Pri"=>"Sobresaliente", "Seg"=>"Sobresaliente", "Ter"=>"Notable"), "Dib"=>array("Pri"=>"Notable", "Seg"=>"Bien", "Ter"=>"Suficiente")); Igualmente, podíamos haber puesto las calificaciones en número y usado índices numéricos para las evaluaciones y las asignaturas, de 0 a 2 para ambas. En este caso la matriz $notas habría quedado así: $notas[0][0] $notas[0][1] $notas[0][2] $notas[1][0] $notas[1][1] $notas[1][2] $notas[2][0] $notas[2][1] $notas[2][2] = = = = = = = = = 1; 2; 3; 4; 5; 6; 7; 8; 9; Es más breve, si bien hay que saber a qué asignatura y evaluación pertenece cada índice. En la sintaxis precedente quedaría así: $notas = array(0=>array(0=>1,1=>2,2=>3), 1=>array(0=>4,1=>5,2=>6), 2=>array(0=>7,1=>8,2=>9)); Como hemos visto, pues, la función array() permite crear e inicializar matrices, si bien no es la única forma de hacerlo. Su sintaxis es array(lista de elementos separados por comas); En la lista de elementos se pueden poner valores de los diferentes tipos de datos que admite PHP. Además, es posible especificar expresamente un índice numérico o de cadena para referirse a cada uno de sus elementos. La función range() devuelve una matriz que sólo contiene los elementos indicados entre dos números, ambos incluidos. Su sintaxis es range(número entero del límite inferior, número entero del límite superior); Por ejemplo, si creamos la matriz $numeros=range(2,6) la matriz resultante tiene cinco elementos: el primero contiene el valor 2 y el último, el valor 6. 103 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 7.9.2. Recorrer los elementos de una matriz unidimensional Las matrices tienen un puntero que apunta a uno de sus elementos. Cuando se accede o usa por primera vez una matriz, el puntero está posicionado sobre el primer elemento. Pero no siempre está sobre este elemento, ya que el puntero puede haberse movido para leer o modificar el contenido de la matriz. La operación de recorrer los elementos de una matriz se lleva a cabo de forma diferente según se trate de matrices secuenciales, es decir, que tienen ordenados sus elementos por un índice ordinal como 0, 1, 2, 3, etcétera, o de matrices no secuenciales, es decir, que no tienen ordenados sus elementos por un índice ordinal. Si creamos una matriz sin utilizar expresamente un índice, PHP le asigna un índice ordinal numérico secuencial, que se inicia con el valor 0. Así pues, los elementos quedarán ordenados por su índice desde 0 hasta su elemento n-1. Pero podemos crear una matriz asignándole un índice numérico que no esté ordenado o incluso un índice de tipo cadena desordenado. Por ejemplo, podíamos haber creado e inicializado así la matriz $persona: $persona[10] $persona[2] $persona[5] $persona[1] = = = = "Josefa"; "Pérez"; "Rubio"; 60; En este caso el primer elemento contendría también "Josefa", pero si queremos acceder al mismo por su índice deberíamos citar el 10. Así pues, esta matriz está desordenada por su índice. Veremos más adelante cómo ordenar matrices por su índice o por el contenido de sus elementos. La función reset() coloca el puntero de una matriz sobre su primer elemento y devuelve su contenido. Por ejemplo, la instrucción echo reset($persona); devuelve "Josefa". Cuando conocemos que el índice utilizado en una matriz es de tipo numérico entero secuencial (0, 1, 2,...), la forma más fácil de acceder a cada elemento es usar la función count() para saber cuántos elementos tiene. Después, podemos utilizar un bucle for para recorrer todos sus elementos. La función end() coloca el puntero de una matriz sobre su último elemento y devuelve su contenido. Por ejemplo, la instrucción echo end($persona); devuelve 60. La función count() cuenta los elementos que integran una matriz y devuelve un número entero. Por ejemplo, la instrucción echo count($persona); devuelve 4. A partir de esta información, podemos recorrer los elementos y mostrar su contenido con un bucle, de esta forma: $numero_elementos=count($persona); for ($i=0; $i < $numero_elementos; $i++) echo $persona[$i]."
"; 104 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Podemos pensar que nos hubiéramos evitado una instrucción si ponemos la función count() como parte de la condición dentro de for. No es conveniente hacerlo por dos motivos: 1. Evitar que se ejecute la función cada vez que se pase por el bucle con la consiguiente pérdida de tiempo al contar siempre lo mismo. 2. Evitar un mal funcionamiento del bucle si dentro de las instrucciones del bucle se altera el número de elementos de la matriz con la función unset(). En cambio, si queremos recorrer una matriz bidimensional, no podemos usar la función count(), sino que debemos utilizar dos bucles, uno anidado en el otro de esta forma: for ($i=0; $i < 3; $i++) { for ($j=0; $j < 3; $j++) echo "".$notas[$i][$j]." - "; } La función next() devuelve el contenido del siguiente elemento según la posición donde esté el puntero y desplaza éste a esa posición nueva. Si se ha alcanzado el último elemento, esta función devuelve False. Por ejemplo, la instrucción echo next($persona); devuelve "Pérez" si el puntero estaba sobre el elemento primero antes de ejecutarse la función. La función prev() devuelve el contenido del elemento anterior según la posición donde esté el puntero y desplaza éste a esa posición nueva. Si se ha alcanzado el primer elemento, esta función devuelve False. Por ejemplo, la instrucción echo prev($persona); devuelve False si el puntero estaba sobre el elemento primero antes de ejecutarse la función. La función current() devuelve el contenido de elemento sobre el que está el puntero sin variar su posición. Por ejemplo, echo current($persona); devuelve "Rubio" si el puntero está sobre el elemento 3. Si se ha sobrepasado el último elemento de la matriz, current() devuelve False. A partir de esta información también podemos recorrer los elementos y mostrar su contenido con el bucle anterior for ($i=0; $i < count($persona); $i++) { echo current($persona)."
"; next($persona); } La función key() devuelve el índice de la posición actual del puntero, se trate de un número entero o de una cadena. Por ejemplo, la instrucción echo key($persona); devuelve "apellido1" si el puntero está sobre el segundo elemento. Podemos recorrer los elementos y mostrar su índice y su contenido con las instrucciones siguientes: 105 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO $datos=array("nombre"=>"Josefa","apellido1"=>"Pérez", "apellido2"=>"Rubio","edad"=>60); $numero_elementos=count($datos); for ($i=0; $i < $numero_elementos; $i++) { $indice=key($datos); $valor=current($datos); echo "Indice: $indice. Contenido: $valor
"; next($datos); } Este código muestra la página siguiente: Indice: Indice: Indice: Indice: 7.9.3. nombre. Contenido: Josefa apellido1. Contenido: Pérez apellido2. Contenido: Rubio edad. Contenido: 60 Convertir cadenas de caracteres en matrices y viceversa La función explode() permite convertir una cadena de caracteres en una matriz mediante un separador dado. Su sintaxis es explode(carácter separador, cadena); La función implode() lleva a cabo la operación inversa: lleva los elementos de una matriz a una cadena separándolos como se indique. Su sintaxis es implode(carácter separador, matriz); 7.9.4. Ordenar matrices Ya hemos comentado que los elementos de las matrices pueden estar desordenados, bien por su índice bien por su contenido. Veamos cómo podemos ordenar los elementos de una matriz de diferentes formas. La función arsort() ordena los elementos de una matriz teniendo en cuenta su contenido (valor) de mayor (en el código ASCII) a menor manteniendo la asociación del contenido de cada elemento con su índice. Su sintaxis es arsort(matriz); Por ejemplo, si tenemos la matriz $palabras=array("1"=>"amazona","2"=>"león","3"=>"zozobra", "4"=>"sabueso", "5"=>"bondad","6"=>"obús"); la instrucción arsort($palabras); devuelve la matriz 106 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO $palabras=array("3"=>"zozobra","4"=>"sabueso","6"=>"obús", "2"=> "león", "5"=>"bondad","1"=>"amazona"); La función asort() hace exactamente lo mismo que la función arsort(), pero ordenando su contenido de menor a mayor. Su sintaxis es asort(matriz); Por ejemplo, si tenemos la matriz $palabras=array("1"=>"amazona","2"=>"león","3"=>"zozobra", "4"=>"sabueso", "5"=>"bondad","6"=>"obús"); la instrucción asort($palabras); devuelve la matriz $palabras=array("1"=>"amazona","5"=>"bondad", "2"=> "león", "6"=>"obús", "4"=>"sabueso","3"=>"zozobra"); La función rsort() ordena los elementos de una matriz teniendo en cuenta su contenido (valor) de mayor (en el código ASCII) a menor pero sin mantener la asociación del contenido de cada elemento con su índice. La función sort() hace exactamente lo mismo que la función rsort() pero ordenando de menor a mayor. La función krsort() ordena los elementos de una matriz teniendo en cuenta su índice de mayor (en el código ASCII) a menor manteniendo la asociación de cada índice con el contenido de cada elemento. Su sintaxis es krsort(matriz); Por ejemplo, si tenemos la matriz $palabras=array("1"=>"amazona","2"=>"león","3"=>"zozobra", "4"=>"sabueso","5"=>"bondad","6"=>"obús"); la instrucción krsort($palabras); devuelve la matriz $palabras=array("6"=>"obús","5"=>"bondad","4"=>"sabueso", "3"=>"zozobra","2"=>"león","1"=>"amazona"); La función ksort() ordena los elementos de una matriz teniendo en cuenta su índice de menor (en el código ASCII) a mayor manteniendo la asociación de cada índice con el contenido de cada elemento. La función shuffle() ordena la matriz que se le pasa como parámetro de forma aleatoria. Su sintaxis es shuffle(matriz); 107 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La función uasort() ordena los elementos de una matriz teniendo en cuenta su contenido y según una función de comparación definida por el usuario manteniendo la asociación del contenido de cada elemento con su índice. Su sintaxis es uasort(matriz,función de usuario); Por ejemplo, si definimos la función de usuario compara() y la usamos como segundo argumento de la función uasort(), obtenemos estos resultados: function compara($a,$b) { return (substr($a,3,1)>substr($b,3,1)); } $colores=array("a"=>"blanco","b"=>"azul","c"=>"rojo", "d"=>"amarillo","e"=>"verde"); uasort($colores,"compara"); for (reset($colores);$indice=key($colores);next($colores)) echo "Indice: $indice Contenido:$colores[$indice]"; En este caso la función uasort() ordena los elementos según el cuarto carácter de su contenido de menor a mayor (se cuenta desde 0; por eso hemos puesto 3 en la función de usuario), que es lo que ejecuta la función de usuario compara(). Así pues, la matriz queda así: $colores=array("e"=>"verde","b"=>"azul","a"=>"blanco", "c"=>"rojo","d"=>"amarillo"); La función usort() hace exactamente lo mismo que la anterior, suponiendo lógicamente que aplicáramos la misma función de usuario que es la que determina el orden de los elementos según su contenido, pero sin mantener la asociación del índice de cada elemento con su contenido. La función uksort() ordena los elementos de una matriz teniendo en cuenta su índice y según una función de comparación definida por el usuario manteniendo la asociación del índice de cada elemento con su contenido. Su sintaxis es uksort(matriz,función de usuario); Por ejemplo, si definimos la función de usuario compara() y la usamos como segundo argumento de la función uksort(), obtenemos estos resultados: function compara($a,$b) { return (substr($a,3,1)>substr($b,3,1)); } $colores=array("primero"=>"blanco","segundo"=>"azul", "tercero"=>"rojo","cuarto"=>"amarillo", "quinto"=>"verde"); uasort($colores,"compara"); for (reset($colores);$indice=key($colores);next($colores)) echo "Indice: $indice Contenido:$colores[$indice]
"; 108 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO En este caso la función uksort() ordena los elementos según el cuarto carácter de su índice de mayor a menor (se cuenta desde 0; por eso hemos puesto 3 en la función de usuario), que es lo que ejecuta la función de usuario compara(). Así pues la matriz queda así: $colores=array("segundo"=>"azul","cuarto"=>"amarillo", "quinto"=>"verde","primero"=>"blanco", "tercero"=>"rojo"); 7.9.5. Modificar matrices Las matrices ya creadas e inicializadas pueden modificarse de diferentes formas: n Uniendo los elementos de dos o más matrices. La función array_merge(), con comportamiento diferente a partir de la versión 5 de PHP, recibe como argumentos dos o más matrices y devuelve otra en la que se han unido todas las que se pongan como argumentos anexionando los elementos de unas a continuación de las otras, según el orden en que se pongan los argumentos. Su sintaxis es array_merge(matriz1,matriz2...); Si en la mezcla algún índice se repite, el último en añadirse elimina el elemento de las matrices anteriores en que se repita. o Completando los elementos de una matriz. La función array_pad() rellena una matriz añadiendo los elementos que se indique con el contenido que se especifique. Su sintaxis es array_pad(matriz,número de elementos de la matriz resultante,relleno de los elementos añadidos); donde matriz es la matriz original a la que se añaden elementos; número de elementos es un entero que indica cuántos elementos tendrá la matriz después de ejecutarse la función; relleno es la cadena o valor con el que se completará el contenido de los nuevos elementos. Si número de elementos es igual o inferior al número de elementos de la matriz original, no se produce ningún cambio en la misma. Si es negativo, los elementos se añaden por el principio de la matriz original. Si es positivo, se añaden por el final. Por ejemplo, si tenemos la matriz de cinco elementos $sabores=array("dulce","amargo","salado","soso","menta"); la instrucción 109 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO $completa=array_pad($sabores,8,"indeterminado"); genera la matriz $completa=array("dulce","amargo","salado","soso","menta", "indeterminado","indeterminado","indeterminado"); p Invirtiendo el orden de la matriz original. La función array_reverse(), añadida en la versión 4 de PHP, devuelve otra matriz que contiene los mismos elementos ordenados al revés, es decir, invierte el orden de los elementos de forma que el primero pasa a ser el último y el último pasa a ser el primero. Su sintaxis es array_reverse(matriz); q Sustituyendo un fragmento de elementos por otro. La función array_splice(), devuelve la misma matriz sustituyendo varios elementos consecutivos por otros nuevos. Su sintaxis es array_splice(matriz original,posición inicial del desplazamiento,longitud del desplazamiento,cadena-valor-matriz que sustituye el fragmento de la original); • • • donde: el argumento posición inicial del desplazamiento es un número entero que indica la posición, contando desde 0, del primer elemento que debe ser sustituido. Si es menor que 0, se cuenta desde el último elemento de la matriz original siendo el último elemento el que ocupa la posición –1. el argumento longitud del desplazamiento es un número entero que indica el número de elementos que serán sustituidos a partir de la posición especificada en el argumento anterior. Si se omite, se eliminan todos desde la posición indicada. Si es menor que 0, se eliminan tantos como se indique, pero contando desde el final de la matriz original hasta la posición especificada. el argumento cadena, valor o matriz contiene el contenido que ha de asignarse a los elementos eliminados. Puede no existir. En este caso, la matriz original pierde los elementos eliminados sin ser sustituidos por otros. Veamos algunos ejemplos: $matriz1=array("muy alto","alto","medio", "bajo","muy bajo"); $matriz2=array("óptimo","bueno","malo"); array_splice($matriz1,2,2); genera la matriz $matriz1=array("muy alto","alto","muy bajo"); 110 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Se han eliminado los elementos tercero y cuarto. array_splice($matriz1,2); genera la matriz $matriz1=array("muy alto","alto"); Se han eliminado todos los elementos desde el tercero. array_splice($matriz1,-2); genera la matriz $matriz1=array(("muy alto","alto","medio"); Se han eliminado los dos últimos elementos. array_splice($matriz1,2,1); genera la matriz $matriz1=array("muy alto","alto","bajo","muy bajo"); Se ha eliminado el elemento tercero. array_splice($matriz1,3,3,$matriz2); genera la matriz $matriz1=array("muy alto","alto","medio", "óptimo","bueno", "malo"); Se han sustituido, desde el elemento tercero, tres elementos con el contenido de la matriz $matriz2. array_splice($matriz1,count($matriz1),3,$matriz2); genera la matriz $matriz1=array("muy alto","alto","medio","bajo", "muy bajo","óptimo","bueno","malo"); Se han añadidos los elementos de la segunda matriz a los de la primera. No conviene confundirse con esta función: si generamos una segunda matriz con esta misma orden, ésta contendrá los elementos eliminados. Por ejemplo, la orden $nueva=array_splice($matriz1,3,3,$matriz2); genera la matriz $nueva=("bajo","muy bajo"); que son los dos elementos eliminados de la matriz original. 111 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO r Ejecutando una función de usuario sobre cada elemento de la matriz La función array_walk(),devuelve otra matriz en cuyos elementos se ha ejecutado una función de usuario. Su sintaxis es array_walk(matriz original,función de usuario,prefijo); s Juntando variables en una sola matriz La función compact() devuelve otra matriz en la que se han incorporado como elementos las diferentes variables y matrices que se especifiquen como argumento. Como índice se pone el nombre de la variable y como contenido el valor de cada variable. Su sintaxis es compact(lista de variables o arrays...); 7.9.6. Extraer información de las matrices La función array_count_values() recibe como argumento una matriz y devuelve otra cuyos índices son los contenidos de la original y cuyo contenido es la frecuencia con que se repite el mismo contenido en la matriz original. Su sintaxis es array_count_values(matriz); La función array_keys() recibe como argumento una matriz y devuelve otra que contiene sólo los índices de la matriz original como contenidos de los nuevos elementos. Como índices de la nueva matriz se asignan valores numéricos enteros desde 0 en adelante. Su sintaxis es array_keys(matriz,valor); El segundo argumento es opcional y, si se usa, sirve para decir que pase a la matriz resultante sólo los índices de los elementos que contengan ese valor. La función array_slice(), devuelve otra matriz que contiene una porción de elementos de la matriz original. Su sintaxis es array_slice(matriz original, posición inicial del desplazamiento, longitud del desplazamiento); donde 112 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO • • el argumento posición inicial del desplazamiento es un número entero que indica la posición, contando desde 0, del primer elemento que debe ser extraído. Si es menor que 0, se cuenta desde el último elemento de la matriz original siendo el último elemento el que ocupa la posición –1. el argumento longitud del desplazamiento es un número entero que indica el número de elementos que serán extraídos a partir de la posición especificada en el argumento anterior. Si se omite, se extraen todos los elementos desde la posición indicada. Si es menor que 0, se extraen tantos como se indique, pero contando desde el final de la matriz original hasta la posición especificada. Como se ve, esta función tiene un comportamiento similar a la función array_splice(), pero aquí se extraen los elementos y en aquélla se eliminan o sustituyen. $altura=array("muy alto","alto","medio","bajo","muy bajo"); $nueva=array_slice($altura,2,2); genera la matriz $nueva=array("medio","bajo"); Se han extraído los elementos tercero y cuarto. La función array_values() recibe como argumento una matriz y devuelve otra en la que se han eliminado los índices dejando sólo los contenidos. Su sintaxis es array_values(matriz original); Lógicamente, como no puede haber una matriz sin índices, a cada elemento se le asignan índices numéricos desde 0 en adelante y se eliminan los que tuviera antes, sean cadenas u otros valores numéricos. La función each() lee el elemento actual de una matriz y avanza el puntero al elemento siguiente. Con el elemento leído fabrica otra matriz de cuatro elementos: dos para el índice (0 y key) y dos para el contenido (1 y value). Generalmente, esta función se utiliza combinada con la función list() para recorrer los elementos de una matriz con un bucle. Su sintaxis es each(matriz original); Por ejemplo, si tenemos la matriz $con_indices=array("uno"=>"muy alto","dos"=>"alto", "tres"=>"medio","cuatro"=>"bajo", "cinco"=>"muy bajo"); y suponemos que el puntero está sobre el elemento "tres"=>"medio", la instrucción $nueva=each($con_indices); devuelve la matriz de cuatro elementos siguiente 113 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO $nueva=array(0=>"tres","key"=>"tres", 1=>"medio","value"=>"medio") Los dos primeros elementos de la matriz resultante hacen referencia al índice del elemento actual de la matriz original. De esta forma podemos referirnos a su contenido también de dos formas: $nueva[0] o $nueva("key"). Como puede verse, los dos últimos elementos de la matriz resultante hacen referencia al contenido del elemento actual de la matriz original. De esta forma podemos referirnos a su contenido de dos formas: como $nueva[1] o como $nueva("value"). La función extract() pasa los contenidos de los elementos de una matriz como contenidos de las variables que llevan como nombre el índice de cada elemento de la misma matriz. Como consecuencia, a la tabla de símbolos de variables se incorporan estas nuevas variables. Su sintaxis es extract(matriz, si hay conflictos tipo de extracción,si hay conflictos cadena de sustitución); Los dos últimos argumentos son opcionales y sólo se aplican, si existen, cuando al ejecutar la extracción se han producido colisiones, es decir, si la variable que se pretendía crear ya existía e incluso si era de diferente tipo. En caso de colisión entre variables, el segundo argumento tiene los valores siguientes: • EXTR_OVERWRITE: se descarta el valor anterior de la variable y se pone el nuevo. Este valor es el que se usa por defecto en caso de colisión, aunque no se indique como argumento. • EXTR_SKIP: se descarta el valor nuevo de la variable y se pone el anterior. • EXTR_PREFIX_SAME: al nombre de la variable nueva conflictiva se le pone como prefijo la cadena del tercer argumento seguida de un guión de subrayado (_). • EXTR_PREFIX_ALL: al nombre de todas las variables nuevas se le pone como prefijo la cadena del tercer argumento seguida de un guión de subrayado (_). • EXTR_PREFIX_INVALID: solo agrega el prefijo a nombres de variables inválidas. • EXTR_IF_EXISTS: solo sobrescribe la variable si ya existe. • EXTR_PREFIX_IF_EXISTES: solo extrae y añade prefijo a las variables si estas xa existen sin prefijo • EXTR_REFS: extrae las variables como referencias a los elementos originales de la matriz, de forma que si se modifica esta se modifican los valores de las variables. Esta función comprueba también si el nombre de las nuevas variables es válido y sólo las crea si lo es. La función in_array() devuelve True si un valor está contenido en alguno de los elementos de una matriz y False si no lo está, Su sintaxis es in_array(valor buscado, matriz donde se busca); 114 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La construcción list() asigna en una única operación el valor de los elementos de una matriz a una lista de variables que se usan como argumento. Ya comentamos que la función each() se usa, por lo general, combinada con la función list() para recorrer los elementos de una matriz dentro de un bucle. Su sintaxis es list(lista de variables); Por ejemplo, si tenemos la matriz $comunidad=array("CA1"=>"Aragón","CA2"=>"Andalucía", "CA3"=>"Galicia","CA4"=>"Murcia", "CA5"=>"Valencia","CA6"=>"Canarias"); el bucle siguiente recorre y muestra el contenido de todos sus elementos: while (list($indice,$valor)=each($comunidad)) { print ("El elemento $indice contiene el valor $valor
"); } En la condición con la que se establece el bucle combinando list() y each() se consigue que list() tome en sus dos variables el índice y el contenido de cada elemento, que luego se muestran. Además, una vez proporcionada por each() la información de cada elemento a list(), hace avanzar el puntero un elemento más, por lo que el bucle se acaba cuando ya no hay elementos que ofrezcan la información necesaria. 7.9.7. Tratar un array como si fuera una pila La versión 4 de PHP ha incorporado cuatro funciones que permiten tratar las matrices como si fueran pilas de tipo LIFO (Last In First Out, Último en Entrar Primero en Salir). El concepto de pila ya es clásico en Informática y se refiere a la forma de almacenar información en forma de montón o pila, Si tenemos muchos platos, podemos almacenarlos apilándolos unos encima de otros. En este caso lo más usual será que el último plato colocado en la pila sea el primero que se retira. Las matrices también pueden considerarse como pilas de datos, que son sus elementos. Veamos las funciones que nos permiten realizar operaciones de tipo pila con las matrices. La función array_pop() extrae el último elemento de la matriz eliminándolo. Su sintaxis es array_pop(matriz); La función array_push() añade elementos al final de la matriz. Su sintaxis es array_push(matriz,lista de elementos que se añaden); 115 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO La función array_shift() extrae el primer elemento de la matriz eliminándolo y desplazando todos una posición a la izquierda. Su sintaxis es array_shift(matriz); La función array_unshift() inserta elementos por el principio de la matriz desplazando los demás a la derecha. Su sintaxis es array_unshift(matriz,lista de elementos que se añaden); Es conveniente observar que, cuando añadimos elementos, PHP crea los índices para cada uno, que son de tipo numérico ordinal. 7.10. Funciones de Tratamientos de Fechas El uso de fechas es muy frecuente e imprescindible en Internet. PHP dispone también de funciones para tratar y obtener fechas. En este apartado se verán las más importantes y necesarias, así como su aplicación en las páginas web . En el Capítulo XXIII. Funciones de fecha y hora del Manual Oicial de PHP aparecen todas las funciones de fecha. 7.10.1. Comprobar la validez de una fecha La función checkdate() nos permite comprobar si una fecha, que se pone como argumento, es válida. Si lo es, la función devuelve el valor True. En el caso contrario, devuelve False. Se considera como válida una fecha cuando su año está comprendido entre los años 1 y el 32767, su mes entre 1 y 12, y su día entre 1 y 28 para febrero no bisiesto, 29 para febrero bisiesto, 30 para abril, junio, septiembre y noviembre, y 31 para el resto de los meses. Así pues, esta función controla los años bisiestos al comprobar la validez de una fecha. La sintaxis de esta función es checkdate(mes,día,año); donde los tres parámetros son números enteros. Conviene observar el orden en que deben introducirse los parámetros, ya que no coinciden con la posición habitual de nuestras fechas (día,mes,año). Por ejemplo, la instrucción checkdate(0,25,2000); devuelve False. En cambio la instrucción checkdate(7,25,2000); devuelve True. 116 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 7.10.2. Dar formato a una fecha y una hora La función date() devuelve una cadena de texto que refleja una fecha y una hora formateadas como se indique en el primer parámetro. En el segundo argumento puede indicarse la fecha que se quiere mostrar utilizando un valor de tipo timestamp (instante calculado como número de segundos transcurridos desde el 1/1/1970, época UNIX). Si no se especifica este segundo parámetro, se muestra la hora actual. La sintaxis de esta función es: date(cadena de formato, número entero del instante o nada); Tabla de caracteres y su significado en la cadena de formato Signo a A c d D e F h H g G i j l L m n N M s S t u U w W Y y z Z Descripción de su resultado en la página web "am" o "pm" "AM" o "PM" fecha completa ISO 8601 día del mes, dos dígitos con cero a la izquierda; es decir, de "01" a "31" día de la semana, en texto, con tres letras; por ejemplo, "Fri" zona horaria; por ejemplo “UTC”,”GMT” mes, en texto, completo; por ejemplo, "January" hora, de "01" a "12" hora, de "00" a "23" hour, sin ceros, de "1" a "12" hour, sin ceros; de "0" a "23" minutos; de "00" a "59" día del mes sin cero inicial; de "1" a "31" día de la semana, en texto, completo; por ejemplo, "Friday" "1" or "0", según si el año es bisiesto o no mes; de "01" a "12" mes sin cero inicial; de "1" a "12" día de la semana: “1” para lunes … “7” para domingo mes, en texto, 3 letras; por ejemplo, "Jan" segundos; de "00" a "59" sufijo ordinal en inglés, en texto, 2 caracteres; por ejemplo, "th", "nd" número de días del mes dado; de "28" a "31" Milisegundos segundos desde el valor de 'epoch' UNIX día de la semana, en número, de "0" (domingo) a "6" (sábado) número de la semana en el año año, cuatro cifras; por ejemplo, "1999" año, dos cifras; por ejemplo, "99" día del año; de "0" a "365" diferencia horaria en segundos (de "-43200" a "43200") Conviene observar que esta cadena no utiliza categorías locales, por lo cual los nombres de los días y los meses aparecen en inglés. Para formatear una fecha y mostrar su resultado, es mejor utilizar la función strftime(), que se explica después. 7.10.3. Extraer información de una fecha La función getdate() se usa para extraer información de una fecha dada. Tampoco admite categorías locales y, por tanto, la información literal está en inglés. La sintaxis de esta función es: getdate(número entero del instante); 117 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO El instante es un número referido a los segundos transcurridos desde el día 1/1/1970 hasta la fecha. La información obtenida se almacena en un array cuyos índices son los siguientes: 1. “seconds”: número de segundo 2. “minutes”: número de minutos 3. “hours”: número de horas 4. “mday”: día del mes 5. “wday”: día de la semana en numero 6. “mon”: número de mes 7. “year”: año 8. “yday”: día del año 9. “weekday”: nombre del día de la semana 10. “month”: nombre del mes. 11. “0”: segundos desde el comienzo de la época Unix Por ejemplo, la instrucción $fecha=getdate(); asigna al array $fecha los nueve contenidos indicados antes. La función mktime() se usa para extraer el valor timestamp de una fecha. Después, podemos utilizar este valor como argumento de otras funciones. El término timestamp se refiere al momento exacto de una fecha concreta expresado en segundos desde el día 1 de enero de 1970 (época UNIX). Esta función nos permite hallar el número de segundos que han transcurrido desde entonces hasta la fecha que especifiquemos. La sintaxis de esta función es mktime(horas,minutos,segundos,mes,día,año); Por ejemplo, si queremos saber el momento timestamp del día 16 de diciembre de 1999, a las 10 horas, 15 minutos y 20 segundos, debemos escribir la instrucción $momento=mktime(10,15,20,12,16,1999);. El resultado es 945339320. Ahora podemos dar este número como argumento de la función getdate() y obtenemos la misma fecha que le dimos a mktime(). Esta función es, además, muy útil para comprobar fechas y compararlas. 7.10.4. Dar formato a una fecha traduciendo los nombres La función strftime() se usa para formatear una fecha teniendo en cuenta las especificaciones y categorías locales. Así soslayamos los problemas de este tipo que plantean las funciones date() y getdate(). La sintaxis de esta función es strftime(cadena de formato,instante); Si no se proporciona el segundo parámetro, que es el número de segundos, se toma la hora del sistema. Veamos ahora los signos de la cadena de formato y sus resultados en la presentación de una fecha. 118 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Tabla de caracteres y su significado en la cadena de formato Signo %a %A %b %B %c %C %d %H %I %j %m %M %p %r %R %S %U %W %w %x %X %y %Y %Z %% Descripción de su resultado en la página web nombre del día de la semana abreviado nombre del día de la semana completo nombre del mes abreviado nombre del mes completo representación de fecha y hora preferidas en el idioma actual número de la centuria (año dividido entre 100) día del mes en número (de 00 a 31) hora como un número de 00 a 23 hora como un número de 01 a 12 día del año como un número de 001 a 366 mes como un número de 01 a 12 minuto en número ‘am’ o ‘pm’, según la hora dada, o las cadenas correspondientes en el idioma actual hora en notación a.m. y p.m. hora en notación de 24 horas segundos en número número de la semana en el año, empezando con el primer domingo como el primer día de la primera semana número de la semana en el año, empezando con el primer lunes como el primer día de la primera semana día de la semana en número (el domingo es el 0) representación preferida de la fecha sin la hora representación preferida de la hora sin la fecha año en número de 00 a 99 año en número de cuatro cifras nombre o abreviatura de la zona horaria carácter '%' Si queremos que los nombres aparezcan en castellano, aquí sí podemos incluir en el script la instrucción setlocale(LC_ALL,"spanish"); para traducirlos. 119 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO 8. Entrada y Salida de Datos ® ® ® Entrada de Datos Salida de Datos Consideraciones sobre la E/S 8.1. Entrada de Datos Normalmente la entrada de datos desde teclado se realiza a través de formularios HTML (forms). Los formularios nos proporcionan la posibilidad de preguntar al usuario cliente una serie de datos que pueden ser devueltos al servidor. Trabajar en PHP con forms es muy fácil, ya que el propio lenguaje se encarga de crear automáticamente las variables necesarias para almacenar los datos del form en la página que los recibe. Vamos a analizar cada uno de los casos: 8.1.1. Valores sencillos Para los campos de un formulario en los que únicamente se puede elegir o introducir un valor (como campos de texto, desplegables y “radio buttons”) PHP crea en el fichero de destino un elemento en la variable superglobal del método que se ha empleado para enviar el formulario (POST, GET,..), con clave igual al nombre del elemento del formulario. Es decir, la clave del elemento de la variable superglobal de PHP ($_GET, $_POST, $_REQUEST) en la página destino es igual al atributo Name del elemento del formulario HTML en la página origen. Por ejemplo, si tenemos este formulario:
En el script de destino accion.php, accederíamos a los valores enviados en el form así: Hola . Tiene años. Analicemos cada uno de los elementos de los formularios que se encuentran es esta situación: Cuadros De Texto (Text) Como hemos visto en el ejemplo anterior se origina un elemento de la matriz supreglobal con nombre igual al atributo Name del elementos input type=’text’ del formulario HTML y con valor igual al contenido introducido por el usuario. 121 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO Botones De Activación (Radio-Button) En este caso se origina un elemento de la matriz supreglobal con nombre igual al atributo Name del elementos input type=’radio’ del formulario HTML y con valor igual al atributo Value del botón de activación seleccionado por el usuario. Casillas de Verificación (CheckBox) En este caso se origina un elemento de la matriz supreglobal con nombre igual al atributo Name del elementos input type=’checkbox’ del formulario HTML que hayan sido seleccionados (de los que no se seleccionen no se genera elemento) y con valor igual al atributo Value de la casilla de verificación correspondiente. 8.1.2. Valores múltiples Para los campos de selecciones múltiples PHP también se encarga de almacenar los valores marcados por el usuario en un elemento de la matriz supreglobal (array) con el nombre del campo, pero en este caso tendremos que llevar cuidado de dar a las variables nombres de arrays, ya que si no sólo tendremos acceso al primer valor seleccionado. Por ejemplo este formulario estaría mal: Deberíamos haberlo escrito así: Y podemos ver el resultado con este código: 122 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO "; foreach($_POST[‘menu’] as $plato) { echo "$plato
\n"; } ?> 8.2. Salida de datos Normalmente la salida de datos se realiza por pantalla a través de paginas HTML. Para ellos se han de usar alguna de las funciones vistas en el apartado Funciones de Tratamientos de Cadenas del capítulo de Funciones, donde se explican en detalle. Dichas funciones son echo(), print(), printf() y sprintf(). Su sintaxis es: echo (argumento1, argumento2,...) Si el argumento es una cadena entre comillas dobles, debemos tener en cuenta que las variables incluidas en ese texto se expanden, es decir, muestran su contenido, no su nombre, pero las funciones no. Para que las variables no muestren su contenido debemos utilizar la barra hacia la izquierda (\) delante de la variable. Además, si queremos que las funciones se expandan (se ejecuten) debemos sacarlas de las comillas y concatenarlas con el texto anterior y posterior usando el operador de concatenación (.). print(argumento1, argumento2,...) Esta orden es prácticamente igual que echo, hasta el punto de que se pueden intercambiar sin problemas. printf ("cadena de formato", argumento1, argumento2,...) En los argumentos se incluye la información que se quiere mostrar, como con echo o con print. En la cadena de formato, entre comillas, puede ponerse un texto, que aparece tal cual lo escribamos, con expansión de las variables si no usamos el signo \, y el valor de una variable según se establezca en la directiva %. $cadena=sprintf(“cadena de formato”, argumento 1, argumento 2,...) Esta función nos permite dar formato a una cadena de texto exactamente igual que con printf, y guardar, además el resultado en una variable, para utilizarlo posteriormente. 8.3. Consideraciones sobre la E/S A la hora de trabajar con formularios hemos de tener en cuenta una serie de consideraciones: L Conviene saber que en PHP es frecuente que una página se llama a sí misma. Este procedimiento se denomina recursividad. Cuando se ejecuta el código por primera 123 PROGRAMACIÓN EN LENGUAJE PHP5. NIVEL BÁSICO vez, sólo se muestra el formulario vacío y no aparecen los datos. Es lógico, pues las variables aún no tienen contenido. Cuando las variables tengan algún contenido, introducido en la página mediante el formulario, se puede mostrar esta información en la página llamada de nuevo al pulsarse el botón Aceptar y ejecutarse la orden