Activitats

Una agenda amb PHP

L’objectiu d’aquesta activitat és proporcionar a l’estudiant un marc de treball on desenvolupar la seva creativitat, utilitzant el llenguatge PHP, per aprofundir en el seu estudi i tenir un coneixement més ampli del mateix. Es recomana haver fet l’apartat 1 i l’apartat 2 d’aquesta unitat per poder desenvolupar l’activitat.

Utilitzant el llenguatge de programació PHP, es vol crear una aplicació que permeti tenir una agenda on guardar les cites del dia seleccionat. Es recomana l’ús de classes PHP i la creació de fitxers en el servidor per guardar la informació.

La solució de l’exercici està dividida en tres fitxers PHP. Els podeu descarregar en aquest

enllaç ( 3.2 KB )
.

  • agenda.php
  • calendari.php
  • store.php

La pàgina principal de l’aplicació és agenda.php, i fa les crides als fitxers calendari.php i store.php.

La pàgina principal fa de vista de l’aplicació, és la pàgina que veurà sempre l’usuari al seu navegador i segons les opcions que utilitzi es cridaran a les funcions de les altres pàgines.

Aquesta aplicació està orientada a objectes; per tant, els utilitzeu per donar una solució a l’exercici.

Primer començareu creant un projecte nou a NetBeans (File / New Project / PHP / PHP Application). Tot seguit li doneu un nom al projecte, per exemple Activitat1. Si voleu, podeu esborrar el fitxer index.php, ja que s’ha creat automàticament en crear el nou projecte PHP.

A continuació, importeu el fitxer descarregat (agendaphp.zip) amb la solució de l’exercici (File / Import project / From ZIP). Quan importeu el fitxer .zip heu d’especificar el directori del projecte destí (vegeu la figura figura).

Figura Importar la solució a l’IDE Netbeans
Importar la solució a l'IDE Netbeans

En acabar el procés, segurament us donarà l’error No NetBeans projects Added. És normal, atès que els fitxers s’han importat correctament, però us informa que no és un projecte sencer (per això heu hagut de crear-ne un de nou). Una vegada teniu els tres fitxers podeu continuar amb l’activitat.

El fitxer calendari.php és on es troba la classe Calendari, que us permet visualitzar el calendari d’un determinat mes (any-mes-dia) i interaccionar amb aquest. Aquest calendari té una funció que us permet obtenir la seva representació gràfica en HTML.

El fitxer store.php és on es troba la classe Store, que us permet guardar un arxiu o recuperar la informació guardada anteriorment en un arxiu. Aquesta classe és una classe estàtica, és a dir, només existeix un objecte d’aquesta classe per a tota l’aplicació PHP, i és el mateix objecte per a tots. No es poden crear més objectes d’aquesta classe. Permet, d’una manera molt ràpida, poder utilitzar les seves funcions i poder realitzar les peticions de l’usuari sense instanciar-la cada vegada. Aquesta classe serialitza els objectes que es volen guardar (és a dir, els converteix a string) i els guarda en un fitxer al disc dur. És una classe genèrica que podríeu utilitzar per guardar arrays o qualsevol altre tipus de dades.

Finalment, com hem dit al principi, el fitxer principal de l’aplicació és qui orquestrarà les dues classes i qui donarà a l’usuari les eines necessàries per poder programar una cita a la seva agenda. Doneu un cop d’ull a aquest fitxer:

  1. <?php
  2. require_once('Calendari.php');
  3. require_once('Store.php');
  4. ?>
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <meta charset="UTF-8">
  9. <title></title>
  10. </head>
  11. <body>
  12. <?php
  13. //creem el calendari. Si l'usuari ha clicat en alguna
  14. //data especial, s'agafa; si no, el calendari utilitzarà
  15. //la data actual
  16. $c = new Calendari($_REQUEST["data"]);
  17. $data = $c->getdata();
  18.  
  19. //Mirem si l'usuari ha afegit una cita a la data seleccionada
  20. if (isset($_REQUEST["cites"])) {
  21. //Agafem el contingut de la cita
  22. $dadesAModificar = $_REQUEST["cites"];
  23. //La guardem a un fitxer en el servidor.
  24. Store::save($dadesAModificar, $data);
  25. }
  26. //Mirem les cites que hi ha a la data seleccionada
  27. $dadesAMostrar = Store::restore($data);
  28. ?>
  29. <!--Mostrem el calendari (la taula)-->
  30. <div><?php $c->view(); ?></div>
  31. <div>
  32. <!--Mostrem el formulari amb un text àrea on podem
  33. modificar les cites del dia seleccionat-->
  34. Amb la data seleccionada al calendari tens les següents cites:<br>
  35. <!--El text àrea està lligat al formulari però
  36. no ha d'estar dintre de les etiquetes perquè
  37. funcioni correctament-->
  38. <textarea form ="citesform" name="cites" id="cites" cols="35" wrap="soft"><?php print $dadesAMostrar; ?></textarea>
  39. <form method="POST" action="agenda.php" id="citesform">
  40. <!--En utilitzar el formulari per enviar les dades
  41. hem de saber el dia seleccionat. Enviem també el dia
  42. amb un text ocult-->
  43. <input type="hidden" name="data" value="<?php echo $data ?>">
  44. <input type="submit" />
  45. </form>
  46. </div>
  47. </body>
  48. </html>

Observeu que accediu al request de la petició per saber les opcions que ha enviat l’usuari mitjançant el navegador web. Aquestes opcions poden ser:

  • Data: s’utilitza per saber la data que l’usuari ha escollit, ja sigui per guardar la informació o per veure-la. Aquesta informació és opcional; si no s’envia, s’agafa el dia actual.
  • Cites: s’utilitza per emmagatzemar la informació que ha introduït l’usuari al text àrea al dia escollit. Si no s’escull dia, s’agafa el dia actual. Si aquesta variable no s’envia, llavors es vol llegir i no es guarda res.

El primer que fa l’agenda, a part d’escriure el codi HTML per confeccionar un document vàlid per al navegador, és crear la classe Calendari amb la data que ha seleccionat l’usuari. Aquest calendari s’utilitzarà més endavant per mostrar-lo per pantalla quan sigui el moment.

Tot seguit, es mira si l’usuari ha enviat dades mitjançant el text àrea del formulari. Aquesta informació es guarda a la variable cites de la petició ($_REQUEST). Si ha enviat alguna informació es guarda utilitzant la classe Store. No s’ha de fer cap new de la classe, perquè només hi ha un objecte en tota l’aplicació d’aquesta classe. S’ha implementat fent-la estàtica. Llavors, s’accedeix als seus mètodes utilitzant els dos punts després del nom de la classe (::).

La funció save de la classe Store guarda un fitxer en el disc dur. El nom del fitxer es correspon amb el dia que l’usuari ha seleccionat, i dintre d’aquest fitxer es guarda la informació que l’usuari ha introduït al text àrea.

Sempre es mira si existeix un fitxer que porta com a nom la data seleccionada per l’usuari (o la data actual). Si es troba, s’agafa la informació, amb el mètode restore de la classe Store, i es guarda en una variable que després s’utilitzarà per omplir el text àrea del formulari. Així, l’usuari sempre podrà modificar afegint o traient informació.

A continuació es mostra el calendari, que és interactiu i s’hi pot clicar als dies o en el més anterior o següent de l’escollit. Sempre que utilitzeu el calendari s’envia una petició amb la data seleccionada. Si es canvia de mes es manté el dia i l’any. De fet, no es dóna opció a canviar d’any si no es va a l’últim més de l’any i es passa al següent mes.

Finalment, es mostra el formulari per poder canviar les cites del dia seleccionat. Aquest formulari us proporciona un botó per guardar qualsevol canvi que hagueu introduït en un dia del calendari.

A la figura figura podeu veure l’aparença que té aquesta aplicació.

Figura Aplicació: una agenda amb PHP
Una agenda amb PHP

Llegint dades XML amb JSP i JSTL

L’objectiu d’aquesta activitat és mostrar a l’estudiant una utilitat dels fitxers XML i com fer el seu tractament amb JSP o JSTL.

Es volen utilitzar les dades de temperatura proporcionades pel servei meteorològic, que normalment estan en format XML, i mostrar la informació en una pàgina web. Aquestes dades també podrien ser produïdes per una estació meteorològica casolana, i amb aquest programa es podrien agafar les dades i mostrar-les d’una manera més amigable.

Si voleu una altra província podeu descarregar-vos l’XML de la següent pàgina web. .

Donat el següent fitxer XML, feu una pàgina amb JSP i una altra amb JSTL per mostrar les dades a l’usuari:

  1. <root id="08">
  2. <elaborado>2016-03-23T14:01:11</elaborado>
  3. <validez_ini>2016-03-23T00:00:00</validez_ini>
  4. <validez_fin>2016-03-24T00:00:00</validez_fin>
  5. <actualizacion/>
  6. <prediccion>
  7. <txt_prediccion>
  8. <p>
  9. Poco nuboso en general, salvo algunas nubes altas. Temperaturas mínimas en descenso, y sin cambios las máximas. Heladas débiles en el Prepirineo y algún punto del interior. Viento variable flojo con predominio de los oestes.
  10. </p>
  11. </txt_prediccion>
  12. <ciudad>
  13. <id>6908298</id>
  14. <nombre>Vic</nombre>
  15. <minima>1</minima>
  16. <maxima>18</maxima>
  17. </ciudad>
  18. <ciudad>
  19. <id>6908121</id>
  20. <nombre>Mataró</nombre>
  21. <minima>8</minima>
  22. <maxima>17</maxima>
  23. </ciudad>
  24. <ciudad>
  25. <id>6908102</id>
  26. <nombre>Igualada</nombre>
  27. <minima>4</minima>
  28. <maxima>18</maxima>
  29. </ciudad>
  30. <ciudad>
  31. <id>6908307</id>
  32. <nombre>Vilanova i la Geltrú</nombre>
  33. <minima>7</minima>
  34. <maxima>20</maxima>
  35. </ciudad>
  36. <ciudad>
  37. <id>6908113</id>
  38. <nombre>Manresa</nombre>
  39. <minima>3</minima>
  40. <maxima>19</maxima>
  41. </ciudad>
  42. <ciudad>
  43. <id>6908187</id>
  44. <nombre>Sabadell</nombre>
  45. <minima>5</minima>
  46. <maxima>19</maxima>
  47. </ciudad>
  48. <ciudad>
  49. <id>6908019</id>
  50. <nombre>Barcelona</nombre>
  51. <minima>9</minima>
  52. <maxima>17</maxima>
  53. </ciudad>
  54. </prediccion>
  55. </root>

La solució de l’activitat està realitzada de dues maneres diferents. La primera amb JSTL i la segona amb JSP. Podeu baixar-vos la solució en aquest

enllaç ( 2.4 KB )
.

Primer començareu creant un projecte amb Maven (File / New Project / Maven / Web Application). Li poseu un nom de projecte, per exemple Activitat2, i seleccioneu GlassFish com a servidor d’aplicacions.

Tot seguit copieu els dos fitxers (llegintjsp.jsp i llegintjstl.jsp) al directori webapp que podeu trobar dintre del directori src / main del projecte NetBeans. Per exemple: home / alex / NetBeansProjects / Activitat2 / src / main / webapp. Podeu esborrar el fitxer index.jsp, ja que s’ha creat automàticament quan s’ha creat el projecte.

Us apareixeran els dos fitxers al programa NetBeans. Executeu-los (botó dret del ratolí Run File), i Maven baixarà les dependències que necessiten els fitxers per funcionar.

A continuació s’explicaran les parts més importants de cadascuna de les dues solucions. Començarem explicant la solució realitzada amb JSTL.

Extracte de la solució:

  1. <c:import var="xmltext" url="http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml"/>
  2. <h1>Lectura de dades XML amb JSTL</h1>
  3. <x:parse xml="${xmltext}" var="output"/>
  4. <h2>Predicció per a la província de Barcelona:</h2>
  5. <p>
  6. <x:out select="$output/root/prediccion/txt_prediccion" />
  7. </p>
  8.  
  9. <ul class="list">
  10. <x:forEach select="$output/root/prediccion/ciudad" var="item">
  11. <li>Ciutat: <x:out select="$item/nombre" /></li>
  12. <ul>
  13. <li>Màx.:<x:out select="$item/maxima" /></li>
  14. <li>Mín.:<x:out select="$item/minima" /></li>
  15. </ul>
  16. </x:forEach>
  17. </ul>

A la solució anterior accediu directament a la URL de la pàgina on es troben les dades en format XML. Si ho preferiu podeu afegir directament el fitxer XML de la següent manera:

  1. <c:set var="xmltext">
  2. <root id="08">
  3. <elaborado>2016-03-23T14:01:11</elaborado>
  4. <validez_ini>2016-03-23T00:00:00</validez_ini>
  5. <validez_fin>2016-03-24T00:00:00</validez_fin>
  6. <actualizacion/>
  7. <prediccion>
  8. <txt_prediccion>
  9. <p>
  10. Poco nuboso en general, salvo algunas nubes altas. Temperaturas mínimas en descenso, y sin cambios las máximas. Heladas débiles en el Prepirineo y algún punto del interior. Viento variable flojo con predominio de los oestes.
  11. </p>
  12. </txt_prediccion>
  13. <ciudad>
  14. <id>6908298</id>
  15. <nombre>Vic</nombre>
  16. <minima>1</minima>
  17. <maxima>18</maxima>
  18. </ciudad>
  19. <ciudad>
  20. <id>6908121</id>
  21. <nombre>Mataró</nombre>
  22. <minima>8</minima>
  23. <maxima>17</maxima>
  24. </ciudad>
  25. <ciudad>
  26. <id>6908102</id>
  27. <nombre>Igualada</nombre>
  28. <minima>4</minima>
  29. <maxima>18</maxima>
  30. </ciudad>
  31. <ciudad>
  32. <id>6908307</id>
  33. <nombre>Vilanova i la Geltrú</nombre>
  34. <minima>7</minima>
  35. <maxima>20</maxima>
  36. </ciudad>
  37. <ciudad>
  38. <id>6908113</id>
  39. <nombre>Manresa</nombre>
  40. <minima>3</minima>
  41. <maxima>19</maxima>
  42. </ciudad>
  43. <ciudad>
  44. <id>6908187</id>
  45. <nombre>Sabadell</nombre>
  46. <minima>5</minima>
  47. <maxima>19</maxima>
  48. </ciudad>
  49. <ciudad>
  50. <id>6908019</id>
  51. <nombre>Barcelona</nombre>
  52. <minima>9</minima>
  53. <maxima>17</maxima>
  54. </ciudad>
  55. </prediccion>
  56. </root>
  57. </c:set>

Si escolliu aquesta opció heu d’eliminar la línia:

  1. <c:import var="xmltext" url="http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml"/>

Com obteniu el fitxer XML no té importància, la qüestió és què feu una vegada el teniu. Hem de saber com està construït per poder obtenir les dades correctament, i hem de mirar la seva estructura i decidir com recórrer-la.

Per poder recórrer aquest XML heu de transformar-lo en una estructura amb nodes. Existeix una funció de JSTL que donat un string que conté un XML vàlid crea una estructura en forma d’arbre, molt semblant a l’HTML, però que conté els nodes XML de l’string. La instrucció és la següent:

  1. <x:parse xml="${xmltext}" var="output"/>

Una vegada creat l’arbre amb tots els nodes, XML el guarda a la variable anomenada output. A partir d’ara utilitzareu aquesta variable per accedir a la informació del document XML.

Si observeu l’XML veureu que es repeteixen sempre les etiquetes ciutat amb la informació que us interessa, sempre de la mateixa manera.

Podeu utilitzar un bucle per poder obtenir la informació. En aquest cas utilitzeu un bucle de tipus foreach:

  1. <x:forEach select="$output/root/prediccion/ciudad" var="item">
  2. <li>Ciutat: <x:out select="$item/nombre" /></li>
  3. <ul>
  4. <li>Màx.:<x:out select="$item/maxima" /></li>
  5. <li>Mín.:<x:out select="$item/minima" /></li>
  6. </ul>
  7. </x:forEach>

Aquest bucle accedeix al node ciutat mitjançant la variable output i donat el camí fins a arribar als nodes ciutat. Llavors, per cada node ciutat seleccioneu el nom i la temperatura màxima i la mínima. Les mostreu a l’usuari en forma de llista HTML.

A més a més, us interessa donar la descripció del temps que farà el dia de la predicció. Torneu a utilitzar l’etiqueta output per accedir al text de la predicció de la següent manera:

  1. <x:out select="$output/root/prediccion/txt_prediccion" />

Com veieu, és molt fàcil utilitzar JSTL per tractar la informació d’un fitxer XML. Podeu veure la figura figura per comprovar el resultat de l’execució de la pàgina JSTL.

Figura Resultat de mostrar les dades d’un fitxer XML amb JSTL

A continuació es mostrarà la solució amb JSP. Vegeu un extracte de la solució:

  1. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  2. DocumentBuilder db = dbf.newDocumentBuilder();
  3. Document doc = db.parse("http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml");
  4. Element root = doc.getDocumentElement(); //root element
  5. //Obtenim tots els nodes de tipus ciutat
  6. NodeList llistaCiutats = root.getElementsByTagName("ciudad");
  7. //Recorrem tots els nodes ciutat, un per un
  8. for (int i = 0; i < llistaCiutats.getLength(); i++) {
  9. //Agafem el primer node ciutat ciutat
  10. Node ciutat = llistaCiutats.item(i);
  11. //Agafem tots els nodes on cadascun té les dades de la ciutat (nom, id, màxima, mínima...)
  12. NodeList dades = ciutat.getChildNodes();
  13. //Recorrem tots els nodes de dades
  14. for (int j = 0; j < dades.getLength(); j++) {
  15. //Agafem el primer node
  16. Node n = dades.item(j);
  17. (..mostrar informació de les ciutats..)
  18. }
  19. }

Com veieu, no té res a veure amb JSTL. En aquest cas hem de conèixer a la perfecció l’estructura de l’XML, ja que sou vosaltres qui ha de recórrer l’arbre creat.

Per recórrer l’arbre de nodes XML heu d’accedir a la web on es troba l’XML i convertir-lo en un arbre amb nodes XML per poder tractar amb ell. Això es fa realitzant aquestes instruccions:

  1. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  2. DocumentBuilder db = dbf.newDocumentBuilder();
  3. Document doc = db.parse("http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml");

A partir d’ara ja teniu l’arbre creat a la variable doc. Heu de jugar amb aquest arbre fins a obtenir les dades que us interessa mostrar a la pàgina web. Vegeu que les funcions que us proporciona la classe Document de Java són molt semblants a les funcions del DOM que crea un navegador web en obtenir un HTML.

Utilitzant la variable doc accediu al node principal de l’arbre, i mitjançant aquest node podeu accedir al llistat de nodes ciutat.

  1. Element root = doc.getDocumentElement(); //root element
  2. //Obtenim tots els nodes de tipus ciutat
  3. NodeList llistaCiutats = root.getElementsByTagName("ciudad");

Per accedir al llistat de nodes ciutat observeu que s’utilitza la funció getElementsByTagName, que dóna un llistat amb tots els nodes que tenen com a nom d’etiqueta XML la paraula ciutat.

Una vegada teniu tots els nodes ciutat aneu ciutat per ciutat (node a node) per agafar els nodes fills d’una ciutat. Els nodes fills, si veieu l’XML, us donen la informació de les temperatures d’una ciutat determinada.

  1. for (int i = 0; i < llistaCiutats.getLength(); i++) {
  2. //Agafem el primer node ciutat ciutat
  3. Node ciutat = llistaCiutats.item(i);
  4. //Agafem tots els nodes on cadascun té les dades de la ciutat (nom, id, màxima, mínima...)
  5. NodeList dades = ciutat.getChildNodes();

Ara que ja heu accedit a les dades d’una ciutat les heu de mostrar per pantalla a l’usuari.

  1. //Si és un node buit o bé és l'identificador del node, passem al següent.
  2. if (isTextNode(n) || n.getNodeName().equals("id")) // skip nodes
  3. {
  4. continue;
  5. }
  6. //Si és el node "nombre" posem la paraula ciutat i després el seu valor.
  7. //A més a més, afegim un nou llistat (subllistat) (<ul>) per posar les temperatures
  8. if (n.getNodeName().equals("nombre")) {
  9. %>
  10. <%="<li>Ciutat:" + n.getFirstChild().getNodeValue() + "</li><ul>"%>
  11. <%
  12. } else {
  13. //És el node "mínima o màxima". Mostrem els seus noms seguit dels seus valors.
  14. %>
  15. <%="<li>" + n.getNodeName() + ":" + n.getFirstChild().getNodeValue() + "</li>"%>
  16.  
  17. <%
  18. }
  19. if (n.getNodeName().equals("maxima")) {
  20. //Si és l'ultim node (és a dir, el node màxima) tanquem el subllistat de temperatures.
  21. %>
  22.  
  23. <%="</ul>"%>
  24. <%
  25. }

Al principi feu unes petites comprovacions per tal que el node sigui el que us interessa. Per exemple, no voleu mostrar l’id d’una ciutat, i llavors compareu el nom del node amb el nom de l’etiqueta XML id; si coincideix, es descarta.

També comproveu si el nom del node correspon a l’etiqueta XML nombre. Si és així, mostreu per pantalla el nom de ciutat en comptes de nombre.

Finalment, es mostren les temperatures màximes i mínimes de la ciutat.

A la figura figura podeu veure el resultat de l’execució de la pàgina JSP.

Figura Resultat de mostrar les dades d’un fitxer XML amb JSP