13. Pintaa syvemmältä 233

Samankaltaiset tiedostot
Taustaa. CGI-ohjelmointi

OPPITUNTI 19 Tilan tallentaminen evästeiden ja kyselymerkkijonojen avulla

OPPITUNTI 3 Ensimmäinen skripti

Ohjelmoinnin perusteet Y Python

Ohjeita peda.net palvelun Luo uusi osioon

Harjoitustyö: virtuaalikone

3.1 Mitä tarkoittaan heredoc? Milloin sitä kannattaa käyttää? Kirjoita esimerkki sen käyttämisestä.

Julkinen. Suomen Pankin ja Finanssivalvonnan suojattu sähköposti: ulkoisen käyttäjän ohje

AJAX-konsepti AJAX. Asynkronisuus. Nykyisten web-ohjelmien ongelmia. Asynchronous JavaScript And XML

T Hypermediadokumentin laatiminen. Sisältö. Tavoitteet. Mitä on www-ohjelmointi? Arkkitehtuuri (yleisesti) Interaktiivisuuden keinot

K U U L A L A A K E R I LUOTTAMUKSELLINEN 1(6)

Ohjelmoinnin perusteet Y Python

Julkinen. Suomen Pankin ja Finanssivalvonnan suojattu sähköposti: ulkoisen käyttäjän ohje

Ohjelmoinnin perusteet Y Python

SeaMonkey pikaopas - 1

Digitaalisen median tekniikat, k2004 HY/TKTL, palvelinohjelmointi_1 21/04/2004. Harri Laine 1. Palvelinohjelmointi. Staattinen www-sivu

Miten Internet toimii. Tuomas Aura T Johdatus tietoliikenteeseen kevät 2013

Digitaalisen median tekniikat. Palvelinohjelmointi Harri Laine 1

Digitaalisen median tekniikat. Palvelinohjelmointi

OPPITUNTI 21 Palvelinympäristö

Harri Laine 1. Digitaalisen median tekniikat, s2007 HY/TKTL, palvelinohjelmointi_1. Palvelinohjelmointi

ASCII-taidetta. Intro: Python

WWW-sivu. Miten Internet toimii? World Wide Web. HTML-koodi. HTTP-istunto URL <#>

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Ohjelmoinnin perusteet Y Python

OPPITUNTI 11 DBM-funktioiden käyttö

OPPITUNTI 5 Ohjelman kulku

5. HelloWorld-ohjelma 5.1

Harjoituksen aiheena on tietokantapalvelimen asentaminen ja testaaminen. Asennetaan MySQL-tietokanta. Hieman linkkejä:

OpeOodi Opiskelijalistojen tulostaminen, opiskelijoiden hallinta ja sähköpostin lähettäminen

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

Verkkosivut perinteisesti. Tanja Välisalo

Ohjelmoinnin perusteet Y Python

MITÄ JAVASCRIPT ON?...3

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Lyseopaneeli 2.0. Käyttäjän opas

6. Funktiot 85. Kuinka funktioita määritellään ja kutsutaan. Kuinka funktioille viedään arvoja ja niistä palautetaan arvoja

NÄIN TEET VIDEO-MAILIN (v-mail)

Suvi Junes Tietohallinto / Opetusteknologiapalvelut 2012

KServer Etäohjaus Spesifikaatio asiakaspuolen toteutuksille

WWW-PALVELUN KÄYTTÖÖNOTTO LOUNEA OY

Hops-ohjaajan ohje Opiskelijan hopsit.

OPPITUNTI 10 Tiedostojen käsittely

Ohjelmoinnin perusteet Y Python

OPPITUNTI 20 Tilan tallentaminen istuntofunktioilla

SSH Secure Shell & SSH File Transfer

Sosiaalihuollon asiakastiedon arkiston validointipalvelu. Käyttöohje

Sonera Viestintäpalvelu VIP VIP Laajennettu raportointi Ohje

EKP:N HANKINTAMENETTELYJEN VERKKOPALVELU OSALLISTUMINEN HANKINTAMENETTELYIHIN

Ilmoitus saapuneesta turvasähköpostiviestistä

6. Valitse avautuneesta ikkunasta Add-painike!

Ohjelmoinnin perusteet Y Python

Luento 5. Timo Savola. 28. huhtikuuta 2006

ALVin käyttöohjeet. Kuvaus, rajaus ja tallennus puhelimella ALVin -mobiilisovelluksen avulla dokumentit kuvataan, rajataan ja tallennetaan palveluun.

Kotisivuohjeet. Eteläpohjalaiset Kylät ry. Sivupohjien rakenne

Sivuston tiedotakcpshop.de.websiteoutlook.com

Sivuston tiedotmysiteworthcheck.com

MOBISITE-TYÖKALUN SISÄLTÄMÄT TOIMINNOT

Kypsyysnäytteen laatiminen ja arvioiminen Examissa

Maastotietokannan torrent-jakelun shapefile-tiedostojen purkaminen zip-arkistoista Windows-komentojonoilla

Android. Sähköpostin määritys. Tässä oppaassa kuvataan uuden sähköpostitilin käyttöönotto Android Ice Cream Sandwichissä.

Ohjelmoinnin perusteet Y Python

1 PHP-sovelluksen toiminta

Zeon PDF Driver Trial

Käytin tehtävän tekemiseen Xubuntu käyttöjärjestelmää aikaisemmin tekemältäni LiveUSB-tikulta.

Pedanet oppilaan ohje Aleksanteri Kenan koulu Eija Arvola

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Enigmail-opas. Asennus. Avainten hallinta. Avainparin luominen

ohjeita kirjautumiseen ja käyttöön

Sosiaalihuollon asiakastiedon arkiston validointipalvelu

Webforum. Version 15.1 uudet ominaisuudet. Päivitetty:

Webinaariin liittyminen Skype for

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {

@PHPOINT Sähköpostitilin asetukset

Kypsyysnäytteen laatiminen ja arvioiminen Examissa

Sivuston tiedotqbsupportcustom erservice.com

OSA III PHP:n käyttö. Oppitunti

TEHTÄVIEN PALAUTTAMINEN MOODLEEN

Olet tehnyt hyvän valinnan hankkiessasi kotimaisen StorageIT varmuuskopiointipalvelun.

Drupal-sivuston hallintaopas

Outlook Web App ver 1.2

VIENET JULKAISUJÄRJESTELMÄLLÄ TOTEUTETTUJEN INTERNET-SIVUJEN YLLÄPITO-OHJE

Ohjelmoinnin perusteet Y Python

Open Badge -osaamismerkit

Yhdistäminen. Tietolähteen luominen. Word-taulukko. Joukkokirje, osoitetarrat Työvälineohjelmistot 1(5)

Internet ja tietoverkot 2015 Harjoitus 7: Kertaus

Oma kartta Google Maps -palveluun

Sivuston tiedotsiteoptimer.com

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

Ohjeistus yhdistysten internetpäivittäjille

DNA Toimistoviestintä Microsoft - sähköposti

Oppilaan opas. Visuaaliviestinnän Instituutti VVI Oy. Versio 0.2 ( )

Sähköposti ja uutisryhmät

Ohjeet e kirjan ostajalle

1.1 Internetistä lyhyesti. Mikä Internet on? 1.2 Maailmanlaajuinen verkko

OpeOodi Opiskelijalistojen tulostaminen, opiskelijoiden hallinta ja sähköpostin lähettäminen

VERKKOSOVELLUSTEN OHJELMOINTI, JOHDATUS PHP:HEN

Sähköpostitilin käyttöönotto

Ohjelmoinnin perusteet Y Python

Transkriptio:

13. Pintaa syvemmältä 233 OPPITUNTI 13 Pintaa syvemmältä Tällä tunnilla tutkimme joitakin funktioita, joilla saamme informaatiota ympäristöstä tai kommunikoimme ulkoisen maailman kanssa. Tämän tunnin aiheita ovat seuraavat: Lisätietoa ympäristömuuttujista HTTP-yhteyden rakenne Asiakirjan saaminen etäpalvelimelta Oman HTTP-yhteyden luominen Muiden verkkopalvelujen käyttäminen Sähköpostin lähettäminen skripteistä käsin

234 13. Pintaa syvemmältä Ympäristömuuttujat Olet jo kohdannut joitakin ympäristömuuttujia, jotka PHP antaa käyttöön palvelinyhteyden syntyessä. Joidenkin muuttujien kautta saadaan tietoa käyttäjistä. On kuitenkin muistettava, että jotkut muuttujat eivät välttämättä ole saatavilla järjestelmässäsi tai palvelinohjelmistosi kautta, joten tilanne kannattaa tarkistaa skripteissä ennen käyttöä. Taulukko 13.1 luettelee joitakin muuttujia, jotka saattavat olla hyödyllisiä haluttaessa saada tietoa käyttäjistä. Taulukko 13. Ympäristömuuttujia. Muuttuja Tarkoitus $HTTP_REFERER URL, josta nykyistä skriptiä kutsuttiin $HTTP_USER_AGENT Tietoa selaimesta ja alustasta, jota vierailija käyttää $HTTP_ADDR Vierailijan IP-osoite $HTTP HOST Vierailijan isäntänimi QUERY_STRING Koodattu merkkijono, joka on URL:n perässä (muoto on?avain1=arvo1&avain2=arvo2). Nämä avaimet ja arvot tulevat skriptiesi käyttöön globaaleina muuttujina. $PATH_INFO Lisätietoa, joka voi liittyä URL:ään Listaus 13.1 muodostaa skriptin, joka tulostaa näiden muuttujien sisällön selaimelle. Listaus 13.1 Joidenkin ympäristömuuttujien listaaminen 1: <html> 2: <head> 3: <title>listing 13.1 Listing some environmental variables</title> 4: </head> 5: <body> 6: <?php 7: $envs = array( "HTTP_REFERER", "HTTP_USER_AGENT", "REMOTE_ADDR", "REMOTE_ HOST", "QUERY_STRING", "PATH_INFO" ); 8: foreach ( $envs as $env ) 9: { 10: if ( isset( $$env ) ) 11: print "$env: ${$env}<br>"; 12: } 13:?> 14: </body> 15: </html>

13. Pintaa syvemmältä 235 Huomaa, että käytimme dynaamisia muuttujia muuntamaan merkkijonot samannimisiksi muuttujiksi. Tätä tekniikkaa tutkimme luvussa 4, Lohkojen rakentaminen. Kuva 13.1 esittää listauksen 13.1 tulostuksen. Kuvan 13.1 tieto generoitiin, kun skriptiä kutsuttiin toisella sivulla olevasta linkistä käsin. Kutsulinkki näytti seuraavalta: <A HREF='eg13.1.php/my_path_info?query_key=query_value'>go</A> Kuten näet, linkki käyttää suhteellista polkua kutsuessaan tiedostoa listing13.1.php. Lisätietoa polusta (my_path_info) lisätään asiakirjan nimen perään; lisätieto on muuttujassa $PATH_INFO. Olemme laittaneet kyselymerkkijonon (query string) tekstinä suoraan linkkiin ja se on saatavilla muuttujassa $QUERY_STRING. Useimmiten käytät kyselymerkkijonoa silloin, kun lomake lähetetään GET-metodilla, mutta voit tietenkin aina rakentaa omia kyselymerkkijonojasi viedäksesi informaatiota sivulta toiselle. Kyselymerkkijono koostuu nimi/arvo-pareista, jotka erotetaan toisistaan et-merkeillä (&). Nuo parit on URLkoodattu, jolloin jokainen laiton merkki tai merkki, jolla on HTML-merkitys, kirjoitetaan heksadesimaalimuodossa. Vaikka koko kyselymerkkijono on ympäristömuuttujassa $QUERY_STRING, tarvitset sitä harvoin. Jokainen avaimen nimi muodostaa aina oman globaalin muuttujansa, jonka sisällä on vastaava arvonsa. KUVA 13.1 Joidenkin ympäristömuuttujien tulostaminen selaimelle. Ympäristömuuttuja $HTTP_REFERER voi olla hyödyllinen, jos haluat seurata, mistä linkeistä käsin skriptisi suoritetaan. Muista kuitenkin, että tämä ja muut ympäristömuuttujat voidaan helposti kumota. Saat lisätietoa asiasta myöhemmin tässä luvussa. Koska asian korjaaminen aiheuttaisi yhteensopivuusongelmia, meidän on pysyttäydyttävä virheellisessä referrer -kirjoitustavassa. Kaikki selaimet eivät tue tätä otsikkoa, joten sen varaan ei kannata laskea liikaa. Voit jäsennellä $HTTP_USER_AGENT-muuttujan saadaksesi esille alustan ja selaimen. Tämäkin muuttuja voidaan kumota. Muuttuja voi olla hyödyllinen, jos haluat käyttää selain- tai selainversiokohtaista HTMLkoodia tai JavaScript-koodia. Luvussa 17, Merkkijonojen käsittely, ja luvussa 18, Säännöllisten lausekkeiden käyttäminen, sinulle annetaan työkaluja, joilla voit ottaa esille haluamasi tiedot tästä merkkijonosta. Ympäristömuuttuja $REMOTE_ADDR sisältää käyttäjän IP-osoitteen ja sillä voidaan jäljittää vierailijoita. Muista kuitenkin, että monilla Web-käyttäjillä ei ole kiinteää IP-osoitetta. Sen sijaan heidän Internetpalveluntarjoajansa antavat heille dynaamiset IP-osoitteet kytkeytymisen yhteydessä. Sama IP-osoite voi siis olla eri käyttäjien käytössä eri aikoina. $REMOTE_HOST ei ehkä ole käytettävissä; asia riippuu palvelinasetuksista. Muuttujaan tallennetaan käyttäjän isäntänimi. Muuttujan läsnäolo vaatii sen, että palvelin hakee isäntänimen jokaiselle pyynnölle, joten

236 13. Pintaa syvemmältä muuttuja on ehkä otettu pois käytöstä tehokkuussyistä. Jos muuttuja ei ole saatavilla, voit saada vastaavat tiedot esille muuttujan $REMOTE_ADDR-arvon kautta. Asiaa käsitellään tarkemmin myöhemmin tässä luvussa. Lyhyt yhteenveto asiakas/palvelin-keskustelusta Palvelimen ja asiakkaan välinen tiedonsiirto asiakaspyynnön tekemisen yhteydessä on tämän kirjan aihealueen ulkopuolella. Lisäksi PHP hoitaa useimmat asiaan liittyvät detaljit puolestasi. Sinun on kuitenkin hyvä tietää perusasiat tästä prosessista, etenkin, jos aiot kirjoittaa skriptejä, jotka noutavat Web-sivuja tai tarkistavat Web-osoitteiden tilan. HTTP tulee sanoista Hypertext Transfer Protocol. Kyseessä on joukko sääntöjä, jotka määrittelevät prosessin, jossa asiakas lähettää pyynnön ja palvelin palauttaa vastauksen. Sekä asiakas että palvelin antavat informaatiota itsestään sekä siirrettävästä tiedosta. Suuri osa tuosta tiedosta on saatavilla ympäristömuuttujissa. Pyyntö Asiakas pyytää tietoa palvelimelta tiettyjen tarkkojen sääntöjen puitteissa. Pyyntö koostuu kolmesta eri komponentista: Pyyntörivistä Otsikko-osasta Tietoyksiköstä Pyyntörivi on pakollinen. Se koostuu pyyntömetodista, joka on tyypillisesti GET, HEAD tai POST, pyydettävän asiakirjan osoitteesta ja HTTP-versiotiedoista (HTTP/1.0 tai HTTP/1.1). Tyypillinen mydoc.html-nimisen asiakirjan pyyntö saattaisi näyttää seuraavalta: GET /mydoc.html HTTP/1.0 Asiakas tekee GET-pyynnön. Toisin sanoen se pyytää koko asiakirjaa, mutta ei lähetä itse mitään tietoa (itse asiassa se voi lähettää pieniä määriä tietoa GET-pyyntöjen yhteydessä lisäämällä kyselymerkkijonon URL:n perään). HEAD-metodi voi olla hyödyllinen, jos haluat vain tietoa asiakirjasta. POST-metodia käytetään siirtämään tietoa asiakkaalta palvelimelle; useimmiten on kyseessä HTML-lomake. Pelkkä pyyntörivi riittää tekemään sopivan GET-pyynnön. Lähettämällä palvelimelle tyhjä rivi kerrotaan, että pyyntö on tehty. Useimmat asiakkaat lisäävät pyyntörivin jälkeen otsikko-osan, jossa on nimi/arvo-pareja. Jotkut noista tiedoista ovat saatavilla ympäristömuuttujissa. Kukin asiakkaan otsikko koostuu rivillä olevasta avaimesta ja arvosta; erottimena on kaksoispiste. Taulukko 13.2 luettelee muutamia otsikkotietoja. Taulukko 13.2 Joitakin asiakkaan lähettämiä otsikoita Nimi Selitys Accept Asiakkaan hyväksymät mediatyypit Accept-Encoding Asiakkaan hyväksymät tiedon tiivistämistavat Accept-Charset Asiakkaan ensisijaiset merkistöt

13. Pintaa syvemmältä 237 Accept-Language Host Referer User-Agent Asiakkaan ensisijainen kieli ( en tarkoittaa englannin kieltä) Isäntäkone, johon pyyntö kohdistuu. Jotkin palvelimet, joilla on useita virtuaalipalvelimia, tukeutuvat voimakkaasti tähän otsikkoon. Asiakirja, josta käsin pyyntö tehtiin Asiakastyyppi ja versio GET- ja POST-metodien kohdalla otsikkojaksot päättävät pyynnön ja tyhjä rivi lähetetään lopuksi palvelimelle. POST-metodia käytettäessä tyhjän rivin jälkeen on yksikön runko. Se koostuu kaikesta palvelimelle lähetettävästä tiedosta. Useimmiten kyseessä on URL-koodattuja nimi/arvo-pareja, jotka ovat samanlaisia kuin kyselymerkkijonossa. Listaus 13.2 esittää pyynnön palvelimelle Netscapen 4.6-selaimella. Listaus 13.2 Tyypilliset asiakkaan otsikkotiedot lähetettyina Netscape-selaimella GET / HTTP/1.0 Referer: http://zink.demon.co.uk:8080/matt/php-book/network/test2.php Connection: Keep-Alive User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc) Host: www.corrosive.co.uk Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 Vastaus Kun palvelin on saanut asiakkaan pyynnön, se lähettää vastauksen takaisin asiakkaalle. Vastaus koostuu yleensä kolmesta osasta: Tilarivistä Otsikko-osasta Yksikön rungosta Kuten näet, pyynnön ja vastauksen välillä on paljon yhteneväisyyksiä. Itse asiassa tietyt otsikot voidaan lähettää joko asiakkaan tai palvelimen toimesta, erityisesti yksikön runkoa koskevat tiedot. Tilarivi koostuu HTTP-versiosta, jota palvelin käyttää (HTTP/1.0 tai HTTP/1.1), vastauskoodista ja viestistä, joka kertoo vastauskoodin merkityksen. Palvelin voi lähettää asiakkaalle useita eri vastauskoodeja. Kukin koodi antaa tietoa pyynnön käsittelyn onnistumisesta. Taulukko 13.3 luettelee joitakin yleisiä vastauskoodeja.

238 13. Pintaa syvemmältä TAULUKKO 13.3 Joitakin vastauskoodeja Koodi Teksti Selitys 200 OK Pyyntö onnistui, ja tieto tulee mukana. 301 Moved permanently Pyydettyä tietoa ei enää ole palvelimella. Sijaintiotsikossa (location) on uusi osoite. 302 Moved temporarily Pyydetty tieto on siirretty. Sijaintiotsikossa (location) on uusi osoite. 404 Not Found Tietoa ei löydy annetusta osoitteesta. 500 Internal Server Error Palvelin tai CGI-skripti on kohdannut vakavan ongelman yrittäessään käsitellä tietoa. Tyypillinen vastausrivi näyttää seuraavalta: HTTP/1.1 200 OK Otsikko-osa sisältää joukon vastausotsikoita, jotka on muotoiltu samalla lailla kuin pyynnön otsikot. Taulukko 13.4 luettelee joitakin otsikoita, jotka palvelin lähettää. Taulukko 13.4 Joitakin yleisiä palvelinotsikoita Nimi Tarkoitus Date Nykyinen päivämäärä Server Palvelimen nimi ja versio Content-Type Sisällön MIME-tyyppi Content-Length Sisällön koko tavuina Location Vaihtoehtoisen asiakirjan koko osoite Sen jälkeen kun otsikot on lähetetty, palvelin lähettää tyhjän rivin asiakkaalle; tyhjän rivin jälkeen tulee itse sisältö eli haettava kohde. Listaus 13.3 esittää tyypillisen palvelinvastineen. LISTAUS 13.3 Palvelinpyyntö 1: HTTP/1.1 200 OK 2: Date: Sun, 30 Jan 2000 18:02:20 GMT 3: Server: Apache/1.3.9 (UNIX) 4: Connection: close 5: Content-Type: text/html 6: 7: <html> 8: <head> 9: <title>listing 13.3 A server response</title> 10: </head>

13. Pintaa syvemmältä 239 11: <body> 12: Hello 13: </body> 14: </html> Asiakirjan saaminen etäosoitteesta Vaikka PHP onkin palvelinpuolen kieli, se voi toimia asiakkaana ja pyytää tietoa etäpalvelimilta sekä laittaa tulokset skriptiesi saataville. Jos osaat jo lukea tiedostoja palvelimelta, sinulla ei ole mitään vaikeuksia käyttää PHP:tä tiedon saamiseen Webistä. Itse asiassa syntaksi on aivan sama. Voit käyttää fopen()- funktiota luodaksesi yhteyden Web-osoitteeseen samalla lailla kuin tiedostojen kohdalla. Listaus 13.4 avaa yhteyden etäpalvelimelle ja pyytää sivua sekä esittää tulokset selaimelle. Listaus 13.4 Web-sivun sieppaaminen fopen()-funktiolla 1: <html> 2: <head> 3: <title>listing 13.4 Getting and printing a web page with fopen()</title> 4: </head> 5: <body> 6: <?php 7: $webpage = "http://www.corrosive.co.uk/php/hello.html"; 8: $fp = fopen( $webpage, "r" ) or die("couldn't open $webpage"); 9: while (! feof( $fp )) 10: print fgets( $fp, 1024 ); 11:?> 12: </body> 13: </html> Kun skripti ajetaan, tuloksena tulisi olla PHP-kotisivu. Huomaa, että sivulla olevat kuvat eivät näy. Se johtuu siitä, että IMG-elementeissä olevat polut kuviin ovat yleensä suhteellisia. Kun skripti tulostaa lataamansa tiedon, käyttäjän selain hakee palvelimelta viitattuja kuvia. Voisimme ohittaa tuon ongelman lisäämällä seuraavan tagin skriptin HEAD-elementtiin: <base href="http://www.php.net"> Yleensä et varmaankaan halua tulostaa koko sivua selaimelle. Useimmiten haluat jäsennellä lataamaasi asiakirjaa. Funktio fopen() palauttaa tiedosto-osoittimen, jos yhteyden luonti onnistuu ja arvon false, jos yhteyttä ei voitu luoda tai sivua ei ole olemassa. Kun olet saanut tiedosto-osoittimen, voit käyttää sitä

240 13. Pintaa syvemmältä normaalisti tiedoston lukemiseen. PHP esittelee itsensä etäpalvelimelle asiakkaana. Omassa järjestelmässäni se lähettää seuraavan pyynnön: GET / HTTP/1.0 Host: www.php.net User-Agent: PHP/4.0b3 Tämä prosessi on yksinkertainen ja juuri tätä lähestymistapaa käytät useimmiten Web-sivujen käsittelyssä. Saatat haluta kytkeytyä kuitenkin muihin verkkopalveluihin tai oppia enemmän Web-asiakirjasta jäsentelemällä palvelinotsikoita. Asiaa käsitellään myöhemmin tässä luvussa. IP-osoitteiden ja isäntänimien muuntaminen Vaikka palvelimesi ei sallisikaan $REMOTE_HOST-muuttujan käyttöä, saat luultavasti tietää vierailijan IPosoitteen $REMOTE_ADDR-ympäristömuuttujan avulla. Voit käyttää sitä gethostbyaddr()-funktion selvittämään käyttäjän koneen nimi. Funktio ottaa argumentikseen merkkijonon, joka edustaa IP-osoitetta ja palauttaa isäntänimen. Jos virhe tapahtuu, se palauttaa annetun IP-osoitteen. Listaus 13.5 sisältää skriptin, joka käyttää gethostbyaddr()-funktiota koneen nimen selville saamiseen siinä tapauksessa, että $REMOTE_HOST-muuttuja ei ole saatavilla. Listaus 13.5 Funktion gethostbyaddr() käyttö koneen nimen selvittämiseen 1: <html> 2: <head> 3: <title>listing 13.5 Using gethostbyaddr() to get a host name</title> 4: </head> 5: <body> 6: <?php 7: if ( isset( $REMOTE_HOST ) ) 8: print "Hello visitor at $REMOTE_HOST<br>"; 9: elseif ( isset ( $REMOTE_ADDR ) ) 10: print "Hello visitor at ".gethostbyaddr( $REMOTE_ADDR )."<br>"; 11: else 12: print "Hello you, wherever you are<br>"; 13:?> 14: </body> 15: </html>

13. Pintaa syvemmältä 241 Jos $REMOTE_HOST on saatavilla, voimme yksinkertaisesti vain tulostaa sen arvon selaimelle. Muutoin, jos saatavilla on $REMOTE_ADDR-muuttuja, yritämme selvittää koneen nimen gethostbyaddr()-funktiolla. Jos epäonnistumme, tulostamme yleisen tervetulotoivotuksen. Voit muuntaa konenimen IP-osoitteeksi funktiolla gethostbyname(). Tuo funktio vaatii argumentikseen konenimen ja palauttaa IP-osoitteen. Jos virhe tapahtuu, se palauttaa argumenttina olleen koneen nimen. Verkkoyhteyden toteuttaminen Toistaiseksi kaikki on ollut helppoa, sillä PHP:n ansiosta etäpalvelimella olevaa Web-sivua voidaan työstää yhtä helposti kuin omassa järjestelmässä olevaa sivua. Joskus on kuitenkin oltava hieman tarkempi verkkoyhteyden suhteen tai ainakin saatava siitä enemmän tietoa. Yhteys Internet-palvelimelle voidaan toteuttaa fsockopen()-funktiolla, joka vaatii isäntänimen tai IPosoitteen, portin numeron ja kaksi viittausmuuttujaa. Muista, että viittaus toteutetaan sijoittamalla et-merkki muuttujan nimen eteen. Viittausmuuttujat, jotka viedään fsockopen()-funktiolle, tallentavat lisätietoa yhteyden yrityksestä, jos yhteydenotto ei onnistu. Funktiolle voidaan myös viedä valinnainen aikaraja, joka määrittää, kuinka kauan fsockopen() odottaa (sekunneissa) ennen kuin se lopettaa yhteydenoton yrittämisen. Jos yhteys onnistuu, palautetaan tiedosto-osoitin. Muutoin palautetaan false-arvo. Seuraava koodi alustaa yhteyden Web-palvelimelle: $fp = fsockopen( "www.corrosive.co.uk", 80, &$errno, &errdesc, 30 ); Arvo 80 on tavallinen porttinumero, jota Web-palvelin kuuntelee. Ensimmäinen viittausmuuttuja $errno sisältää virhenumeron, jos yhteys ei onnistu, ja $errdesc voi sisältää lisätietoa virheestä. Kun tiedosto-osoitin on saatu, voit sekä kirjoittaa yhteyteen fputs()-funktiolla että lukea siitä fgets()-funktiolla, kuten tiedostojen kohdalla yleensä tehtäisiin. Kun yhteyttä ei enää tarvita, se lopetetaan fclose()-funktiolla. Meillä on nyt tarpeeksi tietoa alustaaksemme oman yhteytemme Web-palvelimelle. Listaus 13.6 toteuttaa http-yhteyden, palauttaa sivun ja tallentaa sen muuttujaan. Listaus 13.6 Web-sivun palauttaminen fsockopen()-funktiolla 1: <html> 2: <head> 3: <title>listing 13.6 Retrieving a Web page using fsockopen()</title> 4: </head> 5: <body> 6: <?php 7: $host = "www.corrosive.co.uk"; 8: $page = "/index.html"; 9: $fp = fsockopen( "$host", 80, &$errno, &$errdesc); 10: if (! $fp )

242 13. Pintaa syvemmältä 11: die ( "Couldn't connect to $host:\nerror: $errno\ndesc: $errdesc\n" ); 12: 13: $request = "GET $page HTTP/1.0\r\n"; 14: $request.= "Host: $host\r\n"; 15: $request.= "Referer: http://www.corrosive.co.uk/refpage.html\r\n"; 16: $request.= "User-Agent: PHP test client\r\n\r\n"; 17: $page = array(); 18: fputs ( $fp, $request ); 19: while (! feof( $fp ) ) 20: $page[] = fgets( $fp, 1024 ); 21: fclose( $fp );print "the server returned ".(count($page))." lines!"; 22:?> 23: </body> 24: </html> Huomaa pyyntöotsikot, jotka lähetetään palvelimelle. Etäkoneen hallintahenkilö näkee arvon, joka lähetetään User-Agent-otsikossa omassa kirjaustiedostossaan. Hän voi myös olettaa, että vierailija kytkeytyi osoitteesta http://www.corrosive.co.uk/refpage.html. Siitä syystä joidenkin ympäristömuuttujien suhteen on oltava varovainen. Kohtele niitä tukevina aputyökaluina, älä aseta niille liikaa painoarvoa. On joitakin hyväksyttyjä syitä, joiden vuoksi saattaisit haluta muokata joitakin otsikoita. Sinun on ehkä jäsenneltävä jotain tietoa, joka lähetetään vain Netscape-yhteensopiville selaimille. Ainoa keino tehdä se on sisällyttää sana Mozilla User-Agent-otsikkoon. Kaikesta huolimatta kannattaa pitää hallintahenkilön puolta. Toimintaan vaikuttavat päätökset tehdään palvelintilastojen pohjalta, joten älä yritä sotkea tuota informaatiota. Listauksen 13.6 esimerkki pelkästään käyttää PHP:n sisäisiä metodeita Web-sivun saamiseen. Listaus 13.7 käyttää fsockopen()-funktiota tarkistamaan tilakoodit, joita palvelimet palauttavat, kun pyydämme joukon sivuja. Listaus 13.7 Web-palvelimien palauttamien tilarivien tulostaminen 1: <html> 2: <head> 3: <title>listing 13.7 Outputting the status lines returned by web servers</ title> 4: </head> 5: <body> 6: <?php 7: $to_check = array ( "www.corrosive.co.uk" => "/index.html",

13. Pintaa syvemmältä 243 8: "www.virgin.com" => "/notthere.html", 9: "www.4332blah.com" => "/nohost.html" 10: ); 11: foreach ( $to_check as $host => $page ) 12: { 13: $fp = fsockopen( "$host", 80, &$errno, &$errdesc, 10); 14: print "Trying $host<br>\n"; 15: if (! $fp ) 16: { 17: print "Couldn't connect to $host:\n<br>error: $errno\n<br>desc: $errdesc\n"; 18: print "<br><hr><br>\n"; 19: continue; 20: } 21: print "Trying to get $page<br>\n"; 22: fputs( $fp, "HEAD $page HTTP/1.0\r\n\r\n" ); 23: print fgets( $fp, 1024 ); 24: print "<br><br><br>\n"; 25: fclose( $fp ); 26: } 27:?> 28: </body> 29: </html> Loimme assosiatiivisen taulukon palvelinten nimistä ja sivuosoitteista, jotka halusimme tarkistaa. Kävimme taulukon läpi silmukan foreach-lauseella. Jokaisen alkion kohdalla alustimme yhteyden fsockopen()- funktiolla asettaen aikarajaksi 10 sekuntia. Jos yhteys epäonnistuu, tulostamme viestin selaimelle ja käytämme continue-lausetta seuraavaan pariin siirtymiseksi. Jos yhteys onnistuu, lähetämme pyynnön palvelimelle. Käytämme HEAD-metodia, koska emme halua jäsennellä koko runkoa. Funktiolla fgets() saamme tilarivin palvelimelta. Tässä esimerkissä emme käsittele palvelinotsikoita, joten suljemme yhteyden fclose()-funktiolla ja siirrymme listan seuraavaan alkioon. Kuva 13.2 näyttää lisauksen tulostuksen.

244 13. Pintaa syvemmältä KUVA 13.2 Skripti tulostaa palvelimen vastausotsikot. NNTP-yhteyden luominen fsockopen()-funktiolla Fsockopen()-funktiota voidaan käyttää yhteyden luomiseen mille tahansa Internet-palvelimelle. Listauksessa 13.8 luodaan yhteys NNTP-palvelimelle, joka on siis Usenet-keskusteluryhmäpalvelin. Esimerkki valitsee keskusteluryhmän ja listaa ensimmäisen viestin otsikot. Listaus 13.8 NNTP-perusyhteyden luominen fsockopen()-funktiolla 1: <html> 2: <head> 3: <title>listing 13.8 A basic NNTP connection using fsockopen()</title> 4: </head> 5: <body> 6: <?php 7: $server = "news"; // anna oma news-palvelimesi 8: $group = "alt.test"; 9: $line = ""; 10: print "<pre>\n"; 11: print "-- Trying to connect to $server\n\n"; 12: $fp = fsockopen( "$server", 119, &$error, &$description, 10 ); 13: if (! $fp ) 14: die("couldn't connect to $server\n$errno\n$errdesc\n\n"); 15: print "-- Connected to $server\n\n"; 16: $line = fgets( $fp, 1024 ); 17: $status = explode( " ", $line ); 18: if ( $status[0]!= 200 )

13. Pintaa syvemmältä 245 19: { 20: fputs( $fp, "close" ); 21: die("error: $line\n\n"); 22: } 23: print "$line\n"; 24: print "-- Selecting $group\n\n"; 25: fputs( $fp, "group alt.test\n" ); 26: $line = fgets( $fp, 1024 ); 27: $status = explode( " ", $line ); 28: if ( $status[0]!= 211 ) 29: { 30: fputs( $fp, "close" ); 31: die("error: $line\n\n"); 32: } 33: print "$line\n"; 34: print "-- Getting headers for first message\n\n"; 35: fputs( $fp, "head\n" ); 36: $line = fgets( $fp, 1024 ); 37: $status = explode( " ", $line ); 38: print "$line\n"; 39: if ( $status[0]!= 221 ) 40: { 41: fputs( $fp, "close" ); 42: die("error: $line\n\n"); 43: } 44: while (! ( strpos($line, ".") === 0 ) ) 45: { 46: $line = fgets( $fp, 1024 ); 47: print $line; 48: } 49: fputs( $fp, "close\n" ); 50: print "</pre>"; 51:?>

246 13. Pintaa syvemmältä 52: </body> 53: </html> Listauksen 13.8 koodi tekee hieman enemmänkin kuin pelkästään demonstroi sitä, että NNTP-yhteys voidaan luoda fsockopen()-funktiolla. Todellisessa esimerkissä rivin jäsentely tehtäisiin funktiossa, jotta vältyttäisiin toistuvalta koodilta. Funktiota voitaisiin kutsua sitten eri rivien kohdalla lisätietojen saamiseksi palvelimelta. Pyörän uudelleen keksimisen sijaan saattaisi olla hyvä tutkia PHP:n IMAP-funktioita, jotka tekevät suuren osan tuosta työstä puolestasi. Tallennamme palvelimemme isäntänimen muuttujaan $server ja valitsemamme ryhmän muuttujaan $group. Jos haluat ajaa tämän skriptin, sinun tulisi sijoittaa Internet-palveluntarjoajasi news-palvelimen nimi $servermuuttujaan. Käytimme fsockopen()-funktiota kytkeytymään isäntäkoneen porttiin 119, joka yleensä on porttina NNTP-yhteyksille. Jos sopivaa tiedosto-osoitinta ei palauteta, käytämme die()-funktiota virhenumeron ja kuvauksen tulostamiseen selaimelle ja lopetamme skriptin ajamisen. Jos yhteys onnistuu, palvelin lähettää meille vahvistusviestin, joten yritämme saada sen haltuumme fgets()-funktiolla. Jos kaikki onnistuu, tämä merkkijono alkaa tilakoodilla 200. Voimme testata sen käyttämällä explode()-funktiota erottamaan $line-merkkijono taulukkoon välilyönnin toimiessa erottimena. Saat lisätietoa explode()- funktiosta luvusta 17. Jos tämän taulukon ensimmäinen alkio on 200, voimme jatkaa; muutoin lopetamme skriptin. Jos kaikki sujuu odotetusti, lähetämme palvelimelle komennon valita keskusteluryhmä. Jos se onnistuu, palvelin palauttaa merkkijonon, joka alkaa tilakoodilla 211. Testaamme sen ja lopetamme skriptin, jos tilakoodi on jokin muu arvo. Kun olemme nyt valinneet keskusteluryhmämme, lähetämme head-komennon palvelimelle pyytäen ensimmäisen viestin otsikoita. Taaskin me testaamme vastauksen ja etsimme nyt tilakoodia 221. Lopuksi saamme itse otsikon. Palvelimen otsikkolistaus päättyy yksittäiseen pisteeseen (.), joka on omalla rivillään, joten testaamme sen while-lauseessa. Niin kauan kuin palvelimen tulostusrivi ei ala pisteellä, pyydämme ja tulostamme seuraavan rivin. Lopuksi suljemme yhteyden. Kuva 13.3 esittää tyypillisen tulosteen listauksesta 13.8. KUVA 13.3 NNTP-yhteyden luominen. Sähköpostin lähettäminen mail()-funktiolla PHP osaa lähettää sähköpostia automaattisesti puolestasi. Se tapahtuu mail()-funktiolla, joka ottaa argumenteikseen kolme merkkijonoa: vastaanottajan, aiheen ja viestin. Funktio palauttaa arvon false, jos virheitä tapahtuu. Seuraava koodi lähettää sähköpostia:

13. Pintaa syvemmältä 247 $to = "someone@adomain.com"; $subject = "hi"; $message = "just a test message! "; mail( $to, $subject, $message ) or print "Could not send mail"; Jos käytät PHP:tä UNIX-koneessa, mail() käyttää apunaan Sendmail-ohjelmaa. Muissa järjestelmissä funktio kytkeytyy SMTP-palvelimelle, joka voi olla paikallinen tai etäkone. Asetus määritetään SMTPkohdassa php.ini-tiedostossa. Sähköpostin lähetyksessä ei tarvitse rajoittua pelkästään niihin otsikoihin, jotka asetetaan mail()-funktion argumentteina. Mukaan voi laittaa mitä tahansa otsikoita valinnaisessa neljännessä argumentissa. Nämä otsikot tulee erottaa toisistaan merkkijonolla \r\n (kuvaavat vaununpalautusta ja rivinvaihtoa). Seuraavassa esimerkissä laitamme sähköpostiviestiimme From-kentän ja myös X-Priority-otsikon, jonka jotkin asiakkaat tunnistavat: $to = "someone@adomain.com"; $from = "book@corrosive.co.uk"; $subject = "hi"; $message = "just a test message! "; mail( $to, $subject, $message, "$from\r\nx-priority: 1 (Highest)" ) or print "Could not send mail"; Yhteenveto Tällä tunnilla opit käyttämään ympäristömuuttujia, joiden avulla saat lisätietoa sivusi vierailijoista. Jos et saa esille käyttäjän isäntäkoneen nimeä, voit käyttää gethostbyaddr()-funktiota sen saamiseen. Luku kuvasi sinulle myös asiakkaan ja palvelimen käymää keskustelua, kun HTTP-yhteys oli luotu. Tämän lisäksi opit käyttämään fopen()-funktiota asiakirjan hakemiseen Webistä ja fsockopen()-funktiota oman HTTP-yhteyden luomiseen. Tuon funktion avulla voit ottaa yhteyden mihin tahansa Internetpalvelimeen. Luvun lopussa sait tietoa mail()-funktiosta, jolla lähetetään sähköpostia skripteistä käsin. K&V K HTTP näyttää hieman kaukaiselta. Onko minun tosiaankin ymmärrettävä sitä voidakseni kirjoittaa hyvää PHP-koodia? V Ei. Voit aivan hyvin kirjoittaa erinomaista koodia tietämättä juuri mitään asiakkaan ja palvelimen välisestä kommunikoinnista. Toisaalta prosessin ymmärtäminen on hyödyllistä, jos haluat tehdä muutakin kuin vain ladata sivuja etäpalvelimilta.

248 13. Pintaa syvemmältä K Jos lähetän muokattuja otsikoita etäpalvelimelle, tulisiko minun luottaa ympäristömuuttujiin? V Sinun ei tulisi luottaa sellaisiin ympäristömuuttujiin kuin esimerkiksi $HTTP_REFERRER tai $HTTP_USER_AGENT, jos niiden tarkkuus on olennaista skriptisi toiminnalle. Muista kuitenkin, että suurin osa asiakkaistasi kertoo sinulle totuuden. Jos haluat taata toimivuuden pelkästään tutkimalla, mitä selainta käyttäjä käyttää tai kerätäksesi tilastotietoa, ei ole mitään syytä hyljeksiä tuota tietoa. Työpaja Työpaja tarjoaa pikakysymyksiä, joiden avulla voit kerrata läpikäytyä materiaalia. Yritä ymmärtää vastaukset ennen kuin jatkat seuraavaan lukuun. Vastaukset annetaan liitteessä A. Kysymyksiä 1. Mikä ympäristömuuttuja antaisi viittaavan sivun URL:n? 2. Miksi et voi luottaa $REMOTE_ADDR-muuttujaan jäljittääksesi yksittäisen käyttäjän monien skriptisi käyttäjien joukosta? 3. Mitä HTTP tarkoittaa? 4. Mikä asiakkaan otsikkorivi kertoo palvelimelle selaimen, joka tekee pyynnön? 5. Mitä palvelimen vastauskoodi 404 tarkoittaa? 6. Mitä funktiota voisit käyttää ottaaksesi esille Web-sivun etäpalvelimelta tekemättä omaa verkkoyhteyttä? 7. Jos käytössäsi on IP-osoite, mikä funktio antaisi palvelimen nimen? 8. Mikä funktio luo verkkoyhteyden? 9. Millä PHP-funktiolla voit lähettää emailia? Toiminta 1. Luo skripti, joka hyväksyy Web-palvelimen nimen (esimerkiksi nimen http://www.microsoft.com ) syöttötiedoikseen. Lähetä palvelimelle HEAD-pyyntö käyttäen fsockopen()-funktiota, jolla yhteys luodaan. Tulosta vastaus selaimelle. Muista ottaa huomioon mahdollisuus, että yhteyden luonti ei onnistu. 2. Luo skripti, joka ottaa vastaan viestin käyttäjältä ja lähettää sen sinulle. Lisää käyttäjän viestiin ympäristömuuttujia, jotka kertovat käyttäjän selaimen ja IP-osoitteen.