1 Introducci[oacute]n#$+
K
Antes de comenzar se van a repasar algunos de los conceptos vistos ya en la serie, pero que refrescar[aacute]n la memoria al lector adem[aacute]s de introducir algunos conceptos nuevos.
Desde que la la WWW decidi[oacute] que quer[iacute]a ser m[aacute]s interactiva (hace ya unos cuantos a[ntilde]os) y dejar de limitarse a ofrecer contenidos est[aacute]ticos, han surgido muchas soluciones que permiten al usuario interactuar con el sistema. Estas soluciones se pueden separar claramente en dos tipos; soluciones ejecutadas en el cliente y soluciones ejecutadas en el servidor. Las primeras (Javascript, VBscript, applets etc.) fueron un avance considerable en la creaci[oacute]n de lugares Web; pero la mayor[iacute]a de las aplicaciones serias donde hay un flujo de informaci[oacute]n importante no se pueden gestionar de esta manera.
Por eso hace mucho que existen los CGI scripts, de amplio uso sobre todo en p[aacute]ginas de servidor que ofrecen alg[uacute]n tipo de servicio en el que no se puede delegar el control al ordenador del cliente; bien por motivos de seguridad, o bien por razones de eficiencia. Pongamos un ejemplo: si queremos que un usuario extraiga una informaci[oacute]n de nuestra base de datos no podemos pasarle la base de datos al usuario para que el pueda hacer la consulta. Ser[iacute]a demasiado costoso en ancho de banda, y es probable que no queramos que acceda a toda la informaci[oacute]n (ni siquiera que la tenga).

2 CGI scripts.#$+
KLa soluci[oacute]n que surge entonces es utilizar un programa que puede intercambiar datos con el usuario a trav[eacute]s de la WWW, ejecutado en nuestro servidor y que por lo tanto corre en un entorno seguro y que conocemos. Esos programas pod[iacute]an estar escritos y funcionando en pr[aacute]cticamente cualquier sistema o lenguaje de programaci[oacute]n.
Nuestro script t[iacute]pico tomar[iacute]a los datos que se le han proporcionado, y realizar[iacute]a alguna acci[oacute]n, devolviendo como resultado una p[aacute]gina www que podr[iacute]a ser distinta dependiendo de los datos o del resultado del proceso en nuestra m[aacute]quina. Esto significa interactividad con control en el servidor. Lo [uacute]nico que controla el usuario son los datos que manda (esto tambi[eacute]n puede resultar un agujero de seguridad, pero ya hablaremos de ello m[aacute]s adelante).
Hasta hace relativamente poco, la soluci[oacute]n m[aacute]s accesible (y la que probablemente siga siendo la m[aacute]s adoptada) es usar Perl para procesar los datos y construir una p[aacute]gina que se le pueda devolver al usuario.
Perl es un lenguaje interpretado que posee unas caracter[iacute]sticas particularmente beneficiosas a la hora de escribir programas de este tipo, ya que fue inicialmente concebido como una herramienta de proceso de informes y muestra un comportamiento excelente en el proceso de datos de cualquier tipo. De hecho, PERL es el acr[oacute]nimo de Practical Extraction and Report Language, es decir, lenguaje de programaci[oacute]n pr[aacute]ctico para extracci[oacute]n y generaci[oacute]n de informes. Adem[aacute]s Perl es completamente libre y hay desarrolladas una cantidad muy importante de librer[iacute]as de funciones que implementan casi todas las funciones que uno pueda necesitar.  Pero en este punto surgen varios problemas:
· Cada vez que el script se tiene que ejecutar ha de iniciarse el int[eacute]rprete de Perl, lo cual resulta en una sobrecarga inicial no despreciable. Esto limita nuestro uso del script: s[oacute]lo podremos utilizarlo en m[aacute]quinas potentes o en sistemas que sepamos que van a tener pocos usuarios simult[aacute]neos. 
· El script que programemos ha de generar la p[aacute]gina [iacute]ntegramente. Es decir, que tenemos que programar nuestro script para que el documento resultante tenga etiquetas como [lt    ]html[gt    ], [lt    ]head[gt    ], [lt    ]body[gt    ] etc, y en el orden adecuado. Esto tiene repercusiones importantes a la hora del dise[ntilde]o de webs grandes, en los que el mantenimiento del estilo y las plantillas no resulta un problema trivial.
2.1 Las alternativas.#K
Como respuesta a estos problemas han surgido varios sistemas, algunos de ellos dependientes de plataforma, que alivian de alg[uacute]n modo las pesadillas de los webmasters y de los administradores.
· PHP/ASP.  Ahora mismo es el tipo de soluci[oacute]n m[aacute]s popular. El concepto es sencillo: dentro de las propias p[aacute]ginas html se incluyen unas directivas escritas en un lenguaje especial que se ejecuta en el servidor (accesos a bases de datos, bucles etc). PHP por supuesto tiene la ventaja de que es libre y que est[aacute] disponible para casi todas las plataformas y sistemas operativos, a diferencia de las Active Server Pages de Microsoft. 
· Servlets. Son programas ejecutados en el lado del servidor que pueden correr scripts en lenguajes como Java (Java Servlets) aunque ahora es posible utilizar otros lenguajes interpretados como Python etc... 
2.2 La soluci[oacute]n elegida#K
Perl Embebido es un m[oacute]dulo de extensi[oacute]n de Perl que nos va a permitir la m[aacute]xima interactividad posible desde el servidor usando Perl como lenguaje de programaci[oacute]n.
Perl Embebido supera nuestras dos dificultades principales del siguiente modo:
· En primer lugar se ejecuta bajo mod[lowbar]perl (aunque tambi[eacute]n puede ejecutarse al estilo de los antiguos CGI's). Mod[lowbar]perl es un m[oacute]dulo de Apache que introduce el int[eacute]rprete de Perl dentro del mismo servidor Web y que optimiza la ejecuci[oacute]n de aplicaciones escritas en este lenguaje, evitando la sobrecarga de inicializaci[oacute]n antes mencionada y logrando un rendimiento muy superior al de otras alternativas. 
· En segundo lugar y tal como reza el nombre, Perl embebido permite incluir c[oacute]digo Perl directamente dentro de las p[aacute]ginas web. Esto no s[oacute]lo resulta c[oacute]modo para el programador sino que permite la integraci[oacute]n con otras herramientas que el estilo Perl-CGI antiguo no nos permit[iacute]a, como por ejemplo con Website Meta Language. 
Principales ventajas de Perl Embebido.K

Es conveniente destacar algunas de las principales ventajas a la hora de utilizar Perl como elemento de acceso a la base de datos, algunas particulares del lenguaje de programaci[oacute]n en s[iacute] y otras particulares de la forma de introducir Perl en servidores WWW:
· Perl es un lenguaje flexible, potente, maduro y muy r[aacute]pido a la hora de escribir c[oacute]digo.          
· Existe una tremenda cantidad de m[oacute]dulos bien documentados que podemos usar dentro de nuestro c[oacute]digo y que nos permiten construir de forma sencilla aplicaciones web que hagan casi cualquier cosa (Ej: Acceso a bases de datos independiente de la implementaci[oacute]n de SQL, creaci[oacute]n autom[aacute]tica de im[aacute]genes, operaci[oacute]n sobre el sistema operativo...). Y toda esta funcionalidad se puede explotar con Perl embebido desde una p[aacute]gina Web.          
· La ejecuci[oacute]n sobre mod[lowbar]perl es muy veloz. Varias pruebas han revelado que es muchas veces m[aacute]s r[aacute]pida que la de CGI's convencionales.          
· Todo el software que es necesario para hacer funcionar mod[lowbar]perl es libre y est[aacute] bien documentado. Adem[aacute]s algunas distribuciones lo incluyen empaquetado y pr[aacute]cticamente listo para usar.          
· mod[lowbar]perl Incluye algunas facilidades propias para manejar aspectos particulares de la programaci[oacute]n web que resultan muy [uacute]tiles (datos de formularios, manejo de la sesi[oacute]n, etc).
Quiz[aacute]s la ventaja m[aacute]s importante es que no es necesario aprender un lenguaje de programaci[oacute]n que sirva para una [uacute]nica aplicaci[oacute]n. Perl es multiprop[oacute]sito y tremendamente [uacute]til en otros campos de utilizaci[oacute]n. 
DesventajasK

Sin embargo Perl embedido no est[aacute] exento de desventajas, puede resultar, a priori, un poco m[aacute]s dif[iacute]cil de utilizar que sus rivales. Adem[aacute]s, el lenguaje de programaci[oacute]n Perl puede ser bastante dif[iacute]cil de leer (y por tanto mantener) si no se ha documentado lo suficiente. La premisa de Perl de poder realizar la misma cosa de muchas maneras distintas puede llevar a que el mantenimiento del c[oacute]digo por parte de otro programador sea dificultosa si las cosas no se han hecho de manera ordenada.

3 Puesta en funcionamiento y configuraci[oacute]n.#$+
K
Antes de explicar c[oacute]mo se instala y configura es necesario introducir los elementos que van a entrar en juego para la instalaci[oacute]n.
· Apache: Es el servidor web libre m[aacute]s avanzado y el m[aacute]s usado en Internet. Implementa un sistema de m[oacute]dulos con los cuales se pueden a[ntilde]adir funcionalidades al servidor. 
· Mod[lowbar]perl: Es un m[oacute]dulo de Apache que permite la ejecuci[oacute]n eficiente de programas escritos en Perl. 
· Perl: Es el int[eacute]rprete de Perl, con el cual podemos ejecutar scripts escritos en el lenguaje del mismo nombre. 
· DBI: Es un m[oacute]dulo (una biblioteca de funciones) de Perl que nos permitir[aacute] el acceso a bases de datos de forma uniforme e independiente de la base a la que estemos accediendo (Postgres, Oracle, Informix, Interbase etc.) 
· Postgresql: Es el sistema de base de datos libre m[aacute]s avanzado. La utilizaremos como ejemplo del acceso a bases de datos desde Perl Embebido. 
· DBD::Pg: Es el m[oacute]dulo que usa DBI para acceder a funciones de Posgresql, que es la base de datos con la que implementamos nuestros ejemplos. En caso de utilizar otras bases de datos, tendremos que utilizar un [quot  ]driver[quot  ] distinto (Ej: DBD::Mysql). 

4 Instalaci[oacute]n#$+
K
En primer lugar, para poder hacer nuestras pruebas necesitamos tener un servidor Apache funcionando. La descripci[oacute]n de la instalaci[oacute]n de Apache queda fuera de la intenci[oacute]n de este art[iacute]culo, pero tampoco es un tema excesivamente complicado, sobre todo si se usa alguna distribuci[oacute]n como Debian o Red Hat. Para saber si tenemos un servidor Apache funcionando podemos probar en un navegador cualquiera que est[eacute] en nuestra m[aacute]quina a acceder a la direcci[oacute]n http://localhost/. Si no hab[iacute]amos introducido anteriormente ninguna p[aacute]gina y tenemos nuestro servidor activo, deber[iacute]amos ver una p[aacute]gina de bienvenida de Apache.
Perl tambi[eacute]n debe estar instalado en nuestra m[aacute]quina. Al igual que en el caso de Apache, existe amplia documentaci[oacute]n sobre este proceso, y la mayor[iacute]a de las veces es extremadamente sencillo.
Una vez que tenemos estos dos elementos instalados pasamos a la instalaci[oacute]n de mod[lowbar]perl. Como siempre, si utilizamos una buena distribuci[oacute]n este proceso resultar[aacute] sencill[iacute]simo, tanto como pedirle al sistema que instale el paquete correspondiente a mod-perl (en Debian se trata del paquete libapache-mod-perl).
Una vez que tenemos el fichero hay que decirle a Apache que lo utilice.  El fichero de configuraci[oacute]n de apache [quot  ]httpd.conf[quot  ] contiene los m[oacute]dulos que se cargan al arrancarlo. Lo normal es que este fichero contenga una linea Loadmodule referente a mod perl, que tan s[oacute]lo hemos de descomentar (eliminar el [quot  ][num   ][quot  ] del principio). Si esta l[iacute]nea no existe, debemos a[ntilde]adirla. La l[iacute]nea tendr[aacute] el siguiente aspecto:

   LoadModule perl_module /ruta/del/archivo/del/modulo/mod_perl.so

Ahora ya tenemos un servidor con la capacidad de ejecutar scripts a trav[eacute]s de mod[lowbar]perl. Lo siguiente ser[aacute] hacer que el Perl embebido funcione. De nuevo aparece la misma disyuntiva: si nuestro Linux est[aacute] instalado a partir de una distribuci[oacute]n en la cual exista el paquete de emb-perl (en Debian: libhtml-embperl-perl) bastar[aacute] decirle al sistema que lo instale. Si no, tendremos que bajarnos el archivo de instalaci[oacute]n (ver listado 1) y realizar los siguientes  pasos: 

   perl Makefile.PL  
        make  
        make test  
        make install 

El pen[uacute]ltimo de los pasos (make test) requiere que se hallen en su sistema algunas bibliotecas instaladas de antemano.
Lo [uacute]ltimo que nos queda por hacer es configurar Apache para que ciertos tipos de extensiones las procese con Embperl. En principio nuestro servidor web puede tener gran variedad de tipos de ficheros que procesar, y no queremos que procese todos a trav[eacute]s de Embperl. Por eso asignaremos a los documentos escritos con este prop[oacute]sito la extensi[oacute]n de fichero .epl, aunque por supuesto esta configuraci[oacute]n puede (o debe) ser modificada seg[uacute]n las necesidades concretas de nuestro servidor o servicios web.
Para asignar la extensi[oacute]n .epl a los ficheros que deben ser procesados por Embperl puede bastar con a[ntilde]adir las siguientes l[iacute]neas a alguno de los ficheros de configuraci[oacute]n de Apache (srm.conf o httpd.conf), aunque cualquier lector que haya trabajado con este servidor web es, probablemente, capaz de sugerir varias alternativas.

    [lt    ]Files *.epl[gt    ] 
    SetHandler  perl-script 
    PerlHandler HTML::Embperl 
    Options     ExecCGI 
    [lt    ]/files[gt    ] 

    AddType text/html .epl

5 ¿C[oacute]mo se programa con Perl embebido?#$+
K
El primer ejemplo que aqu[iacute] se muestra, servir[aacute] para introducir la sintaxis b[aacute]sica del lenguaje y al mismo tiempo para comprobar que nuestro sistema est[aacute] funcionando y procesa nuestros ficheros .epl. Pero antes necesitamos tener el esqueleto de un archivo escrito en HTML corriente en el que podamos empotrar nuestro c[oacute]digo Perl.

[lt    ]HTML[gt    ] 
[lt    ]HEAD[gt    ] 
[lt    ]TITLE[gt    ]Pruebas de Embperl[lt    ]/TITLE[gt    ] 
[lt    ]/HEAD[gt    ] 
[lt    ]BODY[gt    ] 
[lt    ]H1[gt    ]Este es nuestro fichero de pruebas[lt    ]/H1[gt    ] 

En este fichero todav[iacute]a no hay nada que tenga que ver con Perl embebido. 

[lt    ]/BODY[gt    ] 
[lt    ]/HTML[gt    ]

El lector que todav[iacute]a no tenga claro si su servidor web est[aacute] funcionando puede comprobarlo copiando este c[oacute]digo en un fichero y poniendo en las localizaciones t[iacute]picas (pruebe a ponerlo en /var/www/ aunque deber[iacute]a mirar la variable DocumentRoot en su configuraci[oacute]n de Apache).
Ahora comenzaremos a a[ntilde]adir capacidad de proceso a este archivo. En primer lugar parece bastante l[oacute]gico que cuando insertemos nuestro Perl en el html tendremos que separarlo de alguna manera, para que el int[eacute]rprete reconozca lo que tiene que procesar y lo que no (el resto del html). Esto en Perl embebido se hace con corchetes. Una sentencia t[iacute]pica podr[iacute]a tener el siguiente aspecto.

   [- $variable1 = "Hola"; -]

El grupo de caracteres [quot  ][lsqb  ]-[quot  ] y [quot  ]-][quot  ] delimitan bloques de c[oacute]digo perl dentro del HTML. Cualquier cosa que est[eacute] incluida entre estos s[iacute]mbolos ser[aacute] interpretada como c[oacute]digo Perl. Tan s[oacute]lo hay que preocuparse de terminar las sentencias con [quot  ];[quot  ] tal y c[oacute]mo har[iacute]amos en un archivo de Perl corriente. Lo que hemos hecho en la l[iacute]nea anterior es una simple asignaci[oacute]n, la variable [quot  ]$variable1[quot  ] contendr[aacute] ahora la cadena de texto [quot  ]Hola[quot  ]. Al programador Perl que vea esto lo m[aacute]s probable es que se le ocurra introducir sentencias con la instrucci[oacute]n [quot  ]print[quot  ] dentro de los delimitadores que acabamos de aprender. Sin embargo, Perl no sabr[iacute]a d[oacute]nde tiene que imprimir el resultado de la variable. El siguiente trozo de c[oacute]digo es incorrecto s[oacute]lo por la declaraci[oacute]n en la que aparece la instrucci[oacute]n print:

   [-  
           $variable1 = "Hola"; 
           $suma = 1 + 2; 
           if ($suma > 0)  
             $texto = "Mayor que cero"; 
             print $texto; # Esta es la l[iacute]nea incorrecta 
             
           $variable2 = $variable1 
         -] 

Pero entonces ¿c[oacute]mo imprimimos el resultado de nuestros c[aacute]lculos (o de nuestras operaciones interactivas) en la p[aacute]gina web? Muy f[aacute]cil, usaremos otros delimitadores: [quot  ][lsqb  ]+[quot  ] y [quot  ]+][quot  ]. El siguiente listado muestra un ejemplo muy sencillo de c[oacute]mo podemos imprimir el resultado de una variable asignada previamente en nuestro c[oacute]digo, ya incluido dentro de nuestra p[aacute]gina de prueba:

    
  [lt    ]HTML[gt    ] 
   [lt    ]HEAD[gt    ] 
    [lt    ]TITLE[gt    ]Pruebas de Embperl[lt    ]/TITLE[gt    ] 
   [lt    ]/HEAD[gt    ] 
   [lt    ]BODY[gt    ] 
    [lt    ]H1[gt    ]Este es nuestro fichero de pruebas[lt    ]/H1[gt    ] 

     [- $variable1 = "hola"; 
        $variable2 = ", ¿qu[eacute] tal?" -] 

     [+ $variable1 +] 

   [lt    ]/BODY[gt    ] 
  [lt    ]/HTML[gt    ]

Con este ejemplo, ya podemos comprobar que Embperl est[aacute] procesando nuestro fichero. Si nombramos al archivo que contiene el c[oacute]digo anterior [quot  ]prueba.epl[quot  ], lo situamos en el mismo lugar donde ya tengamos p[aacute]ginas funcionando e intentamos acceder a [eacute]l desde el exterior, deber[iacute]amos ver algo como la figura nº 1.
****** IMAGEN 1 ****************************
En este punto hay que aclarar algunas cuestiones que se pueden plantear habiendo visto los ejemplos anteriores. En primer lugar, como ya aparece impl[iacute]cito en los ejemplos anteriores, dentro de los delimitadores [quot  ][lsqb  ]-[quot  ] y [quot  ]-][quot  ] podemos escribir c[oacute]digo en varias l[iacute]neas, e incluso poner comentarios. El [uacute]ltimo [quot  ];[quot  ] que pongamos dentro de este c[oacute]digo es opcional, ya que Embperl lo cierra por nosotros en caso de que no nos demos cuenta.
Podemos incluir cuantos grupos de c[oacute]digo queramos, y todos comparten el mismo espacio de variables dentro de una misma p[aacute]gina y una misma llamada. Esto quiere decir por un lado que podemos dotar a las variables de un valor en un grupo de c[oacute]digo y luego usar esa variable (que ya contiene el valor que le hemos asignado previamente) en otro grupo, y por otra parte que si un usuario desde Internet decide hacer una recarga de nuestra p[aacute]gina, los valores de las variables no se conservar[aacute]n.
Dentro de los delimitadores de impresi[oacute]n en la p[aacute]gina ([lsqb  ]+ +]) podemos poner cualquier cosa que pudiera ser argumento de la funci[oacute]n print. Por ejemplo, si queremos que la p[aacute]gina descrita unos p[aacute]rrafos m[aacute]s arriba sea un poco m[aacute]s educada, podemos sustituir la l[iacute]nea [quot  ][lsqb  ]+ $variable1 +][quot  ] por esta otra [quot  ][lsqb  ]+ [quot  ]$variable1.$variable2[quot  ] +][quot  ]
Cuando decimos que podemos incluir c[oacute]digo dentro de nuestra p[aacute]gina, tambi[eacute]n quiere decir que puede haber bucles, condiciones y cualquiera de las posibilidades de control de flujo de un programa que perl nos brinda (que no son pocas). Pero el verdadero poder que nos brinda Perl en una p[aacute]gina web es la posibilidad de iterar y condicionar no s[oacute]lo la ejecuci[oacute]n de una parte programada, sino tambi[eacute]n las etiquetas HTML y sus contenidos. Para explicar mejor esto, ponemos un ejemplo:
Necesitamos que nuestra p[aacute]gina ense[ntilde]e una imagen si el resultado de un c[aacute]lculo anterior es mayor que 5, y en caso contrario, que muestre un texto de cabecera de primer nivel ([lt    ]H1[gt    ]). Para hacer esto utilizaremos lo que se denomina en Embperl Meta-comandos; aunque el nombre asusta un poco, tan s[oacute]lo se trata de separar las sentencias Perl de bifurcaci[oacute]n e iteraci[oacute]n en bloques separados. Por ejemplo [lsqb  ]$ if (condici[oacute]n) $] que hay que terminar con [lsqb  ]$ endif $]. A continuaci[oacute]n listamos el c[oacute]digo que implementa el problema enunciado al principio del p[aacute]rrafo.

  [lt    ]HTML[gt    ] 
    [lt    ]HEAD[gt    ] 
      [lt    ]TITLE[gt    ]Pruebas de Embperl[lt    ]/TITLE[gt    ] 
    [lt    ]/HEAD[gt    ] 
    [lt    ]BODY[gt    ] 
      [lt    ]H1[gt    ]Este es nuestro fichero de pruebas[lt    ]/H1[gt    ] 
       [-  
         $variable=7;   #aqu[iacute] podr[iacute]a haber algo m[aacute]s complicado. 
       -] 
       [$ if ($condicion[gt    ]5) $] 
         [lt    ]IMG SRC=imagen.gif[gt    ] 
       [$ else $] 
         [lt    ]H1[gt    ]La variable es menor o igual a 5, mis disculpas.[lt    ]/H1[gt    ] 
       [$ endif $] 
   [lt    ]/BODY[gt    ] 
  [lt    ]/HTML[gt    ]

Desde el punto de vista de la programaci[oacute]n Perl choca un poco el hecho de que haya que cerrar cada una de las sentencias, pero con un poco de detenimiento podr[aacute] el lector observar que si no se le indicara al int[eacute]rprete la finalizaci[oacute]n del bucle o la condici[oacute]n [eacute]ste no podr[iacute]a determinar sobre que trozo de c[oacute]digo iterar o decidir.  Adem[aacute]s del meta-comando que acabamos de utilizar existe uno para cada sentencia de control de flujo de Perl. A continuaci[oacute]n listamos unos cuantos con sus sentencias de cierre como referencia.

   [$ if (condicion) $]             
        [$ elseif (condicion) $]                 
            ...                         
        [$ else $]       
        [$ endif $]      
         
        [$ do $] 
        [$ until $] 

        [$ while (condicion) $] 
        [$ endwhile $]          

        [$ foreach $var (lista) $] 
        [$ endforeach $]

Pero el ejemplo descrito anteriormente no resulta de mucha utilidad, en primer lugar porque siempre producir[aacute] la misma salida. Nuestra pr[oacute]xima tarea ser[aacute] interactuar con el usuario.
La manera m[aacute]s directa y usual para interactuar con el usuario a trav[eacute]s de una p[aacute]gina web es un formulario. Embperl nos permite acceder f[aacute]cilmente a la informaci[oacute]n proveniente de los formularios que se ha enviado a nuestra pagina-Embperl[lowbar]script. Para eso existe una estructura de tipo [quot  ]hash[quot  ] (tambien llamada array asociativo) con la cual podemos acceder directamente a estos datos. Este [quot  ]hash[quot  ] se llama [percnt]fdat contiene la informaci[oacute]n enviada de la siguiente forma:

   %fdat = ( 
                  nombre_del_campo  => informaci[oacute]n_del_campo, 
                  nombre_otro_campo => informaci[oacute]n_del_otro_campo 
                )

Para verlo m[aacute]s claro supongamos que una p[aacute]gina web que hemos hecho de antemano (que no tiene porqu[eacute] tener nada que ver con Embperl) contiene las siguientes l[iacute]neas:

   [lt    ]FORM METHOD="POST" ACTION="prueba.epl"[gt    ] 
        Ponga su comentario:[lt    ]INPUT TYPE="text" NAME="comentario"[gt    ][lt    ]BR[gt    ] 
        Y su nombre:    [lt    ]INPUT TYPE="text" NAME="nombre"[gt    ][lt    ]BR[gt    ] 
        [lt    ]INPUT TYPE="submit" NAME="enviar" VALUE="enviar"[gt    ] 
        [lt    ]/FORM[gt    ]

Cuando el usuario de esta p[aacute]gina pulsa el bot[oacute]n en el que pone [quot  ]enviar[quot  ], el navegador env[iacute]a una petici[oacute]n http de la p[aacute]gina-script [quot  ]prueba.epl[quot  ] (la que ahora nos ocupa) incluyendo la informaci[oacute]n del formulario que hemos descrito un poco antes. Para saber si el usuario que lo ha mandado ha tecleado en el campo de nombre la informaci[oacute]n [quot  ]pepe[quot  ], y obrar en consecuencia, podr[iacute]amos incluir en nuestra p[aacute]gina el siguiente c[oacute]digo:

   [$ if ($fdatnombre eq "Pepe") $] 
        [+ "¡Qu[eacute] alegr[iacute]a Pepe, cuanto tiempo sin saber nada de t[iacute]!" +] 
        [$ else $] 
        Lo siento, [+ $fdatnombre +], pero no nos han presentado.[lt    ]br[gt    ] 
        [$ endif $]

Ahora tenemos una visi[oacute]n m[aacute]s amplia de lo que puede hacer Embperl por la interactividad de nuestras p[aacute]ginas. Pero todav[iacute]a no hemos abierto la caja de Pandora, o mejor dicho CPAN, el archivo de m[oacute]dulos Perl.

6 Programaci[oacute]n en  Perl::DBI#$+
K
DBI es el acr[oacute]nimo de Database Interface, y es un m[oacute]dulo que permite al programa abstraerse de la implementaci[oacute]n espec[iacute]fica del acceso a la base de datos, que puede ser distinta en cada base de datos, y le permite programar el acceso a una base de datos de manera transparente. De esta forma se est[aacute] facilitando la portabilidad de los diversos programas ya que no est[aacute]n [quot  ]atados[quot  ] a ninguna base de datos.
Como se muestra en la figura 2, Perl::DBI encaja entre los programas y los interfaces particulares de cada base de datos, los llamados DBD (de Database Drivers) que son los que implementan el acceso a la base de datos en s[iacute].
DBI tiene un interfaz muy sencillo que permitir[aacute] al programador seleccionar la base de datos a utilizar y hacer consultas SQL, devolviendo los resultados en tablas o arrays asociativos que puedan ser f[aacute]cilmente tratados en Perl.
El acceso a una base de datos con Perl::DBI se limita a:
· La conexi[oacute]n a la base de datos, que se realiza con la funci[oacute]n connect y en la que se indica la base de datos a utilizar, as[iacute] como el usuario y contrase[ntilde]a para realizar la conexi[oacute]n. 
· La preparaci[oacute]n de una llamada SQL con la funci[oacute]n prepare, que se utilizar[aacute] para que el motor de la base de datos con la que se ha realizado la conexi[oacute]n [quot  ]compile[quot  ] la instrucci[oacute]n SQL y se prepare a ejecutarla. 
· La ejecuci[oacute]n de la llamada SQL ya preparada con la funci[oacute]n execute. 
· La recuperaci[oacute]n de los datos resultados de la ejecuci[oacute]n de la orden SQL con las funciones fetchrow[lowbar]array, fetchrow[lowbar]arrayref o fetchrow[lowbar]hashref. 
· La finalizaci[oacute]n de la consulta con la funci[oacute]n finish. 
· La desconexi[oacute]n de la base de datos con la orden disconnect. 

7 Migraci[oacute]n de pgsql a Perl Embedido#$+
K
En los art[iacute]culos anteriores se ha desarrollado el acceso a una base de datos utilizando un preprocesador espec[iacute]fico para PostgreSQL que permit[iacute]a desarrollar int[eacute]rpretes CGI r[aacute]pidamente con los que acceder a la base de datos. Sin embargo este acercamiento no esta exento de problemas, algunos de los cuales ya se introdujeron en art[iacute]culos previos, y que pueden concretarse en:
· dificultada en la intercepci[oacute]n de errores.
· dificultad en la comprobaci[oacute]n de datos recibidos.
· dificultad en la elaboraci[oacute]n de interfaces complejos.
· necesidad de la separaci[oacute]n de los formularios y el acceso a la base de datos.
Estos problemas van a poder ser solventados, pero no sin antes un esfuerzo adicional de programaci[oacute]n para contemplarlos y una reimplementaci[oacute]n haciendo uso de Perl embedido. Una vez hecha, sin embargo, la reimplementaci[oacute]n, la disponibilidad de un gran n[uacute]mero de m[oacute]dulos de Perl para las m[aacute]s diversas tareas (env[iacute]o de correos electr[oacute]nicos, acceso a ficheros...) as[iacute] como la integraci[oacute]n con el servidor de Apache para la gesti[oacute]n, por ejemplo, de cookies o de sesiones, nos permitir[aacute]n poder abrir nuevos campos de aplicaci[oacute]n al interfaz ya realizado.
Otra ventaja, adem[aacute]s, es que podremos coger consultas implementadas en Perl embedido y, con m[iacute]nimos esfuerzo, convertirlas en programas interpretados escritos en Perl que se ejecuten en el servidor. Esto va a permitir, si fuera necesario, convertir el tratamiento din[aacute]mico de la informaci[oacute]n en est[aacute]tico, si fuera necesario.
7.1 Consulta de datos con Perl embedido#K
************** LISTADO 2 ****************************+
Como se puede ver en el listado 2, el acceso a las funciones de Perl embedido permiten programa muchas caracter[iacute]sticas dentro de una p[aacute]gina. Vamos a tomar dicho listado como la base de un ejemplo para ver c[oacute]mo se har[iacute]a la migraci[oacute]n de las distintas consultas y formularios de introducci[oacute]n de datos en este lenguaje, analiz[aacute]ndolo por completo.
En primer lugar se puede ver que el primer bloque hace que se carguen los distintos m[oacute]dulos que van a ser utilizados por el int[eacute]rprete, de particular inter[eacute]s ser[aacute]n DBI, ya comentado, y CGI::Cookie, que permitir[aacute] acceder a las cookies que el usuario env[iacute]e al servidor. Estas cookies, como ya se coment[oacute] en art[iacute]culos anteriores son las que se van a utilizar para identificar si el usuario ha sido autenticado.
Posteriormente, se hace la conexi[oacute]n con la base de datos, utilizando la funci[oacute]n correspondiente del m[oacute]dulo DBI, preservando en variables la posibilidad o no de haber realizado la conexi[oacute]n. Esto va a permitir que, a continuaci[oacute]n se puedan tratar los casos de fallo de conexi[oacute]n a la base de datos.
Como se puede ver en el bloque if se pueden, dentro de una misma p[aacute]gina introducir informaci[oacute]n que se va a mostrar en funci[oacute]n de las acciones tomadas anteriormente. Este bloque permite mostrar una p[aacute]gina determinada (en realidad va a reenviar al usuario con un refresh a la p[aacute]gina en cuesti[oacute]n) en el caso de que no se haya podido establecer la conexi[oacute]n a la base de datos. Los siguientes bloques se evaluar[aacute]n s[oacute]lo en el caso de que la conexi[oacute]n haya sido exitosa, ya que, de no serlo, el int[eacute]rprete saltar[aacute] al bloque endif correspondiente.
A continuaci[oacute]n se eval[uacute]a si la cookie del usuario corresponde con una v[aacute]lida, utilizando el valor de [eacute]sta para realizar una consulta a la base de datos que nos indicar[aacute] si est[aacute] accediendo un usuario autorizado.
En el caso de que no lo sea, hay un nuevo error que le indicar[aacute] al usuario que no pertenece a la base de datos y deber[aacute] autenticarse. Si lo es, se llegar[aacute] a la construcci[oacute]n de la consulta que ser[aacute] realizada en la base de datos, en este caso un listado de Antiguos Alumnos.
Se utiliza Perl embedido para procesar la consulta a trav[eacute]s del interfaz DBI, y para mostrar la lista de columnas recibidas dentro de una tabla. En el caso de que no haya datos se muestra un mensaje explicativo indicando la raz[oacute]n.
Asimismo se pueden introducir en una misma p[aacute]gina tres p[aacute]ginas distintas que ser[aacute]n mostradas en funci[oacute]n de las condiciones de ejecuci[oacute]n del programa.
7.2 Autenticaci[oacute]n de usuarios con Perl embedido#K
************** LISTADO 3 ***************************
Finalmente, como ejemplo m[aacute]s complejo se puede consultar el listado 3. [Eacute]ste ser[iacute]a el correspondiente a la p[aacute]gina de acceso al servidor, que, como se puede ver es din[aacute]mica.
En dicha p[aacute]gina est[aacute] incluido el formulario de entrada de datos del usuario, la comprobaci[oacute]n de los datos en s[iacute], y los mensajes de aceptaci[oacute]n y rechazo correspondientes. Como se puede ver se puede hacer de golpe todas estas operaciones sin tener que necesitar distintas p[aacute]ginas separadas que s[iacute] eran necesarias en el caso de pgsql.
Se deja, por limitaciones de espacion, como ejercicio al lector el determinar el exacto funcionamiento de este programa.

8 Resumen#$+
K
Como se ha visto en [eacute]ste art[iacute]culo es posible hacer uso de toda la potencia expresiva de Perl en la programaci[oacute]n de p[aacute]ginas dentro de servidores de WWW, esto, acompa[ntilde]ado con la gran versatilidad del m[oacute]dulo Perl::DBI permite a los programadores la definici[oacute]n de interfaces desde WWW a servidores de bases de datos que sean f[aacute]cilmente portables entre servidores, sistemas operativos y sistemas de gesti[oacute]n de bases de datos.

9 Sumarios#$+
KLa soluci[oacute]n m[aacute]s f[aacute]cil para hacer CGIs es usar Perl.
Perl posee beneficiosas caracter[iacute]sticas a la hora de escribir programas.
Existen alternativas al uso de Perl embedido.
Perl emebedido permite una gran interactividad en el servidor.
Antes de nada es necesario introducir los elementos necesarios.
La configuraci[oacute]n para Perl embedido no es complicada.
No es dif[iacute]cil introducir Perl embedido en p[aacute]ginas HTML.
DBI es un interfaz gen[eacute]rico de acceso a bases de datos.
Se reimplementar[aacute]n los ejemplos anteriores con Perl embedido.
Es posible hacer uso de toda la potencia expresiva de Perl.

10 Listados#$+
K
LISTADO 1
Algunos servidores de inter[eacute]s son: 
· www.apache.org que contiene toda la informaci[oacute]n relativa al servidor Apache.
· www.perl.org, toda la informaci[oacute]n sobre el lenguaje de programaci[oacute]n Perl.
· perl.apache.org, que contiene toda la informaci[oacute]n sobre la integraci[oacute]n de Perl y Apache.
· www.cpan.org, servidor que ofrece todos los m[oacute]dulos disponibles para Perl.
· www.postgresql.org, el servidor principal del sistema de gesti[oacute]n de bases de datos PostgreSQL. 
· Se puede encontrar gran informaci[oacute]n sobre DBI en la p[aacute]gina de recursos http://www.symbolstone.org/technology/perl/DBI/ 
· El proyecto WebDBI, www.wdbi.net, es tambi[eacute]n de gran inter[eacute]s en el sentido de que permite realizar r[aacute]pidamente interfaces web a bases de datos con DBI y perl embedido. Merece la pena conocerlo. 
· lucas.hispalinux.es, que contiene gran cantidad de documentaci[oacute]n traducida al castellano incluyendo el proyecto de traducci[oacute]n de PostgreSQL al castellano. Otro servidor de gran inter[eacute]s para hispano parlantes es www.postgres.org.mx
El libro de O'reilly de Perl::DBI [quot  ]Programming the Perl DBI[quot  ] de Alligator Descartes y Tim Bunce, los creadores del m[oacute]dulo es una estupenda referencia sobre el tema (ISBN: 1565926994).
PIE LISTADO 1: M[aacute]s informaci[oacute]n
LISTADO 2 

 
[lt    ]!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//ES"[gt    ] 
[lt    ]HTML[gt    ] 
[lt    ]HEAD[gt    ] 
   [lt    ]TITLE[gt    ]Listado de antiguos alumnos por a[ntilde]o de promoci[oacute]n[lt    ]/TITLE[gt    ] 
    
 [-  
   use DBI; 
   use POSIX qw/strftime/; 
   use CGI::Cookie; 
   %cookies = fetch CGI::Cookie; 
   $db="alumni2k"; 
   $uslec="lectura"; 
  -] 
 [-     
  $dbuser=$uslec; 

  if (not(defined($dbhlectura)))  
   eval $dbhlectura = DBI-[gt    ]connect("dbi:Pg:dbname=$db", "$dbuser", "")  
   or die "No puedo abrir la base de datos $dbname con el usuario $dbuser"; ; 

   $falloconex = "fallo" if ( ! defined($dbhlectura) ); 
  ; 
  -] 

 [$ if ($falloconex) $] 
 [- $udaterrores="Sin conexi[oacute]n";  -] 
           [lt    ]META http-equiv="refresh" content="1;URL=../error/fallo_conexion.epl"[gt    ] 
           [lt    ]/HEAD[gt    ] 
           [lt    ]BODY[gt    ] 
           Ha habido un [lt    ]A HREF="../error/fallo_conexion.epl"[gt    ]error%lt;/A[gt    ] 
           [lt    ]/BODY[gt    ] 
           [lt    ]/HTML[gt    ] 
 [$ else $] 

 [-  if (exists($cookies'codigo') && $cookies'codigo'-[gt    ]value != 0 )  
        
        $codigo = $cookies'codigo'-[gt    ]value; 
        @arraydatos = $dbhlectura-[gt    ]selectrow_array("SELECT DISTINCT codigo, nombre, apellido, id_persona FROM persona WHERE codigo = $codigo"); 
       
      if (@arraydatos)  
       
         $ref = arraydatos; 
        ($bogus,$nombreusuario,$apellidousuario,$idpersona)=@$ref; 
        
      else $ref="" 
  -] 

  [$ if (not($ref)) $] 
  [- $udaterrores="No es miembro o no autentificado"; -] 
[lt    ]META http-equiv="refresh" content="0;URL=../error/no_pertenece.epl"[gt    ] 
[lt    ]/HEAD[gt    ] 
[lt    ]BODY[gt    ] 
[lt    ]STRONG[gt    ] 
Ha habido alg[uacute]n error en el proceso, si su navegador no se lo muestra 
autom[aacute]ticamente pulse [lt    ]a HREF="../error/no_pertenece.epl"[gt    ]aqu[iacute][lt    ]/A[gt    ]. 
[lt    ]/STRONG[gt    ] 
[lt    ]/BODY[gt    ] 
[lt    ]/HTML[gt    ] 

 [$ else $]  

[lt    ]/HEAD[gt    ] 
[lt    ]BODY[gt    ] 
[lt    ]H1[gt    ]Listado de AAs por a[ntilde]o de promoci[oacute]n[lt    ]/H1[gt    ] 

[-  

   $consulta = "select nombre, apellido, graduacion  from persona, datos_academicos where persona.id_persona = datos_academicos.id_persona and autorizacion = 1 order by graduacion"; 
   $sth = $dbhlectura-[gt    ]prepare($consulta); 
   $sth-[gt    ]execute or die "Lo siento, no puedo realizar la consulta en este momento";  
   $head = $sth-[gt    ]NAME; 
   $data = $sth-[gt    ]fetchall_arrayref ; 
   $rows = $sth-[gt    ]rows; 
-] 
[$ if $rows [gt    ] 0 $] 
[lt    ]table border=0[gt    ] 
[lt    ]tr[gt    ][lt    ]th[gt    ][+ $head-[gt    ][$col] +][lt    ]/th[gt    ][lt    ]/tr[gt    ] 
[lt    ]tr[gt    ][lt    ]td[gt    ][+ $data -[gt    ] [$row][$col] +][lt    ]/td[gt    ][lt    ]/tr[gt    ] 
[lt    ]/table[gt    ] 
[$ else $] 
[lt    ]P[gt    ]Lo lamentamos, pero no hay datos en la base de datos en respuesta 
a la consulta 

[lt    ]/BODY[gt    ] 
[lt    ]/HTML[gt    ] 

[$ endif $] 

[$ endif $]  
  
[-  
 if (defined($dbhlectura))  
     eval$dbhlectura-[gt    ]disconnect or warn "La desconexi[oacute]n de la base de datos fall[oacute]: $DBI::errstr"; 
   ; 
 -] 

PIE LISTADO 2: Ejemplo de consulta con perl embedido
LISTADO 3 

 

[lt    ]!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//ES"gt; 
[lt    ]HTMLgt; 
[lt    ]HEADgt; 
   [lt    ]TITLEgt;Bienvenidos al sitio de la Asociaci[oacute]n de Antiguos Alumnos[lt    ]/TITLEgt; 
    
  [-  
   use DBI; 
   use POSIX qw/strftime/; 
   use CGI::Cookie; 
   %cookies = fetch CGI::Cookie; 
   $db="alumni2k"; 
   $uslec="lectura"; 
   $usesc="escritura"; 
   $uspub="sincompletar"; 
   $usadm="sincompletar"; 
   $passadm="sincompletar"; 
  -] 

  [-     
  $dbuser=$uslec; 
if (not(defined($dbhlectura)))  
eval $dbhlectura = DBI-gt;connect("dbi:Pg:dbname=$db", "$dbuser", "") or die "No puedo abrir la base de datos $dbname con el usuario $dbuser"; ; 
if (not(defined($dbhlectura))) $falloconex="fallo"; 
; 
  -] 

 [-  if (exists($cookies'codigo') && $cookies'codigo'-gt;value != 0 )  
        
        $codigo = $cookies'codigo'-gt;value; 
        @arraydatos = $dbhlectura-gt;selectrow_array("SELECT DISTINCT codigo, nombre, apellido, id_persona FROM persona WHERE codigo = $codigo"); 
       
      if (@arraydatos)  
       
         $ref = arraydatos; 
        ($bogus,$nombreusuario,$apellidousuario,$idpersona)=@$ref; 
        
      else $ref="" 
 -] 

    
[- 
$dni=$fdatdonaid; 
$fecha=$fdatfecha; 
-] 

[$ if ($dni && $fecha ) $]  

[-  sub compruebadate  
    use POSIX qw/strftime/; 
    my $anno = strftime "%Y", localtime; 
    $_=shift; 
    if (not(m/()-()-()/)) push @erroresdate, "La fecha no cumple el formato, rev[iacute]sela. (DD-MM-AAAA)"; 
    return @erroresdate; 
 
-] 
[- sub compruebadni  
my $dnip=shift; 
$_=$dnip; 
if (not(m/^(+)$/)) push @erroresdni, "El dni que ha introducido no es v[aacute]lido, por favor, aseg[uacute]rese de que no incluye espacios ni caracteres que no sean d[iacute]gitos."; 
return @erroresdni; 
 
-] 
[-  
   @edate= compruebadate($fecha); 
   @edni = compruebadni($dni); 
-] 
[$ if (not(@edate||@edni)) $] 

[- 
$autentificable = "SELECT DISTINCT id_persona, nombre, apellido FROM persona WHERE fecha_nacimiento = $fecha and dni = $dni"; 
$sthautentificable = $dbhlectura-gt;prepare($autentificable); 
$sthautentificable-gt;execute; 
@arrayautent = $sthautentificable-gt;fetchrow_array; 
-] 
[$ if (not(@arrayautent)) $] 
[-  
$autentificable = "SELECT DISTINCT id_persona, nombre, apellido FROM persona_sin_verif WHERE fecha_nacimiento = $fecha and dni = $dni"; 
$sthautentificable = $dbhlectura-gt;prepare($autentificable); 
$sthautentificable-gt;execute; 
@arrayautent = $sthautentificable-gt;fetchrow_array; 
-] 
[$ if (not(@arrayautent)) $] 
[- push @egeneral,('Vd. no ha introducido a[uacute]n sus datos para solicitar ser miembro de la asociaci[oacute]n o ha cometido algun error en sus datos; si tiene algun problema, por favor [lt    ]A HREF="mailto:alumni-admin@dat.etsit.upm.es"gt;contacte con el administrador[lt    ]/Agt;.'); -] 
[$ else $] 
[- push @egeneral,('Ya hemos recibido sus datos pero lamentamos decirle que a[uacute]n no hemos podido verificarlos. No podr[aacute] acceder, a[uacute]n, a las consultas de la base de datos pero s[iacute] podra [lt    ]A HREF="datos/modificadatos.epl"gt;modificar[lt    ]/Agt; sus datos si lo desea. '); -] 
[- ($aid,$anom,$aape) = @arrayautent; -] 

[- 
$sec = strftime "%S", localtime; 
$criptado = crypt $anom, "$sec"; 
$metecodigo="UPDATE persona_sin_verif SET codigo=$criptado WHERE id_persona=$aid"; 
$sthcodigo=$dbhescritura-gt;prepare($metecodigo); 
$sthcodigo-gt;execute(); 
-] 

[lt    ]META HTTP-EQUIV="Set-Cookie" CONTENT="codigo =[+ $criptado +]"gt; 

[- 
$aumentaacceso="UPDATE accesos SET num_accesos = num_accesos + 1 WHERE persona_sin_verif.id_persona=$aid"; 
$aumentaaccesotemp="UPDATE accesos SET num_accesos_parcial = num_accesos_parcial +1 WHERE persona_sin_verif.id_persona=$aid"; 
$marcaultimoacceso="UPDATE accesos SET fecha_ultimo_acceso = now WHERE persona_sin_verif.id_persona=$aid"; 
$sthaumenta=$dbhescritura-gt;prepare($aumentaacceso); 
$sthaumenta-gt;execute(); 
$sthaumentatemp=$dbhescritura-gt;prepare($aumentaaccesotemp); 
$sthaumentatemp-gt;execute(); 
$sthmarca=$dbhescritura-gt;prepare($marcaultimoacceso); 
$sthmarca-gt;execute(); 
-] 

[$ endif $] 
[$ else $] 
[- ($aid,$anom,$aape) = @arrayautent; -] 

[- 
$sec = strftime "%S", localtime; 
$criptado = crypt $anom, "$sec"; 
$metecodigo="UPDATE persona SET codigo=$criptado WHERE id_persona=$aid"; 
$sthcodigo=$dbhescritura-gt;prepare($metecodigo); 
$sthcodigo-gt;execute(); 
-] 

[lt    ]META HTTP-EQUIV="Set-Cookie" CONTENT="codigo =[+ $criptado +]"gt; 

[- 
$aumentaacceso="UPDATE accesos SET num_accesos = num_accesos + 1 WHERE persona.id_persona=$aid"; 
$aumentaaccesotemp="UPDATE accesos SET num_accesos_parcial = num_accesos_parcial +1 WHERE persona.id_persona=$aid"; 
$marcaultimoacceso="UPDATE accesos SET fecha_ultimo_acceso = now WHERE persona.id_persona=$aid"; 
$sthaumenta=$dbhescritura-gt;prepare($aumentaacceso); 
$sthaumenta-gt;execute(); 
$sthaumentatemp=$dbhescritura-gt;prepare($aumentaaccesotemp); 
$sthaumentatemp-gt;execute(); 
$sthmarca=$dbhescritura-gt;prepare($marcaultimoacceso); 
$sthmarca-gt;execute(); 
-] 

[$ endif $] 

[$ endif $] 

[$ endif $] 

          [$ if ($falloconex) $] 
           [- $udaterrores="Sin conexi[oacute]n";  
           -] 
           [lt    ]META http-equiv="refresh" content="1;URL=error/fallo_conexion.epl"gt; 
           [lt    ]/headgt; 
           [lt    ]bodygt; 
           [lt    ]/bodygt; 
           [lt    ]/htmlgt; 
          [$ else $] 
                 
          [$ if ($falloconex) $] 
           [- $udaterrores="Sin conexi[oacute]n";  
           -] 
           [lt    ]META http-equiv="refresh" content="1;URL=error/fallo_conexion.epl"gt; 
           [lt    ]/headgt; 
           [lt    ]bodygt; 
           [lt    ]/bodygt; 
           [lt    ]/htmlgt; 
          [$ else $] 
         
[lt    ]/HEADgt; 
[lt    ]BODY BGCOLOR="white"gt; 
[lt    ]H1gt;Bienvenido[lt    ]/H1gt; 
[lt    ]Pgt;Bienvenido al servidor de la Asociaci[oacute]n de Antiguos Alumnos. 

[lt    ]table border="0" cellpadding="0" cellspacing="0"gt; 
 [lt    ]trgt; 
  [lt    ]td width="280" valign="top" align="left"gt; 
[$ if not($aid) $] 
     
[$ if (not($ref)) $] 

[lt    ]FORM METHOD="POST" ACTION="index.epl"gt; 
D.N.I.:[lt    ]INPUT TYPE="PASSWORD" NAME="donaid" TABINDEX="1" SIZE="10"gt; 
Fecha de Nacimiento: 
(DD-MM-AAAA) [lt    ]INPUT TYPE="TEXT" NAME="fecha" TABINDEX="2" SIZE="10"gt; 
[lt    ]input type="submit" name="autent" value="Autentif[iacute]came"gt; 
[lt    ]/FORMgt; 

[$ endif $] 
[$ if ($ref) $] 

[+ $nombreusuario +][nbsp  ][+ $apellidousuario +][lt    ]brgt; 
Conectado al servidor, con los correspondientes permisos de usuario. 

[$ endif $] 

[$ endif $] 
[$ if ($aid) $] 
Ud. acaba de ser reconocido como[lt    ]brgt; 
[+ $anom +][nbsp  ][+ $aape +],[lt    ]brgt; 
Bienvenido al servidor. 
[$ endif $] 

[$ if ($dni) $] 
[$ if (@edate||@edni||@egeneral) $] 

[$ foreach $msg (@edni) $] 
[+ $msg +][lt    ]HRgt; 
[$ endforeach $] 
[$ foreach $msg (@edate) $] 
[+ $msg +][lt    ]HRgt; 
[$ endforeach $] 
[$ foreach $msg (@egeneral) $] 
[+ $msg +][lt    ]HRgt; 
[$ endforeach $] 

[$ else $] 

No olvide que una vez su acceso al servidor ha sido reconocido, ya puede 
acceder tanto a las [lt    ]a href="consultas/"gt;consultas[lt    ]/Agt; como a 
la [lt    ]A HREF="datos/modificadatos.epl"gt;modificaci[oacute]n o actualizaci[oacute]n[lt    ]/Agt; de sus datos guardados aqu[iacute]. 

[$ endif $] 
[$ endif $] 
[$ if (not($aid)) $] 
     
[$ if (not($ref)) $] 

[lt    ]FORM METHOD="POST" ACTION="datos/nuevosocio.epl"gt; 
Nombre: [lt    ]INPUT TYPE="TEXT" NAME="nombre" TABINDEX="3" SIZE="20"gt; 
Apellidos: [lt    ]INPUT TYPE="TEXT" NAME="apellidos" TABINDEX="4" SIZE="20"gt; 
[lt    ]input type="submit" name="nuevosocio" value="Comenzar"gt; 
[lt    ]/FORMgt; 

[$ endif $] 

[$ endif $] 

[lt    ]/BODYgt; 
[lt    ]/HTMLgt; 
[$ endif $]  
[$ endif $] 

  [- if (defined($dbhescritura))  
     eval$dbhescritura-gt;disconnect or warn "La desconexi[oacute]n de la base de datos fall[oacute]: $DBI::errstr";; 
  -] 

  [- if (defined($dbhlectura))  
     eval$dbhlectura-gt;disconnect or warn "La desconexi[oacute]n de la base de datos fall[oacute]: $DBI::errstr";; 
  -] 

PIE LISTADO 3: Entrada al servidor

11 Capturas#$+
K
· Figura 1: (fig1.bmp) Primer ejemplo con Perl embedido
· Figura 2: (ambitodbi.png) Ambito del m[oacute]dulo Perl::DBI
· Figura 3: (entrada.png) Entrada al servidor

12 Notas de maquetaci[oacute]n#$+
K

13 Notas de coordinaci[oacute]n#$+
K
Es posible seguir con art[iacute]culos de esta serie con los siguientes temas:  
· WDBI
· uso de WML para la creaci[oacute]n de webs
· programaci[oacute]n m[aacute]s detallada del uso de Perl::DBI