Mini curso de PHP Versi贸n 2 6 de Febrero de 2008 Javier Peces Hidalgo <javierpeces@gmail.com>
Mini curso de PHP Ha llegado el momento. Pasen y vean, sufridos principiantes e ignorantes profanos en el arte de la tecla. Sean tocados por la mano de la ciencia, que todo lo bendice sin terminar de aclarar nada. Disfruten de ésta mi enésima tontería maestra. El menor curso de PHP que merece tal apelativo, liberado bajo la misma licencia que todo este humilde blog. Es decir, cópielo a placer citando su procedencia. Y no dude en darme un bocinazo si encuentra algún proyectil entre las líneas, cree que algo se debe mejorar o tiene la sensación de que necesita ayuda. Para eso estamos. Observe que a lo largo del texto se muestran fragmentos de código que ha de teclear “tal cual está” en su ordenador. Por ejemplo:
echo "Hola, mundo...\n“;
En el caso de que una línea de código sea más larga de lo que se puede representar en este documento, se usará el símbolo « para indicar que ha de teclear todo el texto seguido, sin pasar a una nueva línea: echo "Esta instrucción es tan larga que no queda más « remedio que escribirla en dos líneas del texto";
2
Introducción En éstos primeros capítulos introductorios [que aquel que tenga un cierto nivel puede saltarse sin problemas] cuento cómo empezar a manejarse en el mundo del PHP en ambiente de “pantalla negra”. Soy consciente de que esto da un poco de miedo a quienes nacieron en un mundo que no sabe respirar sin puertas y ventanas, y de que hay mucha gente que no entiende mi pasión por la “línea de comandos”. La pregunta que más me hacen al cabo del mes -en ambiente tecnológico, se entiende- no es otra que: ¿Por qué se empeña usted, pedazo de subnormal, en usar la pantalla negra? Y la respuesta siempre es la misma. “Porque quiero irme de aquí cuanto antes” Los espectaculares entornos gráficos, llenos de botones, listas desplegables de cosas, menús, ayudas contextuales y demás zarandajas tienen un grave inconveniente. Necesitan la constante atención de una persona frente a la pantalla. Y yo me quiero ir. De antros, de revolcones o similares. Todo menos estar aquí, haciendo el canelo. Dicho esto, deléitese con los capítulos iniciales sobre intérpretes, compiladores y líneas de comandos. Finalmente, construya su primer ejemplo escrito en PHP, el célebre hola, mundo.
3
Intérprete y compilador Se preguntará usted qué es esto del PHP, apreciado lector. Tal será el caso si pertenece a la segunda categoría, la de los “ignorantes profanos en el arte de la tecla“. No se preocupe, que se lo explico ahora mismo. A poco que se aplique mudará de categoría, poblando dentro de un tiempo el selecto grupo primero, el de los “sufridos principiantes”. Si lee habitualmente mi humilde blog, cosa que me extrañaría, ya se habrá topado con un extraño documento llamado nanocurso de shell script. Como es de esperar que no le suene para nada, ayudará un vistacillo rápido al concepto de lenguaje, visto en términos informáticos. Usted ya sabe lo que es un lenguaje en la vida cotidiana. Conjunto de ruidos y signos que producen un efecto sorprendente. Comunican mensajes que otros pueden percibir, entender e interpretar. Incluso pueden reaccionar si usted emite los sonidos apropiados en el momento oportuno y apuntando al interlocutor pertinente. El computador, desprovisto de pabellones auditivos, evita en principio la comunicación aérea. Y, para desesperación de Scotty -el de Star Trek- tampoco entiende las lenguas indoeuropeas del timorato hombre occidental. En su lugar, obtiene por procedimientos misteriosos una extraña sucesión de dígitos en base dos, compuesta por interminables cadenas de unos y ceros únicamente. Adecuadamente agrupados, estos unos y ceros componen las órdenes que el aparato entiende y ejecuta con singular predisposición y diligencia. ¿Inconveniente? Previsible. No se nos da bien leer y escribir encadenamientos de números como 0100 0101 0101 0101 1101. Por más atención que pongamos, por más interés que tengamos en aprender la extraña jerga, nos equivocaremos una y otra vez. Por eso, alguien muy sesudo inventó cosas para traducir textos escritos por y para seres humanos en código del que entiende la máquina, machine code que dicen los anglos y los sajones. Cada tipo de máquina entiende un dialecto diferente (los unos y los ceros no significan lo mismo en todos los computadores) y por ello este tipo de herramientas son especialmente oportunas.
4
Imagine que tiene usted una empresa -es un decir- de cerámica, y se entera de que en Croacia alguien construye unas máquinas que producen millones de azulejos a la hora con el mínimo coste. Con gran esfuerzo y paciencia consigue usted hacerse con una. Va a reducir sus costes y a aumentar sus beneficios de manera exorbitante. El gran problema es que todo viene escrito en serbocroata: Cartelitos junto a controles, mandos y botones. Hasta el manual de instrucciones. Necesita que alguien conocedor del idioma le ayude a salir del trance. Puede optar por contratar a alguien que hable español y serbocroata y esté constantemente al lado de la maquinita, recibiendo instrucciones y operando el aparato. Es un intérprete. También puede buscarse a alguien que traduzca el libro de instrucciones al español, de modo que un operario hispanohablante pueda manejar la máquina en el futuro. En el mundo de la informática esto se llama compilador. Cada uno tiene sus ventajas y sus inconvenientes. El intérprete es flexible porque está junto a la máquina siempre. Cualquier idea nueva que usted tenga será plasmada por él instantáneamente. Pero es ineficiente porque ha de convertir cada una de sus instrucciones al serbocroata así, al vuelo, y eso le lleva algún tiempo. El compilador crea un manual en español que será aprendido de una vez por el operario español, quien trabajará a toda velocidad una vez que comprenda el contenido. Pero cualquier nuevo comportamiento esperado requerirá una nueva traducción. Y eso llevará tiempo y dinero nuevamente. PHP, como veremos, es un intérprete. Perdiendo un poquito en términos de rendimiento puro y duro, se gana en flexibilidad. La sintaxis del lenguaje es relativamente fácil de entender, siempre que uno esté habituado a andar con computadores. No en vano es un primo cercano de otros lenguajes como C, C++, Pascal, etc. Los programas PHP se escriben en simples documentos de texto plano. Nota para infames usuarios de windows: Esto quiere decir que ha de usar el bloc de notas o notepad y no el word para manejarlos. Se debe a que los procesadores de texto guardan información sobre el formato (que si negrita, que si cursiva) y muchas otras cosas en el interior del documento. Texto plano significa “nada de formato”. Letras, números, signos de puntuación, saltos de columna y saltos de línea.
5
La línea de órdenes PHP está preparado para funcionar de tres maneras. La que veremos en primer lugar se denomina CLI (Command Line Interface, o interfaz de línea de órdenes). En la segunda modalidad, el código PHP puede embeberse dentro del código HTML que compone una página web, ejecutándose cada vez que esa página sea visitada. La tercera, conocida como CGI, es poco usada y no es muy relevante para usted en este momento. Créame. Veamos qué es ésto de la CLI, la temida “interfaz de línea de órdenes”, que también aparece como “símbolo del sistema” o “system prompt” o “línea de comandos” o “pantalla negra” o mil cosas semejantes. En otros tiempos, los hombres se casaban con las mujeres, el precio de los pisos era razonable y se iba uno de vacaciones metiendo doce niños en un seiscientos. Por supuesto no existía el aire acondicionado, ni los elevalunas eléctricos, ni el cierre centralizado. Tampoco era de uso común la “interfaz gráfica de usuario” o GUI (Graphical User Interface) que fue un invento de Xerox para facilitar al operador el manejo de las fotocopiadoras. No, no, Bill Gates no ha inventado nada que se sepa. Y los genios de Xerox ni siquiera imaginaron que su invento sería clave en el mundo de la informática personal. Impresionante. En aquellos felices tiempos, la pantalla era negra como el culo de un grillo, y mostraba veinticuatro o veinticinco líneas de ochenta caracteres cada una, todos verdes, todos del mismo ancho y todos con la misma tipografía. Por supuesto no existían los ordenadores personales o PCs, se usaba un terminal tonto conectado a un ordenador central aún más tonto. En la parte inferior podía aparecer “el rayo de la muerte” que avisaba de que el terminal se había desconectado fatalmente del sistema, o de que éste había fallecido. Como concesión a la modernidad, nos vimos inundados en un momento dado por la anarquía de la negrita, el subrayado y la intermitencia, objeto de múltiples denuncias por incumplimiento de la reglamentación de higiene y seguridad en el trabajo. En la parte alta de la gama apareció la posibilidad de que los caracteres salieran en varios colores.
6
El paradigma de la interfaz de usuario [la shell, que llaman los anglosajones] tenía, ya entonces, más de cien años. Venía a ser el mismo del teletipo, heredado a su vez del telégrafo: • • • • • • • •
El computador manda un breve mensaje al usuario para indicarle que está presto a atender sus requerimientos. El usuario escribe un mensaje con sus instrucciones. Cuando ha terminado de escribir, el usuario pulsa una tecla especial, [Enter] se llama comúnmente. Pulsar esa tecla viene a significar algo parecido a “Ya está. Haz esto que te indico”. El computador recibe el mensaje e intenta descifrarlo. Si lo entiende, realiza las acciones que se solicitan en el mismo. En su caso, el computador manda de vuelta un mensaje al usuario indicando el éxito o fracaso de la operación. Vuelta al primer punto.
El gran inconveniente de esta manera de trabajar es la necesidad de conocer la jerga, es decir, que el usuario tiene que saberse -o llevarse anotadas- las órdenes que la shell puede entender. Y además, las órdenes en Windows no son iguales que las de UNIX. Y además, las órdenes son diferentes en los distintos tipos de UNIX (que si Linux, que si Solaris, que si HP-UX, que si Compaq TRU64 UNIX, que si AIX…) Y además, dentro del mismo UNIX puede haber varias shell diferentes (que si Bourne Shell, que si C Shell, que si bash, que si Korn Shell…) Parece la obra de un loco, pero no lo es. Se trata de la obra de una legión de locos. Los entornos gráficos simplifican la instrucción “copy origen destino” convirtiéndola en el arrastre de un icono con el ratón de una ventana a otra. Más intuitivo, pero a costa de poner más capas de cosas entre las entrañas de la máquina y el usuario. En la pantalla negra, si algo falla será relativamente fácil hacer un diagnóstico. En ambiente gráfico se tiene, en general, más dificultad para saber qué ha ido mal.
7
Si tiene la desgracia de sentarse ante un computador con Windows, el aspecto de su interfaz de mandatos, el “símbolo del sistema”, será como éste:
Si anda entre ferretería de verdad verá una pantalla más parecida a ésta:
En los dos casos hay un mensaje del sistema, el “system prompt”, que indica la disposición del mismo a recibir sus instrucciones. Se puede modificar su comportamiento, pero semejante asunto no es objeto de este mini curso. Si se encuentra suficientemente motivado, en el capítulo siguiente haremos un ejemplo, el típico Hola, Mundo.
8
Hola, Mundo Me he propuesto firmemente evitar que este mini curso de PHP se convierta en contenido para freaks. Soy consciente de que las personas normales usan windows, y solamente la gente excepcional se ha atrevido ya a darle una oportunidad a alguna distribución de Linux. Esto cambiará con el tiempo, pero de momento es lo que hay. Por todo esto, intentaré que no tenga usted que formatear el disco y pasar veintisiete horas instalando nuevo software para seguir con aprovechamiento este curso. Por fortuna, PHP funciona en una multitud de combinaciones diferentes de hardware y software. Y ello sin modificar sustancialmente la sintaxis de lo que se programa. Solamente las cosas que están íntimamente ligadas al sistema se ven afectadas. No es culpa del intérprete de PHP que M$-DO$ y sus ilustres derivados pongan la barra torcida en la dirección equivocada a la hora de nombrar un archivo… \Archivos de Programa\Porno Stars\verselotodo.exe en contraposición al anodino /usr/local/bin/vt de cualquier UNIX que se precie… O sea, que tiene un windows en su computador. Lástima, cobarde. Vuelva usted por aquí con un Ubuntu instalado y luego disfrute de su superioridad intelectual [puede ver con sus propios ojos que, por más que lo intento, me sale solo el rechazo al güindoles] O bien, siga leyendo. Vamos a instalar PHP en este su paupérrimo entorno, lo más seguro es que nadie lo haya hecho por usted, pero conviene dar un vistazo al disco por si acaso. Un buen procedimiento de verificación consiste en buscar archivos cuyo nombre se parezca a “php.exe” en los discos locales. Esto se puede hacer pulsando en el botón “Inicio”, después en “Buscar”, y finalmente en “Archivos y Carpetas”. O, para irse soltando con la pantalla negra, puede ser aventurero y teclear las órdenes “cd \” y “dir /s php*.exe” en la ventana del “símbolo del sistema”. Todo ello sin las comillas, oiga. Si encuentra algo, puede saltarse lo que sigue. En caso contrario, supondremos que no ha tiene un intérprete de PHP en su máquina. Atención: A la menor duda hágase aconsejar por un experto. El autor no se hace responsable de los daños que pueda provocar en su computador o en cualquier otra parte por seguir estas instrucciones, por su falta de destreza en la relación con personas del sexo contrario, o por cualquier otra circunstancia.
9
También asumiremos que dispone de una conexión a Internet decente. Si no la tiene, tendrá que buscar un procedimiento adecuado para conseguir el mismo efecto. Vaya a http://es.php.net/downloads.php y descargue el “PHP Installer MSI” que encontrará entre los “Windows Binaries” de esa página.
Después de un rato cuya duración depende de la pastaza que se gaste en bandas anchas, dispondrá de un flamante archivo de instalación, cuyo nombre termina en MSI.
Si tiene privilegios de administrador en su sistema, bastará un doble clic sobre el archivo MSI una vez descargado. Esto instalará el intérprete de PHP. Si planea seguir completamente el curso necesitará instalar también un servidor web (como Apache) para usar PHP embebido en páginas HTML. Conviene que haga primero la descarga e instalación de Apache para que la configuración sea lo más sencilla posible.
10
Vaya a http://apache.rediris.es/httpd/binaries/win32/ y descargue el binario para Windows. En el momento de escribir éste documento es el archivo llamado “apache_2.2.6-win32-x86-no_ssl.msi”, pero esto cambiará con el tiempo. Instale primero Apache (doble clic en el MSI correspondiente) y después instale PHP. Verifique someramente que dispone de un intérprete operativo, tecleando “php -v” precedido, si es necesario, del PATH apropiado. Cualquier respuesta del estilo “not found” implica que tiene que revisar su instalación. Búsquese un editor apropiado para la ocasión (no vale el Word, la lo he avisado antes) y escriba lo que se muestra a continuación. Guárdelo como hello.php en un directorio de su elección:
11
Como esta pantalla viene de un UNIX, necesitará algo de mente abierta para adaptarse al cambio. No será un problema insalvable, espero. Cuando haya guardado el archivo “hello.php” tendrá que ejecutarlo; no se preocupe, nadie saldrá herido. En UNIX se actúa de éste modo:
Y en windows:
Ya ha escrito su primer guión. Como puede observar, una primera línea contiene algo que parece un comentario pero no lo es; comienza con “#”, sigue un signo de admiración, y luego aparece el nombre de la shell que tiene que ejecutar el guión. Todo esto no es necesario en Windows. Más adelante, el código PHP va encerrado entre los símbolos “<?php” y “?>” casi como si se tratara de una etiqueta HTML. ¿Qué es exactamente lo que hemos echo? Pues, sinceramente, una tontería, pero por algo hay que empezar. La instrucción “echo” de PHP toma todo lo que encuentra a su derecha y lo envía a la salida estándar, que viene a ser la ventana que simula las antiguas pantallas negras de las que hablé al principio. 12
Este guión o script no parece de mucha utilidad, pero complicándolo paulatinamente encontraremos la gracia del asunto. Para ello tenemos que introducir unos cuantos elementos básicos del lenguaje, como son las constantes, las variables y las matrices. En el siguiente capítulo vamos a hacer un paréntesis para repetir el ejemplo, un “hello, world” al estilo web, reutilizando casi todo lo visto aquí.
13
Hola, mundo www Para que vea que sigo fiel a mi intención inicial de no dañar al sufrido lector, voy a salirme por un minuto de la pantalla negra. Con esto mostraré una aplicación práctica de PHP que animará a seguir leyendo. Casi sin cambiar de hábitos, con lo que hemos aprendido en el capítulo anterior podremos desarrollar una aplicación web, es decir, una página web en la que el contenido es dinámico, o séase, que puede cambiar en función de las necesidades. El procedimiento es muy semejante, requiriendo solamente una pequeña adaptación al entorno que no se deriva del lenguaje sino de circunstancias externas al intérprete de PHP. En el mundo de la pantalla negra, para que un usuario vea un texto, se escribe el mismo en la salida estándar (representada por el archivo stdout en los UNIX) y se termina con el carácter “salto de línea”, representado con la secuencia “\n”. Por eso hemos escrito la instrucción: echo "Hola, mundo...\n“;
El comportamiento no es el mismo en el mundo www, que requiere que el o los mensajes se formateen usando el lenguaje HTML. Una forma adecuada de enviar un texto al usuario (que en éste caso empleará un navegador en lugar de un terminal) consiste en encerrarlo entre las etiquetas “<p>” y “</p>”, inicio y final de párrafo respectivamente. Para escribir un texto en ambiente “web”, nuestro script tiene que generar código HTML de éste modo: echo "<p>Hola, mundo…</p>";
14
Podrá usar casi todo lo que veamos a lo largo de éste documento para crear páginas web, siguiendo estos sencillos pasos y adaptándose convenientemente al entorno:
En éste momento estamos editando el archivo “hello.php” que contiene el código fuente de una página web. Copiado a la carpeta adecuada, se convertirá en el código que el servidor web entrega al navegador [el “cliente”] cada vez que éste visita la página. Puede verse cómo se ha insertado el código PHP en el interior del código HTML de la página web, simplemente encerrándolo entre los mismos delimitadores que antes. Como puede verse, en HTML se crea un párrafo escribiéndolo entre las etiquetas “<p>” y “</p>”. El código PHP genera otro párrafo usando la instrucción “echo” (es decir, escribiendo en stdout) con la salvedad de que tiene que generar código HTML válido, para que lo pueda entender el navegador que mostrará el texto.
15
Como acabamos de indicar, tendrá que copiar este archivo al directorio de documentos del servidor web. Si usa Windows estará bajo el directorio de Apache (típicamente “C:\Archivos de Programa\Apache Software Foundation\Apache2.2\htdocs”). Si usa Linux estará, probablemente, en /var/www o en /var/www/html. En ambos casos esto puede cambiar, para encontrar el lugar exacto busque en el disco de su computador un archivo de texto llamado “httpd.conf” y localice la directiva “DocumentRoot” en su contenido. Para ejecutar el guión solamente hay que visitar la página web. Típicamente tendrá que escribir en su navegador una URL como la que se muestra:
Habrá notado que no he puesto tildes. Es para no confundirle. En HTML, para escribir la palabra “guión” hay que poner una cosa tan fea como “gui&oacute;n” y no me parecía oportuno molestar con esto ahora… ya habrá ocasión… En definitiva, puede ver que será capaz de desarrollar aplicaciones con facilidad, tanto para la web como para la pantalla negra (guiones) en cuanto que conozca los trampantojos del lenguaje.
16
Conceptos Básicos Después de un rápido paseo por el entorno, el usuario despierto será capaz de moverse con soltura por las procelosas aguas de la ejecución de guiones escritos en PHP, tanto en modo CLI (Command Line Interface, o pantalla negra) como en www, en el ámbito de un servidor web Apache. El resto de los lectores tendrían que volver a leer –más despacito- la primera parte del curso. O plantearse seriamente invertir su valioso tiempo en algo más productivo. En las siguientes páginas revisaremos las bases fundamentales de cualquier lenguaje de programación, a saber: • • • • • • • • • •
Comentarios: Texto que el intérprete ignora, pero ayuda al lector a entender el código. O le confunde. Constantes: Símbolos que representan un valor (un numero o una palabra) que no cambia. Pista: PI es 3,14159… Variables sencillas: Símbolos a los que sí se puede cambiar el valor en el transcurso de la ejecución del guión. Variables complejas: Símbolos con varios valores. Representan el concepto matemático de “matriz”o “tabla”. Expresiones aritméticas: ¿Área del triángulo? Base por altura partido por dos. Expresiones lógicas: Soy lista AND ingeniosa… OR guapa AND estúpida… OR… Decisiones simples: Si llueve, entonces no salgo a la calle. En caso contrario me voy de fiesta. Decisiones múltiples: El importe de la multa se calcula mediante tramos de velocidad. De 160 a 190, mil euros. Repeticiones: Hazme caricias mil veces. O un número indeterminado de veces, hasta que se haga de noche. O más. Funciones: En el contexto algebraico del y=f(x). Cobrarás un bono que depende del número de programas que hagas. Así, bono = f ( ls -l *.php )
Sin más dilatación, vayamos al tema.
17
Comentarios Siempre se agradecen los comentarios. Y más cuando hay que meter la mano en algo que ha desarrollado otro, a su manera y con sus manías. Si ha dejado alguna pista, como hizo pulgarcito con las migas de pan, llegaremos al destino sanos y salvos, que es de lo que se trata. Es necesario hacer saber al intérprete que hemos escrito cosas que no queremos que se ejecuten. Para ello tenemos dos medios: el comentario en una línea, que es cualquier cosa que se escriba después de dos barras seguidas, que pueden estar al principio de la línea… // El intérprete va a ignorar este texto.
… o después de una instrucción ejecutable. echo “Hola”; // Esto es un saludo, y lo demás son tonterías
El otro tipo de comentario está delimitado por las secuencias /* y */ pudiendo ocupar una línea… /* El intérprete va a ignorar este texto. */
o varias: /* Programar en PHP con soltura te convierte en un ser superior */
Es importante cerciorarse de que no se está anidando un comentario dentro de otro.
18
Constantes Son elementos de datos, con nombre y valor asignado. Son “constantes predefinidas” si el valor es asignado por el propio intérprete, o “constantes de usuario” si se asigna en algún punto del programa. En las del segundo tipo no puede cambiarse el valor una vez asignado. Evidentemente, las primeras tienen un valor previamente establecido que tampoco se puede modificar. <?php echo “Constantes”; echo “Elementos de datos cuyo contenido no se puede « cambiar.\n”; define( “DEPRIMERO”, “patatas bravas” ); define( “DESEGUNDO”, “calamares en su tinta” ); echo “De primer plato quiero ” . DEPRIMERO . “\n”; echo “y de segundo, ” . DESEGUNDO . “\n”; ?>
En este guión se anticipa la sintaxis de la concatenación de cadenas de texto. Para unir cadenas se usa el carácter “punto”. Anticiparemos también, aunque se explicará más adelante, la forma de ver todas las constantes definidas:
<?php echo “Constantes definidas”; foreach( get_defined_constants( ) as $name => $value ) echo $name . “ = ‘” . $value . “‘\n”; ?>
Se llama a una función que el intérprete de PHP tiene predefinida (get_defined_constants) y que devuelve como resultado una matriz. Un bucle foreach recorre esa matriz elemento a elemento.
19
Y -para los amantes de la matemática- se dispone de unas constantes predefinidas muy valiosas: M_E = ‘2.718281828459 M_LOG2E = ‘1.442695040889 M_LOG10E = ‘0.43429448190325 M_LN2 = ‘0.69314718055995 M_LN10 = ‘2.302585092994 M_PI = ‘3.1415926535898 M_PI_2 = ‘1.5707963267949 M_PI_4 = ‘0.78539816339745 M_1_PI = ‘0.31830988618379 M_2_PI = ‘0.63661977236758 M_SQRTPI = ‘1.7724538509055 M_2_SQRTPI = ‘1.1283791670955 M_LNPI = ‘1.1447298858494 M_EULER = ‘0.57721566490153 M_SQRT2 = ‘1.4142135623731 M_SQRT1_2 = ‘0.70710678118655 M_SQRT3 = ‘1.7320508075689
Dos constantes serán de especial relevancia durante todo el curso. Son TRUE y FALSE, y sirven, como puede imaginar, para simbolizar el hecho de que algo es verdadero o falso.
20
Variables sencillas Las variables son imprescindibles en cualquier lenguaje. Permiten almacenar un contenido numérico o alfanumérico. El programador asigna un nombre a cada variable, haciendo referencia a ella por ese nombre. Su vigencia es temporal. Mantienen su valor durante la ejecución del script, y al terminar ésta desaparecen. No se guarda el valor entre dos ejecuciones del mismo script. Si se precisa guardar un dato de manera permanente, ha de almacenarse en un archivo o en una base de datos. En PHP se distinguen las variables por el hecho de que su nombre siempre empieza con el signo del dólar, “$”. No se permite la existencia en un mismo script de dos variables con igual nombre en el mismo contexto. Para crear una variable basta con asignar un valor mediante la instrucción de asignación: $base = 198;
Si el valor es alfanumérico se encierra entre comillas, que pueden ser simples o dobles, con la condición de que se termine el literal con el mismo tipo de comilla que se usó para iniciarlo: $nombre = “Claudia”; $apellido = “Schiffer”; $muymal = “Esto no va a funcionar porque empieza con « comillas dobles y termina con comillas simples’;
Pronto veremos que es posible combinar unas variables con otras para realizar operaciones matemáticas, crear cadenas de caracteres más complejas, etc. Un anticipo: $area = $base * $altura / 2; $mensaje = “La modelo se llama $nombre y se « apellida $apellido”;
Además de las variables simples, disponemos de poderosísimas variables complejas o múltiples, también llamadas tablas o arrays.
21
Variables múltiples Ya se ha explicado cómo se almacena un valor en una variable. Ahora se detallará cómo crear un array (o matriz, o tabla, que de todas esas formas se denomina) en el que un mismo nombre de variable sirve para albergar varios valores. Para crear un array es necesario -contrariamente a lo que ocurre con las variables simples- crearlo de manera explícita llamando a la función “array”. La forma más sencilla es ésta: $nombre = array( );
Los diferentes valores se distinguen mediante un índice que se añade entre corchetes al final del nombre: $nombre[ 1 ] = “Pepe”; $nombre[ 2 ] = “Juan”; $nombre[ 3 ] = “Antonio”;
También se puede asignar una serie de valores en el momento de la creación del array: $nombre = array( “Pepe”, “Juan”, “Antonio” );
Al asignar los valores de éste modo se crea automáticamente el primer índice con el valor cero. De éste modo, la instrucción anterior sería equivalente a: $nombre[ 0 ] = “Pepe”; $nombre[ 1 ] = “Juan”; $nombre[ 2 ] = “Antonio”;
22
Hasta ahora se ha expresado el índice literalmente, pero es perfectamente posible usar una variable como índice y acceder al elemento correspondiente a su valor. $i = 2; echo $nombre[ $i ];
Otro uso tremendamente potente consiste en usar índices no numéricos, construyendo un array asociativo: $elemento[ “Ag” ] = “Plata”; $elemento[ “Au” ] = “Oro”; $elemento[ “Cl” ] = “Cloro”;
Esto equivale a una asignación con este formato: $elemento = array( « “Ag” => “Plata”, « “Au” => “Oro”, « “Cl” => “Cloro” );
Por este procedimiento se puede, si es necesario, forzar la asignación de índices empezando en “uno” en lugar de en “cero” en el ejemplo del principio:
$nombre = array( 1 =>“Pepe”, 2 =>“Juan”, 3 => “Antonio” );
23
Es posible definir arrays de más de una dimensión, simplemente anidando la llamada a “array” en su creación. El siguiente ejemplo muestra una casa de vecinos, en la que cada línea es un piso. Si no se indica nada, los pisos empiezan en “cero” y las puertas también. En el piso cero, puerta cero, vive Pepe. En el piso dos, puerta dos, vive Ana. #!/usr/bin/php <? $vecino = array( array( “Pepe” , “Juan” , “Antonio” ), array( “Marta” , “Marilia”, “Nadie” ), array( “Josema”, “Millan” , “Ana” ) ); echo $vecino[ 1 ][ 1 ]; ?>
Para hacerlo más similar a la realidad, podemos rehacer el ejemplo poniendo nombres significativos a los índices: #!/usr/bin/php <? $vecino = array( “Primero” => array( “A” => “Pepe”, “B” => “Juan”, “C” => “Antonio” ), “Segundo” => array( “A” => “Marta”, “B” => “Marilia”, “C” => “Nadie” ), “Tercero” => array( “A” => “Josema”, “B”=> “Millan”, “C” => “Ana” ) ); echo $vecino[ “Segundo” ][ “B” ]; ?>
En los dos casos el resultado es “Marilia”.
24
Decisión simple Ha llegado el momento de acabar con la lógica aburridamente lineal que se ha mostrado hasta ahora. El intérprete del lenguaje PHP, como casi todos los demás intérpretes y compiladores, toma el código fuente y ejecuta las instrucciones de una en una, empezando por la primera y hasta encontrar el final. Este anodino comportamiento se puede modificar de varios modos. El primero que se discutirá es la decisión simple, que permite saltarse una o varias instrucciones dependiendo de que una expresión devuelva “cierto” o “falso”. La instrucción que permite implementar una decisión es “if”, y se complementa con su opositor “else”. Un ejemplo: #!/usr/bin/php <? $grande = 1000; $chico = 10; if( $grande > $chico ) echo "Evidente. $grande es mayor que $chico.\n"; else echo "Raro. $chico es mayor que $grande.\n"; ?>
En este caso tan sencillo, la instrucción que sigue a “else” nunca se ejecutará. Pero suponga que los valores de las variables se obtienen de un modo distinto de la asignación “a fuego” en el programa. No podríamos saber a priori qué parte del código se ejecutaría. Puede definir un bloque de instrucciones encerrándolas entre llaves. El efecto de esta acción es extremo. En principio, si se ejecuta una instrucción del bloque se ejecutan todas. $velocidad = 82; if( $velocidad <= 90 ) { echo "Se mantiene dentro del límite de velocidad.\n”; echo "Puede seguir circulando.\n"; } else { echo "Deténgase, insensato.\n"; echo "Multa de 100 euros, y dos puntos menos.\n";
}
25
Todo el código que aparece tras la instrucción “else” es opcional, y puede omitirse si la lógica del proceso lo permite. Finalmente, los bloques de instrucciones “if/else” pueden anidarse unos dentro de otros, dando lugar a bonitos fragmentos de código inescrutable. Tenga piedad de aquellos que tendrán que modificar el código que usted escriba, y trate de mantener sencillo el programa siempre que pueda. Método KISS: “Keep It Simple, Stupid”
26
Decisiones múltiples La sentencia switch equivale a una cascada de sentencias if/else debidamente concatenadas. Sirve para ejecutar unos y otros bloques de código en función de la evaluación de una expresión, que ha de devolver un entero. Observe cómo la instrucción “break” evita que se siga ejecutando en secuencia una vez encontrado el bloque adecuado: <?php echo "Decisión múltiple...\n"; $velocidad = 47; switch( $velocidad ) { case 0: echo "Parado...\n"; break; case 50: echo "Lento pero seguro...\n"; break; case 90: echo "En los límites de la ley.\n”; echo “Atento a las señales...\n"; break; default: echo "Soy torpe, no sé a qué velocidad « va...\n"; echo "Multa por si acaso.\n"; $puntos ‐= 6; } echo "Le quedan $puntos puntos.\n"; ?>
27
He puesto deliberadamente un mal ejemplo para que vea cómo esta estructura se adapta mejor a unos procesos que a otros. Si tiene que comprobar intervalos, le propongo una versión un poquito más complicada pero mucho más potente: <?php
echo "Decisión múltiple...\n"; $velocidad = 47; $puntos = 12; switch( TRUE ) { case ( $velocidad > 0 and $velocidad <= 60 ): echo "Lentoooo...\n"; break; case ( $velocidad > 60 and $velocidad <= 90 ): echo "En los límites de lo razonable...\n"; break; case ( $velocidad > 90 and $velocidad <= 120 ): echo "En los límites de la ley.\n”; echo “Atento a las señales...\n"; break; default: echo "Multa y pérdida de seis puntos...\n"; $puntos ‐= 6; } echo "Le quedan $puntos puntos.\n";
?>
28
Repeticiones Si ya conoce otros lenguajes de programación, no encontrará muchas cosas diferentes aquí. Es evidente que la salsa de la programación consiste en ahorrar esfuerzos programando la solución a un problema de manera que se pueda usar de manera reiterativa. Imaginemos que un banco quiere regalar un millón de euros a cada uno de sus clientes. Soñar es gratis. Imaginemos también que hemos conseguido que los datos de todos los clientes estén accesibles en un array en la memoria del script… [ojo, esta no es una buena práctica en el mundo real… salvo que su banco tenga unos cientos de clientes y no unos millones de ellos…] <?php $cliente[0][”saldo”] += 1000000; echo “Aumentado el saldo de ” . $cliente[0][”nombre”] . ” en un millón.\n”; $cliente[1][”saldo”] += 1000000; echo “Aumentado el saldo de ” . $cliente[1][”nombre”] . ” en un millón.\n”; $cliente[2][”saldo”] += 1000000; echo “Aumentado el saldo de ” . $cliente[2][”nombre”] . ” en un millón.\n”; ?>
Ya puede usted intuir que mediante un gesto reiterativo de copiar y pegar podría hacer un hermoso programa de tamaño colosal siguiendo este procedimiento. Pero no es práctico. En el capítulo de arrays se apuntó la posibilidad de usar una variable como índice para acceder a los diferentes elementos del array. Esto, combinado con el bucle “for”, se convierte en la herramienta definitiva: <?php for( $i = 0; $i < 99; $i ++ ) { $cliente[$i][”saldo”] += 1000000; echo “Aumentado el saldo de ” « . $cliente[$i][”nombre”] . “\n”; } ?>
29
¿Cómo se interpreta esto? Muy fácil. La instrucción “for” va acompañada de tres expresiones entre paréntesis, separadas por el carácter “punto y coma”. La primera se evalúa antes de hacer la primera repetición. La segunda fuerza la salida del bucle cuando su evaluación devuelve “cierto”. La tercera se evalúa al final de cada vuelta. Por tanto, se repite todo el bloque de instrucciones entre llaves. En la primera repetición la variable $i toma valor cero. En cada repetición sucesiva, se incrementa el valor de $i tal y como se indica en la tercera expresión, en este caso se suma una unidad por cada vuelta. Cuando el valor de $i supere 99, se abandona el bucle. Por simplicidad, hemos asumido que el array tiene 99 elementos, cosa que no es deseable en términos de negocio, ni previsible en términos de programación. Cuando veamos las funciones, encontraremos muy útil una que devuelve el número de elementos que tiene un array. Se llama “count( )” y se usará profusamente más adelante. Si quiere ejecutar éste script cambie el 99 por la llamada count( $cliente ) o refleje el número real de elementos del array para que todo funcione adecuadamente. Tenga también en cuenta que necesitará crear un array de clientes y llenarlo de datos. Ponga al principio del script algo parecido a esto: $cliente= array( array( "nombre" => "José Pérez", "saldo" => 1900 ), array( "nombre" => "John Smith", "saldo" => 2901 ), array( "nombre" => "Pepe Pardo", "saldo" => 36777 ), array( "nombre" => "Juan March", "saldo" => 81911 ), array( "nombre" => "Jim Clarke", "saldo" => 100 ), array( "nombre" => "Antonio Pi", "saldo" => 19 )
);
Con “while” también se puede realizar un bucle, en la línea de los habituales en otros lenguajes de programación. En éste caso no hay manejo automático de índices, pero nadie impide al programador su libre manejo. Por ejemplo: $i = 0; while( $i < 6 ) { $cliente[$i]["saldo"] += 1000000; echo "Aumentado saldo de " . $cliente[$i]["nombre"] . "\n"; $i ++; } echo "Procesados $i clientes.\n";
30
Se supone que ha creado, como antes, un array de clientes tal y como se indicó antes. También es posible comprobar la condición al final usando “do/while”: $i = 0; do { $cliente[$i]["saldo"] += 1000000; echo "Aumentado el saldo de " . $cliente[$i]["nombre"] . "\n"; $i ++; } while( $i < 6 ); echo "Procesados $i clientes.\n";
Es posible abandonar el bucle en un momento dado mediante la instrucción “leave”, y evitar la ejecución de una parte de una iteración, volviendo arriba a ejecutar la siguiente mediante la instrucción “continue”. Supongamos que solamente se desea regalar el millón de euros a los clientes ricos: $i = 0; do { echo "Procesando el cliente " . $cliente[$i]["nombre"] . "\n"; if( $cliente[$i]["saldo"] < 50000 ) { $i ++; continue; } $cliente[$i]["saldo"] += 1000000; echo "\tAumentado el saldo de " . $cliente[$i]["nombre"] . "\n"; $i ++; } while( $i < 6 ); echo "Procesados $i clientes.\n";
Tenga cuidado para no crear un bucle infinito… particularmente, observe que antes de “continue” nos hemos asegurado con “$i ++” de que la vuelta prematura al principio procesará el siguiente cliente.
31
Finalmente, veamos el uso de la instrucción “foreach” combinado con el array para obtener los mismos resultados con una sintaxis más elegante. foreach( $cliente as $i => $dato ) { echo "Procesando el cliente $i\n"; $dato["saldo"] += 1000000; echo "Aumentado el saldo de " . $dato["nombre"] . "\n"; }
Como puede observar, con la sintaxis “$array as $clave => $valor” se accede a cada elemento del array. Tenga en cuenta que el uso de la clave es opcional, es válido “$array as $valor” omitiendo la clave. En el ejemplo, cada elemento del array principal es a su vez otro array, lo que nos permitiría anidar un segundo “foreach” para rematar la fiesta en términos de máxima elegancia, rayando la metrosexualidad: echo "Contenido del array...\n"; foreach( $cliente as $indice => $fila ) { echo "$indice: "; foreach( $fila as $titulo => $celda ) { echo "\t$titulo: $celda"; } echo "\n"; }
32
Funciones Con éste capítulo podemos dar por completa la visión somera de los conceptos básicos de PHP como lenguaje de procedimientos. Por supuesto, hay muchas más cuestiones -más o menos básicas- que visitar, sobre todo si tenemos en cuenta que PHP dispone de una poderosa capacidad de orientación a objetos. Para no perdernos, veamos brevemente el concepto de “función” que refleja nuevamente las casi olvidadas explicaciones del bachillerato. En una función se realiza un cálculo que puede depender de uno o varios parámetros suministrados. El resultado sustituye a todos los efectos a la propia llamada a la función dentro de una expresión. <?php function areatriangulo( $b, $h ) { $a = $b * $h / 2; return $a; } $base = 4; $altura = 6; $area = areatriangulo( $base, $altura ); echo "El área de un triángulo\n"; echo " de base $base y altura $altura es: $area.\n”; ?>
La definición de la función está arriba, y en la expresión “$area = …” aparece una llamada a esa función. Cuando la ejecución alcanza el punto en el que se llama a la función, se toman los valores de las variables entre paréntesis: $base y $altura, en este caso. Se copian a las variables que hacen de parámetro en la definición. En este caso, el valor de $base se copia a $b, y el de $altura a $h. Se ejecuta el código y el valor resultante de la expresión que acompaña a “return” se deposita en la variable que está a la izquierda de la igualdad en la llamada. PHP dispone de un trillón de funciones predefinidas, que facilitan la labor del programador y expanden el lenguaje hasta límites insospechados. En un mini curso de éste tamaño es imposible citar siquiera una pequeña parte de ellas. A título de mero ejemplo, trabajaremos un poco con tres tipos. Las funciones matemáticas, las que sirven para manejar fechas y horas, y las que procesan cadenas de caracteres.
33
Funciones matemáticas. Las más sobresalientes son las siguientes: • • • • • • • • • • • • •
Trigonométricas: sin, cos, tan, asin, acos, atan. Hiperbólicas: sinh, cosh, tanh, asinh, acosh, atanh. Conversión de base arbitraria: base_convert. De base 10 a otras: dechex, decbin, decoct. De binario, hexadecimal y octal a base 10: bindec, hexdec, octdec. Conversión de grados a radianes y viceversa: deg2rad, rad2deg. De redondeo: abs, ceil, floor, round. Logarítmicas: exp, expm1, log, log10, log1p. Potencias: pow. Aleatorios: getrandmax, rand, srand, mt_getrandmax, mt_rand, mt_srand. Máximos y mínimos: max, min. Raíces cuadradas: sqrt. Comprobación: is_finite, is_infinite, is_nan.
Ejemplo: Obtener seis números al azar comprendidos entre 1 y 49, muy apropiado para rellenar la primitiva y hacerse inmensamente rico: <?php ?>
for( $i = 0; $i < 6; $i ++ ) { $aleatorio = rand( 1, 49 ); echo "Número $i es $aleatorio.\n"; }
Lamentablemente, esta versión tan corta no garantiza que los seis números obtenidos sean diferentes entre sí.
34
Funciones de fecha y hora. Se dispone, entre otras, de las siguientes: • •
Obtención de la fecha y hora actual: getdate, gettime, gettimeofday. Dar formato a una fecha/hora: date, time.
Ejemplo: Obtener la fecha y hora en un formato legible. <?php echo date( "l dS F Y h:i:s A" ); // Aparece "Monday 22nd October 2007 01:48:34 PM" ?>
Carácter Día d D J l N S w z Semana W Mes F m M n t Año L o Y y Hora a A B g G h
Descripción
Valor devuelto
Día del mes, 2 dígitos con ceros iniciales Representación del día en texto, tres letras Día del mes sin ceros iniciales (L minúscula) Texto del día de la semana Día de la semana ISO-8601 (1=Lunes…) Sufijo en inglés del día del mes, usar con j Día de la semana (0=Domingo, 6=Sábado) Día del año, comenzando en cero
01 a 31 Mon a Sun 1 a 31 Sunday a Saturday 1a7 St, nd, rd, th 0a6 0 a 365
Número de la semana (comienza en lunes)
1 a 52, aprox.
Texto completo del mes Número del mes, con cero inicial Texto corto del mes, tres letras Número del mes, sin cero inicial Número de días del mes dado
January a December 01 a 12 Jan a Dec 1 a 12 28 a 31
Indicador de año bisiesto (0=no, 1=si) Año del nº de semana actual Número del año en cuatro dígitos Número del año en dos dígitos
0a1 2007 2008 08
Ante y post meridiano en minúsculas Ante y post meridiano en mayúsculas Hora swatch Internet Hora en formato 12 horas sin ceros iniciales Hora en formato 24 horas sin ceros iniciales Hora en formato 12 horas con ceros iniciales
am o pm AM o PM 000 a 999 1 a 12 0 a 23 01 a 12 35
H Hora en formato 24 horas con ceros iniciales i Minutos con ceros iniciales S Segundos con ceros iniciales u Milisegundos Zona horaria e Identificador de zona horaria I Indicador de DST (0=no, 1=si) O Diferencia con GMT en horas P Diferencia con GMT en horas con “:” T Abreviatura de zona horaria Z Desplazam. de la zona horaria en segundos Fecha/Hora completa c Fecha ISO-8601 r
Fecha en formato RFC 2822
U
Seg. de Epoch Unix (1/Ene/1970 0:00h GMT)
00 a 23 00 a 59 00 a 59 P. ej.: 54321 UTC, GMT, Atlantic/... 0a1 Ej: +0200 Ej: +02:00 Ej: EST, MDT… -43200 a 50400 2004-0212T15:19:21+00:00 Thu, 21 Dec 2000 16:01:07 +0200
36
Funciones de cadenas. Hay una miriada de ellas, con sintaxis semejante a la del lenguaje C. Destacan: • • • • • • • • • •
Obtener la longitud de una cadena: strlen. Obtener un trozo de una cadena: strstr, substr. Convertir mayúsculas/minúsculas: strtolower, strtoupper, ucfirst, ucwords. Comparar cadenas: strcmp. Encontrar en una cadena: strpos. Dividir en elementos: strtok, str_split, join, split. Eliminar espacios: trim, ltrim, rtrim. Formatear: number_format, money_format. Comprobaciones: md5, crc32. Manejo de juego de caracteres: chr, ord.
Ejemplo: <?php $texto = "La bella y graciosa moza marchóse a lavar la ropa"; $longitud = strlen( $texto ); echo "La longitud de la cadena: $longitud\n"; $diezprim = substr( $texto, 1, 10 ); echo "Los diez primeros caracteres: '$diezprim'\n"; $hastafin = substr( $texto, 20 ); echo "Desde el veinte hasta el final: '$hastafin'\n"; $ultimo = substr( $texto, ‐1, 1 ); echo "Ojo al truco, último carácter: '$ultimo'\n"; $catorce = $texto{14}; echo "Otro truco, carácter 14: '$catorce'\n"; $i = 15; $quince = $texto{$i}; echo "Lo mismo con variable: '$quince'\n"; $inicio = ‐10; $longitud = ‐3; $finmenos3 = substr( $texto, $inicio, $longitud ); echo "Diez finales, menos los tres últimos: « '$finmenos3'\n"; ?>
37
Otro ejemplo, divide una cadena en palabras. Observe las novedades, como el uso de “printf” igual que en C, y el incremento de la variable $i “al vuelo”. La primera llamada a strtok define el objetivo, la cadena sobre la que se va a operar. Las llamadas sucesivas operan sobre esa misma cadena siempre que no haya una nueva variable objetivo: <?php $texto = "La bella y graciosa moza marchose a lavar la ropa"; $i = 1; $token = strtok( $texto, ” ” ); while( $token !== FALSE ) { printf( “Palabra %d = ‘%s’\n”, $i ++, $token ); $token = strtok( ” \t\n” ); } ?>
Otro, convirtiendo cadenas en arrays y viceversa: <?php $raciones = array( "Calamares", "Chopitos", "Jamón", "Queso", "Lomo", "Gambas plancha", "Gambas cocidas" ); $pegamento = ", "; echo "Tenemos " . join( $raciones, $pegamento ) . “.\n”; $texto = “Cilindro Carburador Cigüeñal Pistón Bulón Segmento”; $piezas = explode( " ", $texto ); foreach( $piezas as $indice => $valor ) { echo “La número $indice es $valor.\n”; } ?>
38