Nykyisin useimmat yritysten ja kotien tietokoneet on verkotettu. Tällöin tietokoneista on modeemin, ISDN:n tai verkkokortin avulla pääsy muualla verkossa sijaitseviin resursseihin, kuten tulostimiin, tiedostopalvelimiin ja sähköpostipalvelimiin.
Organisaation sisäistä verkotusta kutsutaan yleensä paikallisverkoksi (LAN eli Local Area Network). Lähes aina paikallisverkot ovat myös yhteydessä isompaan runkoverkkoon, jotka taas ovat yhteydessä toisiin runkoverkkoihin. Tätä tietokoneverkoista koostuvaa valtavaa verkkoa kutsutaan Internetiksi. Se kattaa nykyään noin 60 miljoonaa tietokonetta ympäri maapallon.
Luvussa 2 kuvaillaan lyhyesti Internetin erästä palvelua, WWW:tä, ja sen käyttömahdollisuuksia.
Luvussa 3 esitellään tutkielman aihe, PHP-kieli.
Luvussa 4 tarkastellaan pintapuolisesti PHP:n syntaksia ottamalla esille yleisimmät PHP-kielen kontrollirakenteet sekä tulostuslauseet.
Luvun 5 esimerkkisovellusten avulla pyritään antamaan käytännön kuva siitä, mitä PHP:llä on mahdollista saada aikaan.
Luvun 6 yhteenvetoon kootaan saadut tulokset sekä vertaillaan PHP:tä muihin vastaaviin tekniikoihin.
LuK-tutkielman tavoitteena on tutustua PHP-kielen tarjoamiin mahdollisuuksiin. Tarkoituksena ei ole kuitenkaan syventyä perinpohjaisesti eri ominaisuuksiin, vaan tutkia pintapuolisesti, kuinka saadaan tehtyä helposti ja nopeasti dynaamisia WWW-sivuja. Tarkasteluun otetaan tärkeimmät perusominaisuudet, joita tarvitaan useimmissa PHP-kieltä käyttävissä HTML-sivuissa. Lisäksi tarkastellaan tietokantojen käyttämistä PHP-kielen avulla.
Tarkoituksena ei ole myöskään tutustua PHP-kielen aliohjelmien syntaksiin kovin syvällisesti. Perinpohjaiset kuvaukset olemassaolevista aliohjelmista ja paljon muuta löytyvät PHP:n kotisivuilta. [PHP-kotisivu]
Jotta PHP:stä muodostuisi kokonaisvaltainen kuva, oletetaan tutkielman lukijan hallitsevan jonkin verran ohjelmointia sekä HTML-sivujen tekemistä. Erityisesti esimerkkikoodien tarkastelussa tarvitaan jonkin verran esitietoja. Luvun 5 esimerkkisovellusten koodeista on selitetty tarkemmin vain merkittävimmät komentokokonaisuudet. Yksittäisiä koodirivejä ei ole yleensä selitetty. Lukijan tehtäväksi jää pohtia yksittäisten komentojen merkitys ja tehtävä koodissa.
WWW eli World Wide Web on yksi Internetin suosituimpia palveluita. WWW:n avulla on mahdollista selata dokumentteja graafisesti ajasta ja paikasta riippumattomasti. Koska Internet koostuu useista eri käyttöjärjestelmiä käyttävistä erilaisista tietokoneista, tulee tiedon esittämiseen käyttää jotakin yhteisesti sovittua tapaa. Tämä tapa on W3C:n eli WWW Consortiumin standardoima HTML-kieli (Hypertext Markup Language) eri versioineen. [W3C-kotisivu]
HTML-kielellä kuvataan WWW:hen sijoitettavan dokumentin ("sivun" tai usean sivun eli "sivuston") rakenne ja siihen liitettävät asiat. Pelkän tekstin lisäksi dokumentti voi sisältää kuvia, videokuvaa ja ääntä, mutta näiden esittäminen käyttäjän tietokoneella ns. selainohjelman avulla ei välttämättä suoraan onnistu. Mahdollisuus kuvien käyttöön oli eräs syy Internetin räjähdysmäiseen kasvuun 1990-luvun puolivälissä.
Selaimeksi kutsutaan ohjelmaa, jolla pystytään lukemaan ja selailemaan WWW:ssä sijaitsevia HTML-kielellä kirjoitettuja dokumentteja. Kun käyttäjä haluaa tutkia jotakin tällaista dokumenttia, kirjoittaa hän selaimeen dokumentin osoitteen eli URLin (Uniform Resource Locator) tai painaa jollakin sivulla olevaa linkkiä, joka johtaa ko. dokumenttiin. Tällöin selain lähettää WWW-dokumentin sisältävälle palvelimelle pyynnön palauttaa haluttu dokumentti.
WWW-palvelin tarkistaa, löytyykö dokumentti oikeasta paikasta ja voidaanko se palauttaa kysyvälle käyttäjälle (selaimelle). Jos voidaan, dokumentti lähetetään selaimelle otsikkotiedoin varustettuna (dokumentin koko, tyyppi, viimeisin muutospäivämäärä, jne.). Jos dokumenttia ei löydy tai ilmenee jokin muu este, WWW-palvelin palauttaa selaimelle virheilmoituksen.
Perinteisesti HTML-kieli on koostunut tietystä joukosta standardinimisiä elementtejä eli tageja, jotka kuvaavat dokumentin rakenteen. Näillä voidaan tuottaa staattisia eli muuttumattomia HTML-dokumentteja, joiden päivittäminen ja korjaaminen voi olla hankalaa ja aikaavievää.
Koska ensi-ihastuksen jälkeen HTML-dokumenttien laatijat halusivat kuitenkin helpomman tavan tuottaa dokumentteja, jotka sisältävät muuttuvaa tietoa, oli keksittävä tapa toteuttaa tämä. Syntyi tekniikoita, joilla staattisia WWW-dokumentteja voitaisiin täydentää tai jopa korvata dynaamisella vastineella. Dynaamisten sivujen muodostukseen käytettyjä tekniikoita kutsutaan yhteisnimellä CGI eli Common Gateway Interface. CGI:n avulla on mahdollista sijoittaa dokumenttiin muuttuvaa tietoa, joka voidaan hakea esimerkiksi tietokannasta sen mukaan, kuka käyttäjä on dokumentin selaimellaan pyytänyt.
On kuitenkin muistettava, että HTML ei ole sanan varsinaisessa merkityksessä ohjelmointikieli. Siitä puuttuvat muun muassa toistorakenteet, ehtolauseet ja aliohjelmat, joten varsinaista ohjelmakoodia ei HTML:llä voida saada aikaan.
Dynaamisten WWW-sivujen tuottamiseen on saatavilla kymmeniä eri vaihtoehtoja. Historiallisesti ensimmäiset toteutukset olivat puhtaasti WWW-palvelimessa suoritettuja komentojonoja, jotka ajettiin käyttöjärjestelmän komentotulkilla. Nämä tuottivat koko HTML-sivun, joka lähetettiin suoraan selaimelle. Vaikka idea on vanha, ei se suinkaan ole huono, joten vielä tänä päivänäkin käytetään tällaista toimintatapaa. Suosituimpia ovat Perl- ja muut UNIX-komentojonot.
Seuraavan kehitysaskeleen tarjosi HTML-sivujen sisään upotettu dynaamisuus. Tämä mahdollistaa sen, että WWW-palvelimessa koodia suorittava tulkki tai kääntäjä voidaan erottaa itse HTML-koodista, joten HTML-koodin korjaileminen on useissa tapauksissa helpompaa. Tulkki tai kääntäjä suorittaa vain sille tarkoitetut komennot ja jättää muun osan sivusta koskemattomaksi. Tällaisen vaihtoehdon tarjoavat muun muassa Microsoftin ASP sekä tässä tutkielmassa esiteltävä PHP.
Kolmannen ryhmän muodostavat tekniikat, jotka ovat ensimmäisen tavan muunnelmia. Näissä WWW-palvelimessa komentoja tulkkaava suoritin palauttaa koko sivun, mutta sivun ulkoasu voidaan suunnitella helposti graafisilla työkaluilla. Tulkin sisäinen kieli voi poiketa suurestikin HTML-kielestä. Tällaisen tekniikan tarjoavat muun muassa Borland (nyk. Inprise) IntraBuilder sekä useat Java-kehitystyökalut, jotka tuottavat HTML-koodia WWW-palvelimen yhteyteen asennettujen servlettien avulla.
Vuosien saatossa on selainten yhteyteen liitetty tulkkeja, jotka osaavat rajoitetusti suorittaa HTML-sivussa olevia tulkin suoritettavaksi tarkoitettuja koodirivejä. Yleisin näistä koodikielistä on Javascript, jota käytetään elävöittämään HTML-sivuja lisäämällä sinne (yleensä) turhia kelloja, vieriviä tekstejä, jne. (engl. "bells and whistles").
PHP eli "PHP: Hypertext Preprocessor" on kokonaisuus, jonka avulla staattisten HTML-kielellä kirjoitettujen sivujen sisälle on mahdollista upottaa dynaamisuutta. PHP sisältää oman kielen, jonka avulla HTML-sivuille saadaan dynaamisuutta käyttäen suurta joukkoa valmiita aliohjelmia.
PHP-tulkki asennetaan WWW-palvelimen yhteyteen. Tutkielmassa ei kuitenkaan puututa PHP:n asennukseen, jonka pitäisi onnistua PHP:n mukana tulleiden ohjeiden avulla. PHP on saatavissa useimmille laiteympäristöille ja WWW-palvelimille. [PHP-kotisivu]
PHP-kieli ja HTML-kieli eivät ole toisensa poissulkevia. Kumpaakin voidaan käyttää samassa dokumentissa täydentämään toista. Molempia ei ole kuitenkaan pakko käyttää, joten W3C-suositusten mukainen HTML-sivu voidaan tehdä myös pelkästään PHP-koodilla.
Kun selain pyytää PHP-koodia sisältävän sivun WWW-palvelimelta, se antaa sivun suoritettavaksi palvelimeen asennetulle PHP-tulkille. PHP-tulkki tutkii dokumentin rakenteen, suorittaa sivulla olevat PHP-kieliset komennot ja palauttaa WWW-palvelimelle työn tuloksena syntyneen staattisen dokumentin. WWW-palvelin palauttaa lopuksi dokumentin sitä pyytävälle selaimelle. PHP-kielellä täydennetyt sivut (kuten yleensä kaikki muutkin dynaamiset WWW-sivut) näkyvät siis selaimella kuten mitkä tahansa HTML-sivut.
PHP-kokonaisuuden kehittäminen alkoi ideasta saada tietää kuka lukee WWW-palvelimella olevia dokumentteja. Kun myös muut käyttäjät ottivat käyttöön kehitetyn ohjelmapaketin pyytäen siihen lisää uusia ominaisuuksia, syntyi alkuperäinen PHP eli Personal Home Page Tools.
Myöhemmin PHP:hen lisättiin ominaisuudet tietokantojen käyttämiseksi HTML-sivuilta. Tätä versiota PHP:stä kutsuttiin nimellä PHP/FI versio 2. FI eli Form Interpreter oli aiemmin toteutettu erillinen HTML-lomakkeiden käsittelyohjelma, jonka ominaisuudet siis yhdistettiin PHP:hen.
PHP:n versiota 3 (PHP3) varten PHP/FI kirjoitettiin ja suunniteltiin uudelleen. Samalla lisättiin uusia ominaisuuksia. PHP versio 4 (PHP4) on uusin sukupolvi PHP-kokonaisuudesta. PHP4 sisältää kaikki PHP3:n ominaisuudet ja lisäksi useita uusia ominaisuuksia. Osa uudistuksista on PHP4:n sisäisiä parannuksia, jotka eivät näy ulospäin. [PHP-uudistuksia]
Lisää historiaa ja kehitystietoa PHP:stä löytyy PHP:n kotisivuilta. [PHP-historia]
Tutkielmassa termi PHP tarkoittaa PHP3:n ja PHP4:n sisältämiä ominaisuuksia.
PHP sisältää kaikki nykyaikaisten kielten parhaat ominaisuudet (muun muassa muuttujat, aliohjelmat, toisto- ja ehtorakenteet sekä olio-ohjelmoinnissa tarvittavat luokat, periytymisen ja ylikuormituksen).
Yleisiä aliohjelmia on tarjolla satoja, sekä muiden valmistajien ohjelmistopakettien tukea varten erikoistuneempia aliohjelmakirjastoja, esimerkiksi eri tietokantakomponenttien käyttöä varten. [PHP-käsikirja]
PHP:n lähdekoodi on vapaasti saatavilla, joten kuka tahansa voi lisätä siihen uusia ominaisuuksia. [PHP-lähdekoodi]
PHP:n tulevaisuus näyttää valoisalta. Sillä on vankka käyttäjäkuntansa, joka tuskin luopuu PHP:n käytöstä. Koska PHP on ilmainen, on se vapaasti saatavilla useille eri käyttöympäristöille. Ilmaisuudesta huolimatta PHP:tä kehitetään ja siitä ilmestyy aika ajoin uusia versioita.
PHP on käytössä useissa WWW-sivustoissa eri organisaatioissa. Erään tutkimuksen mukaan PHP olisi käytössä lähes 3.5 miljoonassa WWW-palvelimessa ympäri maapalloa (tieto elokuulta 2000). PHP-perustan päälle on rakennettu useita eri projekteja, joista osa on ilmaisia ja osa kaupallisia. [PHP-käyttö] ja [PHP-projekteja]
Luvussa esitellään pääpiirteissään PHP-kielen syntaksi. Myös esimerkkikoodeja tutkimalla selviää syntaksi.
PHP-kielen syntaksi perustuu C-, Java- ja Perl-kielten syntaksiin, jonka lisäksi mukana on muutamia pelkästään PHP:lle ominaisia piirteitä. Tarkoituksena on ollut kehittää kieli, jonka avulla HTML-sivuille voitaisiin helposti ja nopeasti saada dynaamisuutta. Tästä johtuen PHP:n syntaksi ei ole yhtä monimutkainen verrattuna esimerkiksi Perl-kielen syntaksiin, mutta kuitenkin yhtä monipuolinen.
PHP-kieliset komennot sijoitetaan elementtien
<?php
ja ?>
väliin. Näitä alku- ja loppuelementtejä voidaan
käyttää missä tahansa HTML-sivulla aloittamaan ja
lopettamaan PHP-komento-osuus. Jopa aliohjelman sisällä voidaan
"vaihtaa" pois PHP-moodista käyttämällä elementtiä
?>
,
kirjoittaa HTML-elementtejä ja palata takaisin PHP-moodiin elementillä
<?php
.
PHP-komentoja voidaan kirjoittaa
peräkkäin erottelemalla ne puolipistein. Aaltosulkeella
"{
"
voidaan aloittaa lausekokoelma, joka päätetään sulkevalla
aaltosululla
"}
".
Kommentteja voidaan merkitä joko C++-tyylisesti
//
-merkein, Unix-komentojonotyylisesti risuaitamerkillä
#
tai C-tyylisesti aloittamalla kommentti merkinnällä
/*
ja lopettamalla merkinnällä */
.
Muuttujat aloitetaan $
-merkillä,
jonka jälkeen ilmoitetaan muuttujan nimi. Nimen pitää alkaa
kirjaimella tai alaviivalla "_
",
jonka jälkeen voi esiintyä kirjaimia, numeroita tai alaviivoja
"_
".
Erikoismerkit (ASCII-merkistössä merkit 127-255) ja skandinaaviset
kirjaimet å, ä ja ö ovat sallittuja, mutta selvyyden vuoksi
niitä ei kannata käyttää. Kirjainten koolla on
merkitystä, joten
$foo
ja $Foo
ovat eri muuttujia.
Toisin kuin useimmissa muissa ohjelmointikielissä, PHP-muuttujilla ei ole tyyppiä. Siten sama muuttuja voi toimia ensin merkkijonona ja sitten numeroarvoisena. Tämä aiheuttaa myös ohjelmoijalle tiettyä vastuuta: muuttujien käytössä on oltava erityisen tarkkana, koska tyyppitarkistusta ei suoriteta.
Muuttuja määritellään sijoittamalla siihen arvo
=
-merkillä.
Muuttujien arvojen vertailu tapahtuu käyttäen
==
-merkintää.
Muuttujan arvo voidaan sijoittaa toiseen muuttujaan. Jos muuttujien tyypit ovat erilaisia, esimerkiksi merkkijono ja numero, varoitusta erityyppisten muuttujien arvojen sijoittamisesta ei tule. Erityyppisiä muuttujia voidaan myös vertailla keskenään, mutta tämä ei välttämättä tuota haluttua tulosta.
Muuttujan näkyvyysalue riippuu
siitä, missä muuttuja on määritelty. Aliohjelman
sisällä määritelty muuttuja näkyy vain aliohjelmassa.
Aliohjelmien ulkopuolella määritelty muuttuja ei näy
aliohjelmassa, ellei sitä aliohjelmassa erikseen määritellä
näkyväksi
global
-merkinnällä.
Seuraava PHP-koodi ei tuota varoituksia
tai virheilmoituksia, vaikka se ei ole kovin selkeää kieltä.
Käytetty print
-aliohjelma
esitellään seuraavassa luvussa. PHP-tulkille tarkoitetut komennot on
kursivoitu kuten muissakin koodiesimerkeissä.
<?php $testi = 'foo'; print($testi . "\n"); $testi = bar; print($testi . "\n"); $testi = 007; print($testi+'foobar' . "\n"); ?>
Koodin tuloksena saadaan seuraavat rivit.
foo bar 7
Välttämättä tulostus ei siis ole sitä mitä halutaan. Muuttujien ja lainausmerkkien käytössä täytyy olla todella tarkkana.
Vakioita voidaan PHP-koodissa määritellä
define()
-aliohjelman avulla esimerkiksi seuraavasti:
define("VAKION_NIMI", "Vakion arvo");
Vakio on kuin muuttuja, mutta sillä
on tiettyjä eroavaisuuksia muuttujiin. Vakiot eivät ala
$
-merkillä,
niitä voidaan käyttää missä tahansa PHP-koodissa
riippumatta näkyvyyksistä eikä vakion arvoa voida muuttaa tai
poistaa sen jälkeen kun se on kerran
määritelty.
PHP-kielen print
-, printf
- ja echo
-aliohjelmilla
voidaan HTML-sivulle tulostaa merkkejä. Käytössä on lisäksi
sprintf
-aliohjelma,
jolla voidaan muuttujaan sijoittaa muotoiltu merkkijono kuten tulostettaisiin
HTML-sivulle printf
-aliohjelmalla.
Kaikilla näillä on joitakin eroavaisuuksia, joten tutkitaan niitä
vähän tarkemmin.
Print
-komennolla
voidaan tulostaa merkkijonoja, jotka tulostuvat HTML-sivulle sellaisenaan.
Echo
-komennolla
tulostettavasta merkkijonosta korvataan merkkijonossa olevat muuttujien nimet
näiden arvolla, jos merkkijono on lainausmerkeissä. Heittomerkkien
sisällä oleva merkkijono tulostetaan sellaisenaan.
Echo
-komennolla
voidaan tulostaa myös rivinvaihtoja sisältäviä pidempiä
merkkijonoja, joiden rivinvaihdot säilytetään.
Echo
-komento
ei varsinaisesti ole aliohjelma, joten sitä käytettäessä ei
tarvita sulkumerkkejä parametrien ympärillä. Lisäksi
parametreina voi olla useampia merkkijonoja pilkuilla eroteltuina. Normaalisti
PHP-merkkijonojen yhdistäminen tapahtuu pistemerkillä (ei
+-merkillä!). Rivinvaihto saadaan aikaan tulostamalla
"\n
".
Printf
-komennolla
voidaan tulostaa muotoiltuja merkkijonoja kuten C-kielen
printf
-komennolla.
Tutkitaan esimerkkinä alla olevia tulostuskomentoja sisältäviä koodirivejä.
<?php $foo = 'bar'; print('Muuttujan $foo arvo on ' . $foo . '.\n'); echo "Muuttujan $foo arvo on " , $foo , ".\n"; printf('Muuttujan $foo arvo on %s.\n',$foo); ?>
PHP-tulkki muokkaa edellä olleet komennot seuraavaan muotoon.
Muuttujan $foo arvo on bar. Muuttujan bar arvo on bar. Muuttujan $foo arvo on bar.
Ensin sijoitetaan muuttujaan $foo
merkkijonoarvo. Print
-komento
tulostaa pistemerkillä yhdistetyn merkkijonon, jonka lopussa on muuttujan
$foo
arvo. Seuraavalle riville echo
-komento
tulostaa rivinvaihtoja sisältävän merkkijonon. Tulostetun
merkkijonon sisällä muuttujamerkintä $foo
on korvattu muuttujan arvolla, koska merkkijono on lainausmerkkien
sisällä. Pilkulla erotellun muuttujan $foo
arvo tulostetaan rivin loppuun. Printf
-komento
tulostaa muotoillun merkkijonon, joka sisältää komennolle toisena
parametrina annetun merkkijonon arvon sijoitettuna ensimmäisen parametrin
kohtaan %s
.
PHP-kieli sisältää if
-ehtolauseen,
jolla voidaan tutkia annetun ehdon totuusarvo ja sen mukaan tehdä
toimintoja. Luvussa 4.7 on esimerkkejä ehtolauseen
käytöstä.
PHP-kieli sisältää useita toistolauseita.
For
-, while
- ja do-while
-rakenteet ovat
näistä yleisimmät. Luvussa 4.7 on esimerkkejä
toistolauseiden käytöstä.
For
-lauseella
voidaan lause tai lausekokoelma toistaa niin kauan kuin annettu ehto on
voimassa. Yleensä toistojen lukumäärä on ennalta
tiedossa.
For
-lauseen syntaksi on seuraava:
for (alkuehto; lopetusehto; seuraava_askel) suoritettavat_lauseet
Alkuehto
on for
-lauseen
suoritusta aloitettaessa kerran suoritettava lause. Tällä voidaan
esimerkiksi nollata lauseessa käytetty silmukkamuuttuja tai tehdä
muita alustustoimenpiteitä.
Lopetusehto
kuvaa ehtolausetta, jonka perusteella for
-lauseen
suoritus joko lopetetaan tai sitä jatketaan. Jos lopetusehdon totuusarvo on
tosi (TRUE
), suoritus jatkuu, muussa tapauksessa (FALSE
)
se lopetetaan.
Seuraava_askel
kuvaa lausetta, joka suoritetaan, kun yksi suorituskerta on saatu tehtyä ja
lopetusehto
tutkittua.
Suoritettavat_lauseet
kuvaavat toistettavaa lausetta tai
lausekokoelmaa.
While
-lauseella
voidaan lause tai lausekokoelma toistaa niin kauan kuin annettu ehto on
voimassa. Yleensä toistojen lukumäärä ei ole ennalta
tiedossa.
While
-lauseen syntaksi on seuraava:
while ( ehto ) suoritettavat_lauseet
Ehto
kuvaa lopetusehtoa, jonka saatua totuusarvon
FALSE
lopetetaan while
-lauseen suoritus.
Suoritettavat_lauseet
kuvaavat kullakin lauseen suorituskerralla suoritettavia
lauseita.
Do-while
-rakenne toimii lähes samoin kuin edellisen luvun
while
-lause,
mutta lopetusehdon tutkinta tapahtuu vasta suoritettavien lauseiden
jälkeen. Tästä johtuen lause tai lausekokoelma suoritetaan aina
vähintään kerran.
Do-while
-rakenteen syntaksi on seuraava:
do suoritettavat_lauseet while ( ehto )
Rakenteen osat ovat samat kuin edellisen luvun
while
-lauseella.
Luvussa käsitellään
esimerkkejä toistolauseista. Sama silmukka suoritetaan käyttäen
ensin for
-lausetta, sitten while
-lausetta ja lopuksi
do-while-
rakennetta.
Kussakin toistolauseessa on mukana lisäksi esimerkki
if
-lauseesta.
Koodit tulostavat luvut yhdestä kahteenkymmeneen ja tiedon siitä, onko
tulostettu luku parillinen vai pariton.
For
-lausetta käyttäen silmukka näyttää seuraavalta:
<?php $i = 1; for ($i = 1; $i <= 20; $i++) { if ( $i % 2 == 0 ) print("Numero " . $i . " on parillinen.\n"); else print("Numero " . $i . " on pariton.\n"); } ?>
While-lausetta käyttäen sama silmukka näyttää seuraavalta:
<?php $i = 1; while ( $i <= 20 ) { if ( $i % 2 == 0 ) print("Numero " . $i . " on parillinen.\n"); else print("Numero " . $i . " on pariton.\n"); $i++; } ?>
Do-while -rakennetta käyttäen silmukka näyttää seuraavalta:
<?php $i = 1; do { if ( $i % 2 == 0 ) print("Numero " . $i . " on parillinen.\n"); else print("Numero " . $i . " on pariton.\n"); $i++; } while ( $i <= 20 ); ?>
Saman tekevä silmukka saadaan siis aikaan useammalla eri tavalla. Käyttökohteesta kuitenkin aina riippuu, mikä silmukkatyyppi kannattaa valita.
PHP tarjoaa ominaisuudet
olio-ohjelmointia varten. Luokkien määrittely onnistuu kuten
missä tahansa yleisesti käytetyssä olio-ohjelmointikielessä.
Luokkien määrittelyn jälkeen niitä voidaan
käyttää PHP-koodissa. Seuraavassa esimerkissä
määritellään Auto
-luokka,
jonka jälkeen luodaan kaksi luokan ilmentymää.
<?php class Auto { var $nimi; var $teho; // konstruktori oletusparametrein function Auto($nimi = "nimetön", $teho = 0) { $this->nimi = $nimi; $this->teho = $teho; } function aseta_nimi($n) { $this->nimi = $n; } function aseta_teho($teho) { $this->teho = $teho; } function kerro_nimi() { return $this->nimi; } function kerro_teho() { return $this->teho; } function kerro_tiedot() { printf("Olen %s. Tehoa minulla on %d yksikköä.\n", $this->kerro_nimi(),$this->kerro_teho()); } } // luokan määrittely päättyy $lada = new Auto("Lada",60); $mersu = new Auto; $mersu->aseta_nimi("Mersu"); $mersu->aseta_teho(220); $mersu->kerro_tiedot(); $lada->kerro_tiedot(); ?>
Koodi asettaa arvoja Auto
-luokan
ilmentymille (olioille) ja tulostaa olioiden attribuutit (muuttujat). PHP-tulkin
muokkaama koodi näyttää seuraavalta:
Olen Mersu. Tehoa minulla on 220 yksikköä. Olen Lada. Tehoa minulla on 60 yksikköä.
PHP-kokoonpano tarjoaa rajapinnat useiden eri tietokantajärjestelmien käyttöön. Koska PHP-kieli on laitteistoriippumaton, tulee jokaiseen käyttöympäristöön olla oma liittymä kuhunkin tuettuun tietokantaan. Liittymiä käytetään samannimisillä aliohjelmilla ja samoin aliohjelmalle vietävin parametrein, jotta laitteistoriippumattomuus saadaan aikaan.
PHP-kokoonpanossa on tuki yleisimmille tietokannoille, joihin kuuluvat muun muassa dBase, Fiservin filePro, InterBase, Microsoftin SQL Server, mSQL, MySQL, Oracle, PostgreSQL ja Sybase. Lisäksi PHP:stä löytyy tuki geneeriselle ODBC-ajurille, joten PHP:n avulla voidaan käyttää periaatteessa mitä tahansa tietokantaa, jolle löytyy ODBC-ajuri. ODBC toimii sekä Windows- että Unix-versioissa.
Kutakin tietokantaa käyttävät aliohjelmat on nimetty yksilöllisesti. Tästä johtuen tietokantoja käyttäviä aliohjelmia on suuri määrä, joten tässä ei voida niitä kaikkia esittää. Tarkastellaan kuitenkin esimerkkinä ODBC:tä käyttäviä aliohjelmia. Kaikki tietokanta-aliohjelmat löytyvät PHP:n käsikirjoista. [PHP-käsikirja]
PHP:ssä on lähes 40
ODBC-aliohjelmaa, joten kaikkia ei käydä tässä läpi.
Aliohjelmista vain tärkeimpiä käytetään alla olevassa
esimerkkikoodissa. Koodia on kommentoitu
//
-merkein alkavilla riveillä. Tietokannasta tulee löytyä
Taulu
-niminen taulu, jossa on ainakin
Tallenne
-niminen merkkijonotyyppinen kenttä.
<?php // Määritellään vakioita virheenkäsittelyä varten. define("VIRHE", "Tapahtui virhe käsiteltäessä tietokantaa."); define("TALLENNUS_EI_ONNISTUNUT", "Tallennus ei onnistunut."); // Määritellään aliohjelmia tietokannan käsittelyyn. function hae_taulusta($arvo) { // Aliohjelmalla voidaan taulusta hakea haluttu arvo. Arvossa voidaan // käyttää SQL-kyselykielen %-jokerimerkkiä. // Avataan tietokantayhteys käyttäen PHP:n ODBC-ajuria. // "lukki" on tässä järjestelmän ODBC-asetuksiin määritelty // liittymä tietokantaan. odbc_connect()-aliohjelmalle annetaan parametreina // myös käyttäjätunnus ja salasana, mutta tässä tietokannassa // niitä ei tarvita. Palautetaan VIRHE-vakio, jos tietokantaan ei saada // yhteyttä. $tietokantayhteys = odbc_connect("lukki", "", ""); if ( !$tietokantayhteys ) return VIRHE; // Muodostetaan kysely halutusta arvosta. Suoritetaan kysely käyttäen // odbc_exec()-aliohjelmaa. Jos kysely ei onnistunut, palautetaan // VIRHE-vakio. $query = "select * from Taulu where Tallenne like '" . $arvo . "'"; $result_id = odbc_exec($tietokantayhteys, $query); if ( !$result_id ) { if ( $tietokantayhteys ) odbc_close($tietokantayhteys); return VIRHE; } // Tutkitaan löytyykö haluttu arvo tietokannasta. // Jos löytyy, otetaan kenttään Tallenne sijoitettu arvo muuttujaan. $onko_tallennetta = odbc_fetch_row($result_id); $tallenne = ""; if ( $onko_tallennetta ) $tallenne = odbc_result($result_id, "Tallenne"); // Suljetaan avattu tietokantayhteys ja palautetaan vastaus. odbc_free_result($result_id); if ( $tietokantayhteys ) odbc_close($tietokantayhteys); return $tallenne; } function aseta_tauluun($arvo) { // Aliohjelmalla voidaan taulun kenttään asettaa haluttu arvo. // Avataan tietokantayhteys. $tietokantayhteys = odbc_connect("lukki", "", ""); if ( !$tietokantayhteys ) return VIRHE; // Muodostetaan kysely. $query = "select * from Taulu where Tallenne like '" . $arvo . "'"; $result_id = odbc_exec($tietokantayhteys, $query); if ( !$result_id ) return VIRHE; $palautettava = ""; // Jos aikaisemmin ei ole vielä tallennettu arvoa, tehdään se // nyt. Jos aikaisemmin on tallennettu, ei tehdä mitään. $onko_tallennetta = odbc_fetch_row($result_id); if ( !$onko_tallennetta ) { $query = "insert into Taulu (Tallenne) values ('" . $arvo . "')"; $result_id = odbc_exec($tietokantayhteys, $query); if ( !$result_id ) $palautettava = TALLENNUS_EI_ONNISTUNUT; } // Suljetaan tietokantayhteys ja palautetaan tieto toiminnon // onnistumisesta. odbc_free_result($result_id); odbc_close($tietokantayhteys); return $palautettava; } function hae($arvo) { // Aliohjelma käyttää edellä määriteltyä hae_taulusta()-aliohjelmaa. // Tutkitaan onko tauluun jo tallennettu haluttu arvo. print("Tutkitaan onko jo tallennettu arvoa '" . $arvo . "': "); $haettu = hae_taulusta($arvo); if ( $haettu == VIRHE ) { print("\n" . $haettu); exit; } if ( $haettu == "" ) print("ei\n"); else { print("kyllä\n"); print("Taulusta haettu arvo '" . $haettu . "'.\n"); } } function aseta($arvo) { // Aliohjelma käyttää edellä määriteltyä aseta_tauluun()-aliohjelmaa. // Tallennetaan tauluun haluttu arvo. $tallenna = aseta_tauluun($arvo); if ( $tallenna != "" ) { print($tallenna); exit; } print("Tauluun tallennettu arvo '" . $arvo . "'.\n"); } // "Pääfunktio" // Suoritetaan hae()- ja aseta()-aliohjelmat. hae("foo%"); aseta("foobar"); hae("foo%"); ?>
PHP-tulkin muokkaama koodi
näyttää seuraavalta, kun käytettyyn tauluun ei ole alunperin
tallennettu foo
-merkkijonolla alkavaa arvoa.
Tutkitaan onko jo tallennettu arvoa 'foo%': ei Tauluun tallennettu arvo 'foobar'. Tutkitaan onko jo tallennettu arvoa 'foo%': kyllä Taulusta haettu arvo 'foobar'.
Jos tietokannan käytössä ilmenee jokin virhe, tulee tästä ilmoitus.
PHP-kokoonpano sisältää
runsaasti muitakin ominaisuuksia, joita ei ole edellä käsitelty. PHP:n
Windows-versiolla voidaan käynnistää ohjelmia ja suorittaa
niillä toimintoja Microsoftin COM- eli Component Object Model
-arkkitehtuurin avulla. PHP:llä voidaan muodostaa Adobe Acrobat Readerilla
luettavia PDF- eli Portable Document Format -tiedostoja. PHP:n
aspell
- ja pspell
-moduleilla
voidaan tarkistaa tekstin oikeinkirjoitusta. XML:n eli eXtensible Markup
Language -määrittelyn mukaisten dokumenttien käsittely onnistuu
PHP:n avulla.
Tietokoneverkkojen ja niihin liittyvien palveluiden käyttö onnistuu PHP:n avulla. SNMP:n eli Simple Network Management Protocol:n avulla voi suuriakin verkkoja käsitellä helposti. Sähköpostin lukeminen ja kirjoittaminen sekä keskusteluryhmiin osallistuminen onnistuvat PHP:n tarjoamien POP3-, IMAP- ja NNTP-protokollien avulla.
PHP:llä onnistuvat myös paikallisessa koneessa olevien tiedostojen ja hakemistojen käsittely, jos PHP:tä ajavan käyttäjän oikeudet siihen riittävät. JPEG-, GIF-, PNG- ja SWF-kuvatiedostojen käsittely onnistuu myös PHP:n avulla.
Kaiken kaikkiaan PHP sisältää suuren määrän erilaisia toimintoja. Aliohjelmia PHP sisältää yhteensä lähes 1500. On vaikea kuvitella ominaisuuksia, jotka PHP:stä vielä puuttuisivat, mutta jotka helposti olisivat toteutettavissa tällaiseen lausekieleen.
Luvussa tarkastellaan esimerkkisovelluksia, joissa on käytetty PHP-kieltä apuna. Esimerkeissä normaalein kirjasimin on esitetty HTML-elementit ja kursivoiduin kirjasimin PHP-kielellä kirjoitetut komennot (ts. PHP-tulkin suoritettavaksi tarkoitetut komennot).
Ensimmäisenä esimerkkiohjelmana esitellään yksinkertainen Hei maailma -tekstin tuottava HTML-sivu. Alla olevassa esimerkkiohjelmassa on käytetty myös kehittyneempiä ominaisuuksia:
<html><head><title>Hei maailma!</title></head> <body> <p> <?php print("Hei maailma!\n"); $aika = time(); $pvm = date("j.n.Y",$aika); $kello = date("H:i:s",$aika); print("On " . $pvm . " ja kello on " . $kello . ".\n"); ?> </p> </body></html>
Tiedoston alussa
määritellään HTML-elementtien avulla dokumentin rakenne ja
otsikko. PHP-tulkille tarkoitetut komennot on sijoitettu elementtien
<?php
ja ?>
väliin. WWW-palvelimeen asennettu PHP-tulkki suorittaa näiden
elementtien välissä sijaitsevat komennot ja palauttaa takaisin
WWW-palvelimelle tuloksen, joka siirretään käyttäjän
selaimelle.
Edellä olevassa esimerkkikoodissa sijoitetaan muuttujaan
aika
nykyhetken aika (sekunteja vuoden 1970 alusta).
Tämän jälkeen muuttujaan pvm
sijoitetaan aika
-muuttujasta
laskettu muotoiltu päivämäärä ja muuttujaan
kello
muotoiltu kellonaika käyttäen hyväksi
date
-funktion tarjoamia muotoilusääntöjä. Kaikki
muotoilusäännöt löytyvät PHP:n käsikirjoista.
[PHP-käsikirja]
Print
-funktiolla
tulostetaan päivämäärä ja kellonaika varustettuna
selittävillä teksteillä. Merkkijonojen yhdistämiseen
PHP-kielessä käytetään pistettä. Lopuksi
päätetään HTML-dokumentti.
PHP-tulkin muokkaama WWW-sivu näyttää seuraavalta:
<html><head><title>Hei maailma!</title></head> <body> <p> Hei maailma! On 21.9.2000 ja kello on 11:49:19. </p> </body></html>
Mukana ei enää ole minkäänlaista viittausta PHP-koodiin.
Luvussa esitellään PHP-kieltä hyödyntävä käytännön sovellus. Päivyrisovellus näyttää sivulla halutun kuukauden kalenterin sekä valintalistan ja painikkeen, joilla näytettävää kuukautta ja vuotta voidaan vaihtaa. Kalenterin vieressä on tilaa muistiinpanoille. Sovellus käyttää hyväkseen tietokantaa päivyrin tietojen säilömiseen.
Kullekin päivälle voidaan tehdä muistiinpanoja, jotka tallentuvat tietokantaan. Muistiinpanoja voidaan korjailla myöhemmin tai vaikka poistaa kokonaan.
Sovelluksen koodi on esitetty liitteessä.
Koodia on kommentoitu risuaitamerkillä #
ja
//
-merkinnällä
alkavilla riveillä. PHP-tulkille tarkoitetut komennot on kursivoitu. Jos
koodista poistetaan lihavoidut rivit, saadaan aikaan sovellus, joka toimii ilman
tietokantaa pelkkänä kalenterina.
Toimiakseen sovellus vaatii normaalien PHP-ominaisuuksien lisäksi myös tietokannan, johon voidaan ottaa WWW-palvelimelta yhteys. Tässä sovelluksessa on käytetty Microsoft Access -kantaa, jonka relaatiokuva ja taulujen rakenne on esitelty kuvassa 1.
Kuva 1. Päivyrisovelluksen tietokannan taulurakenne.
Käytettävän tietokannan
ei tarvitse olla monimutkainen, ja tämänkin kannan
Henkilöt
-taulu on tässä sovelluksessa tarpeeton.
Kalenteri
-taulussa riittävät kentät
Pvm
ja Tallenne
,
jos kaikki käyttäjät saavat muokata kaikkien
muistiinpanoja.
Henkilöt
-taulun HenkilöID
-kenttä
on numerotyyppinen (ja lisäksi autonumber
-tyyppinen
avainkenttä). Muut taulun kentät ovat merkkijonotyyppisiä.
Kalenteri
-taulun KalenteriID
- ja
HenkilöID
-kentät ovat numerotyyppisiä.
KalenteriID
on lisäksi
autonumber
-tyyppinen avainkenttä. Muut taulun kentät ovat
merkkijonotyyppisiä.
Kuvassa 2 on esitetty päivyrisovelluksen ulkoasu selaimella.
Kuva 2. Päivyrisovelluksen ulkoasu selaimella.
WWW-sivujen dynaamista tuottamista varten on olemassa useita eri tekniikoita. Kaikki vaihtoehdot eivät sovellu kaikkiin tarpeisiin, ja kaikki tekniikat eivät edes toimi kaikissa käyttöympäristöissä. Tutkielmassa on esitelty yksi käytännössäkin hyväksi koettu vaihtoehto, PHP. Se toimii niin Windows- kuin Unix-ympäristöissäkin.
Unix-ympäristöissä usein käytettyjä ovat Perl-kieliset CGI-ohjelmat. Perl-kieli on monipuolinen, mutta se tuntuu vaikeahkolta aloittelijasta. Tästä syystä se vain harvoin opetellaan ensimmäisenä ohjelmointikielenä. Perl sopii kuitenkin loistavasti merkkijonojen käsittelyyn, jota WWW-lomakkeiden käsittely suurimmaksi osaksi on.
PHP:tä vastaava Microsoftin tarjoama tekniikka on ASP eli Active Server Pages. Pääperiaate ASP:ssa on sama kuin PHP:ssäkin, eli sivujen sisään upotetaan komentoja, jotka WWW-palvelimeen asennettu tulkki suorittaa. ASP-komennoissa voidaan käyttää Microsoftin VBScript- tai JScript-kieliä, mutta muitakin mahdollisuuksia on, esimerkiksi Perl. [ASP-tietoutta]
ASP toimii vain Microsoftin omassa WWW-palvelinohjelmistossa IIS:ssä eli Internet Information Serverissä. ASP on suoraan käytettävissä, kunhan käyttöjärjestelmänä on Windows NT Server tai Windows 2000 Server sekä vapaasti Microsoftilta saatavilla oleva IIS-palvelinohjelmisto. Koska ASP on Microsoftin tuote, on se Windows-käyttöjärjestelmän mukana levinnyt laajalle. [ASP-tietoutta]
ASP:sta ei ole saatavilla lähdekoodia, toisin kuin PHP:stä. [PHP-lähdekoodi]
Mikään ohjelma ei ole täysin virheetön. PHP:n uusimmassa versiossa (tutkielman kirjoitushetkellä 4.0.3 patch level 1) on lähdekoodia yhteensä yli 10 megatavua, joten koodissa on varmasti useita virheitä. PHP:tä kehitetään ja korjaillaan kuitenkin koko ajan, joten ohjelmistossa olevien virheiden vuoksi sitä ei kannata hylätä. Käytännössä virheitä tulee esiin suhteellisen harvoin. [PHP-lähdekoodi]
Jos verrataan PHP:tä ja muita luvussa 2.4 esiteltyjä tapoja tuottaa dynaamisia WWW-sivuja, voidaan sanoa, että PHP on monessa suhteessa paras vaihtoehto. Tämän todistaa sekin, että PHP:tä käytetään WWW-sivustoissa yhä enemmän.
PHP-kotisivu, saatavilla WWW-muodossa
<URL: http://www.php.net/>
, viitattu 23.10.2000
PHP-historia, saatavilla WWW-muodossa
<URL: http://www.php.net/manual/phpfi2.html>
, viitattu 23.10.2000
PHP-uudistuksia, saatavilla WWW-muodossa
<URL: http://www.zend.com/zend/whats-new.php>
, viitattu 23.10.2000
PHP-käsikirja, saatavilla WWW-muodossa
<URL: http://www.php.net/manual/>
, viitattu 23.10.2000
PHP-projekteja, saatavilla WWW-muodossa
<URL: http://www.php.net/sites.php>
ja <URL: http://www.php.net/projects.php>
, viitattu 23.10.2000
PHP-käyttö, saatavilla
WWW-muodossa <URL: http://www.php.net/usage.php>
, viitattu 23.10.2000
PHP-lähdekoodi, saatavilla WWW-muodossa
<URL: http://www.php.net/downloads.php>
, viitattu 23.10.2000
ASP-tietoutta, saatavilla WWW-muodossa
<URL: http://msdn.microsoft.com/workshop/server/asp/aspfeat.asp>
,
viitattu 23.10.2000
W3C-kotisivu, saatavilla WWW-muodossa
<URL: http://www.w3.org/>
, viitattu 23.10.2000
Liitteessä on esitelty
päivyrisovelluksen koodi. Koodia on kommentoitu risuaitamerkillä
#
ja //
-merkinnällä
alkavilla riveillä. HTML-elementit on esitetty normaalein kirjasimin ja
PHP-tulkille tarkoitetut komennot kursivoiduin kirjasimin. Lihavoiduin
kirjasimin on esitetty kohdat, jotka poistamalla saadaan aikaan sovelluksen
versio, joka ei käytä tietokantaa ja jonka avulla ei voida tehdä
päivyrimerkintöjä.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html lang=fi> <head> <title>Päivyri</title> <meta name="rating" content="safe for kids"> <meta name="robots" content="index,nofollow"> <meta name="Description" content="Sivu sisältää PHP:llä tehdyn nettipäivyrin, joka on tehty LuK-tutkielmaa varten."> <meta name="KeyWords" content="Päivyri, Nettipäivyri, LuK-tutkielma, PHP"> <meta name="author" content="Pauli Kujala"> <link rev="Made" href="mailto:pjkujala@mit.jyu.fi"> </head> <body> <h1>Päivyri</h1> <h2>Nettikäyttöinen päivyrisovellus</h2> <h3>© 2000 Pauli Kujala</h3> <h3>23.10.2000</h3> <p> <strong>Päivyri</strong>n avulla voit käyttää nettipäivyriä ja tehdä muistiinpanoja päiville. Päivyri vaatii toimiakseen tietokannan sekä mahdollisuuden käyttää <a href="http://www.php.net/">PHP-komentoja</a>. </p> <?php ######################## globaalit muuttujat ######################## # Alustetaan taulukoita ja muuttujia. Tässä globaalien taulukoiden # käyttö on perusteltua. Yksinkertaisuuden vuoksi myös muita # muuttujia on määritelty globaaleiksi. $kuukaudet = array("ei kuu", // aloitetaan kuukaudet ykkösestä "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu" ); $viikonpaivat = array("ma","ti","ke","to","pe","la","su"); $nyk_aika = time(); $nyk_paiva = date("j",$nyk_aika); $nyk_kuukausi = date("n",$nyk_aika); $nyk_vuosi = date("Y",$nyk_aika); # Käyttäjänä yksi henkilö, jonka tiedot on tallennettu tietokannan # Henkilöt-tauluun ja jonka HenkilöID-kentässä on arvo 1. # Kaikki päivyrisovellusta käyttävät henkilöt voivat siis muuttaa # toisten käyttäjien tekemiä muistiinpanoja (julkinen päivyri). # Jos halutaan lisätä ominaisuus, jonka avulla kukin käyttäjä voi # muokata vain omia muistiinpanojaan, vaatisi se koodiin # käyttäjätunnusten hallinnan, salasanojen hallinnan sekä # sisäänkirjautumisrutiinin. $tietokantayhteys = 0; $henkiloid = 1; # Määritellään VIRHE-vakio tietokannan käsittelyssä tapahtuvia # virhetilanteita varten. define(VIRHE, "Virhe tietokannan käsittelyssä."); ######################## funktiot ################################ # Aliohjelmia ei suoriteta heti sivua ladattaessa, vaan vasta niitä # kutsuttaessa. function avaa_tietokanta() { global $tietokantayhteys; $tietokantayhteys = odbc_connect("lukki", "", ""); if ( !$tietokantayhteys ) return VIRHE; return ""; } ######### function sulje_tietokanta() { global $tietokantayhteys; if ( $tietokantayhteys ) odbc_close($tietokantayhteys); return ""; } ######### function hae_tallenne($henkiloid,$p,$k,$v) { global $tietokantayhteys; if ( !$tietokantayhteys ) avaa_tietokanta(); $query = "select Tallenne from Kalenteri where HenkilöID=" . $henkiloid . " and Pvm='" .$p. "." .$k. "." .$v. "'"; $result_id = odbc_exec($tietokantayhteys, $query); if ( !$result_id ) return VIRHE; $onko_tall = odbc_fetch_row($result_id); $tallenne = ""; if ( $onko_tall ) $tallenne = odbc_result($result_id, "Tallenne"); odbc_free_result($result_id); sulje_tietokanta(); return $tallenne; } ######### function tallenna_kirjoitus($henkiloid,$p,$k,$v,$teksti,$poista) { global $tietokantayhteys; if ( !$tietokantayhteys ) avaa_tietokanta(); if ( $poista ) { # Ollaan poistamassa muistiinpanoa. $query = "delete from Kalenteri where HenkilöID=" . $henkiloid . " and Pvm='" .$p. "." .$k. "." .$v."'"; } else { # Ollaan tallentamassa muistiinpanoa. # Tutkitaan ensin onko ko. päivälle jo tehty muistiinpanoa. # Jos on, korvataan se. Muussa tapauksessa luodaan uusi # muistiinpano. $query = "select KalenteriID from Kalenteri where HenkilöID=" . $henkiloid . " and Pvm='" .$p. "." .$k. "." .$v. "'"; $result_id = odbc_exec($tietokantayhteys, $query); if ( !$result_id ) return VIRHE; $onko_tall = odbc_fetch_row($result_id); # Jos aikaisemmin oli tehty muistiinpano, muuttujan $kalenteriID # arvoksi tulee positiivinen luku, jota käytetään muistiinpanon # korvaamisessa. $kalenteriID = -1; if ( $onko_tall ) $kalenteriID = odbc_result($result_id, "KalenteriID"); odbc_free_result($result_id); if ( $kalenteriID < 0 ) $query = "insert into Kalenteri (HenkilöID,Pvm,Tallenne) " . "values (" .$henkiloid. ",'" .$p. "." .$k. "." .$v. "','" .$teksti. "')"; else $query = "update Kalenteri set Tallenne='" .$teksti. "' where KalenteriID=" .$kalenteriID; } $result_id = odbc_exec($tietokantayhteys,$query); sulje_tietokanta(); if ( !$result_id ) return VIRHE; return ""; } ######### function poista_kirjoitus($henkiloid,$p,$k,$v) { # Käytetään edellä määriteltyä tallenna_kirjoitus()-aliohjelmaa # viemällä sille viimeisenä parametrina true-arvo. tallenna_kirjoitus($henkiloid,$p,$k,$v,"",true); } ######### function tulosta_kalenteri($vuosi,$kuukausi) { # Määritellään aiemmin määritellyt muuttujat näkymään myös tässä # aliohjelmassa. Muuttujien arvot voitaisiin myös tuoda parametrina # tälle aliohjelmalle. global $kuukaudet, $viikonpaivat, $nyk_aika, $nyk_kuukausi, $nyk_vuosi, $nyk_paiva; global $textarea_paiva, $textarea_kuukausi, $textarea_vuosi; global $henkiloid; # Tulostetaan HTML-sivulle form-elementti, joka kutsuu itseään # (action="paivyri.php3"). ?> <form method="post" action="paivyri.php3"> <?php # Muodostetaan tiedot kuukauden ensimmäisestä päivästä (viikonpäivä). # date()-aliohjelmalle ensimmäisenä vietävä parametri "w" kertoo # viikonpäivän (su=0, ma=1, ..., la=6). Jos kyseessä on sunnuntai, # muutetaan se suomalaiseen asuun numeroksi 7. $eka_pv = mktime(0,0,0,$kuukausi,1,$vuosi); $wday = date("w", $eka_pv); if ( $wday == 0 ) $wday = 7; # Tulostetaan HTML-sivulle form-elementtiä varten piilotetut tiedot # näytettävästä kuukaudesta ja vuodesta, sekä tekstialueessa # näytettävän muistiinpanon päivämäärästä. ?> <input type="hidden" name="kuukausi" value="<?php echo $kuukausi; ?>"> <input type="hidden" name="vuosi" value="<?php echo $vuosi; ?>"> <input type="hidden" name="textarea_paiva" value="<?php echo $textarea_paiva; ?>"> <input type="hidden" name="textarea_kuukausi" value="<?php echo $textarea_kuukausi; ?>"> <input type="hidden" name="textarea_vuosi" value="<?php echo $textarea_vuosi; ?>"> <?php # Tulostetaan otsikkoon kuukausi ja vuosi. # Tehdään sivulle HTML-taulukko kuukauden päivistä. # Tulostetaan taulukon ensimmäiselle riville viikonpäivien nimet. ?> <h2><?php echo $kuukaudet[$kuukausi] . " " . $vuosi; ?></h2> <table border=3> <tr> <td> <table border=1> <tr> <?php $leveys = floor(100/count($viikonpaivat)); for ($i = 0; $i < count($viikonpaivat); $i++) print("<th width=\"" . $leveys . "%\">" . $viikonpaivat[$i] . "</th>\n"); ?> </tr> <tr> <?php # date()-aliohjelman ensimmäinen parametri "t" antaa kuukaudessa # olevien päivien lukumäärän. # Muuttuja $vkp sisältää tulostettavan päivän viikonpäivän. $viim = date("t",$eka_pv); $vkp = $wday; $kuluva_kuu = false; $nykypv = false; # Tulostetaan kuukauden ensimmäisen viikon alkuun tyhjiä soluja kunnes # vuorossa on kuukauden ensimmäinen päivä. for ($i=1; $i<$wday; $i++) print("<td> </td>\n"); # Tulostetaan kukin kuukauden päivä omaan soluunsa painikkeena. # Siirrytään taulukon seuraavalle riville kun on tulostettu sunnuntai. # Jos ollaan tulostamassa kuluvaa päivämäärää, asetetaan solun # taustaväriksi punainen. # Jos päivälle on tehty muistiinpanoja, asetetaan solun taustaväriksi # keltainen. # Jos kuluvalle päivämäärälle on tehty muistiinpanoja, asetetaan solun # taustaväriksi sininen. for ($i=1; $i<=$viim; $i++) { $nykypv = false; if ( $nyk_vuosi == $vuosi && $nyk_kuukausi == $kuukausi && $nyk_paiva == $i ) { $nykypv = true; $kuluva_kuu = true; } $tallenne = hae_tallenne($henkiloid,$i,$kuukausi,$vuosi); $bgcolor = ""; if ( $nykypv == true ) $bgcolor = "red"; if ( $tallenne != "" ) $bgcolor = "yellow"; if ( $nykypv == true && $tallenne != "" ) $bgcolor = "blue"; print("<td align=right"); if ( $bgcolor != "" ) print(" bgcolor=\"" . $bgcolor . "\""); print("><input type=\"submit\" name=\"paivaButton\" value=\"" .substr("0".$i,-2) . "\"></td>\n"); $vkp++; if ( $vkp > 7 && $i < $viim) { print("</tr>\n<tr>\n"); $vkp = 1; } } # Tulostetaan lopuksi viimeinen rivi viimeisen päivän jälkeen täyteen # tyhjiä soluja. for ($i=$vkp; $i<=7; $i++) print("<td> </td>\n"); ?> </tr> <tr><td colspan=7> </td></tr> <?php # Tulostetaan valintalista, jonka avulla voidaan siirtyä muihin # kuukausiin edellisen, kuluvan ja seuraavan vuoden aikana. ?> <tr> <td colspan=7 align=left> <select name="kuu_ja_vuosi" size="1"> <?php for ($v=$vuosi-1; $v<=$vuosi+1; $v++) for ($i=1; $i<=12; $i++) { print("<option"); if ( $i == $kuukausi && $v == $vuosi ) print(" selected"); print(">" . $kuukaudet[$i] . " " . $v . "</option>\n"); } ?> </select> <input type="submit" name="siirryButton" value="Siirry"> </td> </tr> <?php if ( $kuluva_kuu == false ) : # Jos näkyvillä ei ole kuluvan kuukauden kalenteri, näytetään painike, # jolla siihen voidaan siirtyä nopeasti. # Tässä PHP-koodissa käytetään PHP:n erinomaista if..endif-rakennetta. ?> <tr> <td colspan=7 align=center> <input type="submit" name="kuluvaKuuButton" value="<?php print($kuukaudet[$nyk_kuukausi] . " " . $nyk_vuosi); ?>"> </td> </tr> <?php endif; ?> </table> </td> <?php # Tulostetaan tekstialue, johon voidaan tehdä muistiinpanoja. Haetaan # tekstialueeseen halutun päivämäärän muistiinpano, jos sellainen on # tehty. Tutkitaan ja näytetään myös muistiinpanotekstin viikonpäivä. $ta_pvm = mktime(0,0,0,$textarea_kuukausi,$textarea_paiva,$textarea_vuosi); $wday = date("w", $ta_pvm); if ( $wday == 0 ) $wday = 7; $wday--; ?> <td> </td> <td align=center> <p> <strong><?php print($viikonpaivat[$wday] . " " . $textarea_paiva . "." . $textarea_kuukausi . "." . $textarea_vuosi); ?></strong><br> <textarea name="taTallenne" rows=10 cols=40><?php print(hae_tallenne($henkiloid,$textarea_paiva, $textarea_kuukausi,$textarea_vuosi)); ?></textarea> </p> <p> <input type="submit" name="tallennus" value="Tallenna"> <input type="submit" name="tallennus" value="Poista"> </p> </td> </tr> </table> </form> <?php } ######################## "pääfunktio" ############################ # Varsinainen PHP-komentojen suoritus alkaa tästä. # Tutkitaan minkä kuukauden kalenteri halutaan näyttää. # Jollei vielä asetettu muuttujia $kuukausi ja $vuosi (päivyriä # kutsutaan ensimmäistä kertaa), asetetaan kuluva kuukausi ja vuosi. if ( !isset($kuukausi) ) $kuukausi = $nyk_kuukausi; if ( !isset($vuosi) ) $vuosi = $nyk_vuosi; # Jos on valittu jokin alkio kuukausi ja vuosi -valintalistasta, # näytetään valitun kuukauden kalenteri. if ( isset($kuu_ja_vuosi) ) { $osat = explode(" ",$kuu_ja_vuosi); if ( count($osat) == 2 ) { $k = 0; for ($i=1; $i<count($kuukaudet); $i++) if ( $osat[0] == $kuukaudet[$i] ) $k = $i; $osat[1] = intval($osat[1]); if ( ( 0 < $k ) && ( 0 <= $osat[1] ) ) { $kuukausi = $k; $vuosi = $osat[1]; } } } # Jos halutaan näytettäväksi kuluvan kuukauden kalenteri, tehdään se. if ( isset($kuluvaKuuButton) ) { $kuukausi = $nyk_kuukausi; $vuosi = $nyk_vuosi; } # Jos on painettu joko Tallenna- tai Poista-painiketta, tehdään haluttu # toiminto tekstialueen muistiinpanolle. if ( isset($tallennus) ) { switch ( $tallennus ) { case "Tallenna" : tallenna_kirjoitus($henkiloid, $textarea_paiva, $textarea_kuukausi, $textarea_vuosi, $taTallenne, $false); break; case "Poista" : poista_kirjoitus($henkiloid, $textarea_paiva, $textarea_kuukausi, $textarea_vuosi); break; default : break; } $tallennus = ""; } # Jos ei ole vielä alustettu tekstialueessa näkyvää päivämäärää, # tehdään se nyt. Tämä tapahtuu vain skriptiä ensimmäistä kertaa # kutsuttaessa. Tekstialueessa näkyvän muistinpanon päivämäärä säilyy # tallessa, vaikka näytettävän kuukauden kalenteri vaihtuisikin. if ( !isset($textarea_paiva) || $textarea_paiva == "" ) textarea_paiva = $nyk_paiva; if ( !isset($textarea_kuukausi) || $textarea_kuukausi == "" ) $textarea_kuukausi = $nyk_kuukausi; if ( !isset($textarea_vuosi) || $textarea_vuosi == "" ) $textarea_vuosi = $nyk_vuosi; # Jos on painettu kuukauden jotakin päivämääräpainiketta, näytetään # muistiinpano kyseiseltä päivältä. if ( isset($paivaButton) ) { $textarea_paiva = intval($paivaButton); $textarea_kuukausi = intval($kuukausi); $textarea_vuosi = intval($vuosi); } # Tulostetaan kalenteri halutulta kuukaudelta ja vuodelta. tulosta_kalenteri($vuosi,$kuukausi); ?> <p> <a href="http://validator.w3.org/check/referer"> <img src="/images/vh40.gif" alt="Valid HTML 4.0!" height="31" width="88"> </a> </p> </body> </html>