Datan hakeminen muilta sivuilta, SOAP, handlerit ja sivupohja - Demo 9
- RSS-feedin sisällyttäminen omalle sivulle
- HTML-dokumentin osan sisällyttäminen omalle sivulle
- SOAP
- Apache handlerit
- Sivupohjan käyttöönotto
Käytetään muiden tekemiä XML-dokumentteja ja WWW-sivuja tiedonlähteenä. Kokeillaan luoda oma SOAP-palvelu ja testataan sen käyttöä. Tutustutaan Apachen handlereihin ja toteutetaan niiden avulla oma sivupohja.
RSS-feedin sisällyttäminen omalle sivulle
- Aloita uusi PHP-ohjelma. Pyritään hakemaan ja parsimaan XML.comin RSS-feedi ja sisällyttämään siitä tärkeimmät osat omalle sivulle.
- Käsiteltävä RSS-feed löytyy osoitteesta: http://www.oreillynet.com/pub/feed/20?format=rss1. Tutki sivun lähdekoodia niin pääset jyvälle RSS-tiedoston rakenteesta.
-
Haetaan RSS-dokumentti PHP-ohjelmaan käyttäen PHP:n DOM-kirjastoa:
// näytetään kaikki tässä vaiheessa pelkkänä tekstinä header("content-type: text/plain"); $url = "http://www.oreillynet.com/pub/feed/20?format=rss1"; // luodaan uusi dokumentti ja haetaan sen sisältö halutusta osoitteesta $doc = new DomDocument(); $doc->load($url); // tulostetaan koko dokumentti print $doc->saveXML(); - Kaivellaan dokumentista yksittäisiä osia. Haetaan ensimmäiseksi yleistietoja:
// dokumentissa tarvittavat nimiavaruudet $rdf_ns = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; $dc_ns = "http://purl.org/dc/elements/1.1/"; $rss_ns = "http://purl.org/rss/1.0/"; // haetaan dokumentin yleistiedot // täytyy käyttää nimiavaruuksia ymmärtävää versiota // getElementsByTagName-metodista $title = $doc->getElementsByTagNameNS($rss_ns, "title"); $link = $doc->getElementsByTagNameNS($rss_ns, "link"); print $title->item(0)->textContent."\n"; print $link->item(0)->textContent."\n"; - Hae edellä tehtyyn tapaan description, rights ja language -elementit ja tulosta niiden tekstisisältö. Huomaa ottaa käyttöön oikea nimiavaruus ($rss_ns tai $dc_ns).
- Muuta dokumenttisi mediatyypiksi text/html ja poista edellä tehdyt
tulostuslauseet. Kopioi itsellesi pohja.xml-tiedosto. Luo uusi DomDocument ja avaa
tähän pohjaksi pohja.xml-tiedosto:
$oma = new DomDocument(); $oma->load("pohja.xml"); -
Lisää $oma-dokumenttiin RSS-feedistä kaiveltu pääotsikko ja tulosta koko $oma-dokumentti:
// on syytä huomata, että id pitää määritellä // <body xml:id="foo"> // jos dokumentti olisi ladattu komennolla loadHTMLFile niin tavallinen // id="foo" olisi riittänyt $body = $oma->getElementById("foo"); $h1 = $oma->createElement("h1"); $h1->appendChild($oma->createTextNode($title->item(0)->textContent)); $body->appendChild($h1); print $oma->saveXML();Testaa myös selaimella.
- Lisää edellä tehtyyn tapaan pääotsikosta linkki RSS-feedistä saatuun osoitteeseen (link). Lisää myös muiden RSS-feedistä kaivamiesi elementtien sisältö XHTML-dokumenttiisi esim. tekstikappaleina.
- Hae RSS-feedistä kaikki item-elementit. Käy nämä kaikki läpi silmukassa ja luo XHTML-dokumenttiin linkkilista (ul), jossa yksi lista-alkio (li) muodostuu kunkin item-elementin sisältämästä title- ja link-elementistä. Vinkkejä silmukassa tehtäviin toimenpiteisiin löytyy mm. seuraavasta tehtävästä, jossa luodaan myös samantyyppinen silmukka sekä luentoesimerkistä. Katso myös mallikuva.
HTML-dokumentin osan sisällyttäminen omalle sivulle
- HTML-dokumentin parsiminen tapahtuu PHP:ssa aivan samalla tavalla kuin
edellä parsittiin RSS-dokumenttia. Luo uusi PHP-tiedosto
ja hae siihen tiedot IT-tiedekunnan pääsivulta:
$url = "http://www.jyu.fi/it"; $doc = new DomDocument(); $doc->load($url);Kokeile validoida sivu. Huomaat, että sivu ei ole täysin validia XHTML:ää, joten edellä ollut sivun lataus XML:nä ei toimisi.
-
Koska sivu ei ole täysin validia, sivu täytyy ladata HTML-moodissa XML:n sijaan. Säädetään lisäksi asetukset
siten, että sivun suoritus ei jää kesken, vaikka tulisi epävalidi kohta:
$url = "http://www.jyu.fi/it"; // säädöt mahdollisimman löysälle ja ladataan HTML-moodissa $doc = new DomDocument(); $doc->recover = true; $doc->strictErrorChecking = false; $doc->loadHTMLFile($url);Nyt sivun lataus pitäisi onnistua.
- Poimitaan seuraavaksi dokumenttiin tuodulta IT-tiedekunnan pääsivulta "Ajankohtaista tiedekunnassa" -kohdassa olevat aiheet ja linkit.
- Muuta dokumenttisi mediatyypiksi text/html. Luo uusi DomDocument ja avaa siihen pohjaksi sama pohja.xml-tiedosto, jota käytettiin ensimmäisessäkin tehtävässä.
- Lisää dokumenttiin bodyn alle uusi listaelementti (ul). Lisääminen tapahtuu samalla idealla kuin edellisessä tehtävässä lisättiin h1-elementti.
- Hae seuraavaksi dokumenttiin tuodulta IT-tiedekunnan sivulta div-lohko, jonka sisällä "Ajankohtaista tiedekunnassa" on.
Katso sivun lähdekoodia ja mieti, miten saat lohkon parsittua irti muusta sivusta. Lohkosta tarvitaan vain sen sisältämät
li-elementit, joten hae ne seuraavaksi taulukkoon.
$ajankohtaista = $doc->getElementById("dynamicpage-fifth-list"); $tapahtumat = $ajankohtaista->getElementsByTagName("li"); - Käy seuraavaksi foreach-silmukassa läpi löytyneet li-elementit.
- Poimi jokaisen elementin sisältö (getElementsByTagName) ja elementin href-attribuutin sisältö (getAttribute) joihinkin muuttujiin.
- Luo sitten silmukassa uusi a-elementti (createElement) ja liitä sille äsken parsimasi sisältö (appendChild, createTextNode, textContent) ja href-attribuutti (setAttribute).
- Luo silmukassa sen jälkeen uusi li-elementti (createElement) ja liitä sen sisällöksi (appendChild) juuri luomasi a-elementti.
- Liitä lopuksi vielä luomasi li-elementti silmukan ulkopuolella luotuun ul-elementtiin (appendChild).
- Edellisissä kohdissa suluissa on metodeja, joita todennäköisesti tarvitset kyseisissä kohdissa.
- Tulosta lopuksi luomasi sivu, jotta voit tarkastella sitä selaimessa.
Katso myös mallikuva.print $oma->saveXML();
SOAP
Luodaan SOAP-palvelu, jolla voidaan hakea tietokannasta kuvioita.
SoapServer
- Luo Kuvio-tietokanta, ellet ole jo tehnyt sitä viikkotehtävässä 8.
- Luodaan WSDL-dokumentti, jolla kuvataan palvelun käyttämät tietotyypit ja funktiot. Tämä onnistuu helpoiten Eclipsellä. Valitse sitten File | New... | Other... | Web Services | WSDL.
- Anna nimeksi
kuviohaku.wsdl ja kansioksi demo9, namespaceksi http://users.jyu.fi/~OMATUNNUS/sovellukset/demo9/ ja
SOAP-viestien malliksi RPC/literal. Hyväksy muutokset ja katso, että Design-välilehti jää päälle.
- Tarkemmin enkoodaustyypeistä voit lukea dokumentista Which style of WSDL should I use?
- Luodaan perus-WSDL-määritykset lisäämällä ne kaavioon

- Laita portin address-kohtaan http://users.jyu.fi/~OMATUNNUS/sovellukset/demo9/kuviohaku.php.
- Valitse input-tietotyypiksi string.
- Valitse output-tietotyypiksi New.... Valitse Complex type ja anna nimeksi Kuviot. Napauta nuolta.
- Luodaan tietotyyppimääritykset:

- Valitse oikealla Kuviot ja kohta Add Element.
- Napauta elementin tietotyyppiä ja valitse New.... Luo uusi Complex Type -elementti Kuvio.
- Napauta vielä KuvioLista-elementtiä oikealla ja valitse Set Multiplicity | 0..* Zero or more.
- Napauta Kuvio-elementtiä oikealla ja valitse Add Attribute.... Lisää string-tyyppiset attribuutit KuvioNimi ja TiedostoNimi.
- Luo uusi PHP-tiedosto kuviohaku.php. Kopioi siihen VT8:n mallivastauksesta ykköstason hae_kuvio.php-tiedoston koodit.
- Poista koodista header-määritys ja kaikki XML-tulostukset. Siirrä tietokantakysely WSDL:ssäkin määritettyyn funktioon getKuviot($haku). Vaihda request-parametrin tilalle SOAP-kutsusta saatu parametri $haku.
- Luo luokat Kuviot ja Kuvio:
class Kuviot { public $KuvioLista = array(); } class Kuvio { public $KuvioNimi; public $TiedostoNimi; public function __construct($kuvionimi, $tiedostonimi) { $this->KuvioNimi = $kuvionimi; $this->TiedostoNimi = $tiedostonimi; } } - Luo
getKuviot-funktiossa uusi Kuviot-luokan olio$kuviotResponseennen SQL:n fetch-metodeja. Luo tulosrivejä silmukassa läpikäydessä aina uusi Kuvio-olio, jonka konstruktoriin viet tietokannasta tulleet datat. Data on lisättävä UTF-8-muodossa SOAP-vasteen vuoksi. Lisää uusi kuvio-olio Kuviot-olion taulukkoon:$kuvio = new Kuvio(utf8_encode($row["Kuvionimi"]), $row["Tiedostonimi"]); $kuviotResponse->KuvioLista[] = $kuvio; - Palauta funktiosta
$kuviotResponse. - Lisää nyt PHP:n runko-osaan uuden SoapServer-olion luonti. Vie konstruktin parametrina luomasi WSDL-dokumentti kuviohaku.wsdl.
- Lisää addFunction-metodilla palveluun getKuviot-funktio.
- Käsittele handle-metodilla SOAP-pyynnöstä PHP:lle tullut data.
SoapClient
- Luo uusi PHP-tiedosto
soap.php, jossa tulostetaan normaali XHTML-runko. - Lisää body-osaan PHP-koodilohko, jossa luot uudet SoapClient-olion. Vie konstruktoriin parametrina WSDL-dokumentti kuviohaku.wsdl.
- Kysy mitä funktiota ja tyyppejä palvelu tarjoaa. Tämä onnistuu __getFunctions() ja __getTypes()-metodeilla.
- Kutsu getKuviot-metodia parametrilla "harmaa". Tulosta var_dump-funktiolla tuloksena tullut olio.
- Käy läpi
foreach-silmukalla kaikki Kuviot-olion sisällä olevat Kuvio-oliot ja tulosta taulukkoon KuvioNimi ja TiedostoNimi.
Apache handlerit
Apachen handlereilla saadaan helposti otettua käyttöön oma sivupohja tai lisättyä esim. autentikointi kokonaisen sivuston päälle ilman, että tarvitsee tehdä mitään muutoksia yksittäisiin sivuihin.
- Siirrä edellä tekemäsi PHP-tiedostot uuteen demo9-alikansioon webbisivut. Älä siirrä SOAP-tiedostoja, sillä niille emme
tarvitse template-käsittelijää. Lisää webbisivut-kansioon
.htaccess-tiedosto, johon kirjoitat:
# määritellään oman käsittelijän sijainti # korjaa osoite toimivaksi Action oma /~tunnus/cgi-bin/template.php # määrätään .php-päätteisille tiedostoille oma käsittelijä AddHandler oma .php
Action-rivin osoite on puoliabsoluuttinen viite käsittelijäohjelmaan (samaan tapaan kuin uudelleenohjauksessa). - Kirjoitetaan seuraavaksi oman käsittelijän (template.php) runko:
<?php // www-palvelimelta pyydettävän tiedoston polku $file = $_SERVER["PATH_TRANSLATED"]; // käynnistää puskuroinnin eli ottaa talteen kaiken // sen mitä yritetään tulostaa ja antaa template-nimiselle funktiolle käsiteltäväksi ob_start("template"); // käsittelee varsinaisen tiedoston eli suorittaa sen sisältämän mahdollisen // PHP-koodin yms. include($file); // puskurointi loppuu ob_end_flush(); // funktio, joka käsittelee puskuriin kerätyn datan // yksinkertaisimmassa tapauksessa ei tee mitään vaan palauttaa suoraan // puskurin sisällön function template($buffer) { return $buffer; } ?> - Tallenna tiedosto
template.phphtml-hakemiston juuressa olevaan cgi-bin-hakemistoon - Kokeile vieläkö aiemmin tekemäsi PHP-ohjelmat toimivat. Luultavasti
ne eivät toimi, koska template-käsittelijän läpi ajo muuttaa oletuspolkua.
Käy vielä muuttamassa edellisten tehtävien PHP-tiedostoissa ladattavien
XML-tiedostojen suhteelliset polut absoluuttisiksi. Esim.
/omaHOMEpolku/html/sovellukset/demo9/webbisivut/pohja.xml
- Muuta template-funktiota sen verran, että se lisää jonkin
merkkijonon puskurissa tulleeseen dataan, niin pääset toteamaan, että käsittelijä
todella toimii:
return $buffer." Kyllä toimii";Tarkista selaimella näkyykö lisätty teksti sivun lähdekoodissa (View | Page Source).
- Omalla käsittelijällä voidaan nyt rakentaa kaikkien PHP-tiedostojen päälle esim. autentikointi tai lisätä yhtenäiset navigointilinkit (sivupohja).
Sivupohjan käyttöönotto
- DOM-rajapinnan ja oman käsittelijän avulla on helppoa liittää puskuriin tullut dokumentti omaan sivupohjaan. Kopioi käyttöösi valmis sivupohja.
- Lisää template-funktioon DOM-rajapinnan avulla seuraavat
toiminnot:
- Luo uusi DOMDocument, johon lataat pohjaksi sivupohjan.
- Luo toinen DOMDocument, johon lataat puskurissa tulleen dokumentin (loadXML).
- Hae puskurissa tulleesta dokumentista title-elementin tekstisisältö ja kopioi
se sivupohjadokumenttiisi title-elementin sisällöksi.
Tarviset DOMDocumentin metodeja ja ominaisuuksia:
- getElementsByTagName
textContent(PHP:ssa read-only)- appendChild
- createTextNode
- Hae puskuroidusta dokumentista body-elementti ja importoi se sivupohjadokumenttiin ($doc->importNode($node, true)).
- Lisää jokainen puskuroidun dokumentin body-elementin lapsisolmu sivupohjadokumentin body-elementin sisälle.
Helpoiten siirto onnistuu while-silmukalla, firstChild-ominaisuudella ja
appendChild-metodilla.
Mieti miksi
childNodes-listan läpikäyminen for-silmukassa olisi hankalaa? - Palauta lopuksi returnilla sivupohjadokumentti, johon on nyt sisällytetty kaikki sisältö, mitä puskuroidusta dokumentista löytyi.
- Kokeile selaimella miten ohjelmassasi on nyt navigointilinkistö.


Käyttäjien kommentit