PHP-opas
Mureakuha
PHP-opas
Oppaan mahdollisille uusille kehittäjille
Vain asiasisältöä. Toivottavasti kirjoituksen asiapitoinen tyyli säilyy. Yritys on tehdä oppaasta mahdollisimman kattava. Punaisella merkityt ovat ToDoa.
Aloittelijoille/mitä tulee tietää
Tätä opasta ei ole tarkoitettu ensimmäistä ohjelmointikieltään opiskelevan aloittelijan ensimmäiseksi oppaaksi. Mikäli et osaa mitään ohjelmointikieltä, suosittelen lukemaan ensin Ohjelmointiputkan käytännön PHP-oppaan. Mutta periaatteessa tämänkin oppaan avulla voi kielen oppia, vaikkei aikaisempaa ohjelmointikokemusta olisikaan, tietysti englannin kielen hallitseminen on eduksi; ovathan funktiot ja rakenteet nimetty juuri englanniksi. Opas sisältää paljon kohtia joita ilmankin voi ohjelmoida ihan mainosti (esimerkiksi olioita tai muuttujien viittauksia ei aloittelijoiden välttämättä kannata alkuun edes alkaa opettelemaan), joten ei kannata hätääntyä vaikka kaikkea tietoa ei ensilukemisella sisäistäkään: edistyneemmät asiat kehittyvät lähinnä vasta käytännön (ohjelmoinnin) myötä.
Syntaksi
Tulostus
PHP:ssä on useita tapoja tulostaa tietoa, mutta tässä oppaassa on lähes poikkeuksetta käytetty komentoa echo, joka tulostaa sille annetut arvot.
<?php echo "Tämä teksti tulostuu"; ?>
Tämä teksti tulostuu
Eli lainausmerkkien sisällä oleva tulostuu. Tulostaa voidaan myös useampia merkkijonoja peräkkäin yhdellä echo-komennolla, erottamalla tulostettavat merkkijonot pisteellä tai pilkulla.
<?php echo "Tämä teksti ", "tulostuu"; ?>
Tämä teksti tulostuu
<?php echo "Tämä teksti ". "tulostuu"; ?>
Tämä teksti tulostuu
Toinen yleisesti käytetty komento tiedon tulostamiseen on komento print, joka eroaa echosta vain hyvin vähän. Periaatteessa voit käyttää yksinkertaiseen tulostamiseen kumpaa komentoa haluat.
Sisennys
Vaikka PHP-tulkki ei välitä välilyönneistä, kannattaa ohjelmakoodia sisentää, jotta koodia on helpompi tulkita. Yleisin tapa sisentää on, että edellisestä riviin liittyvät koodit tulevat sisennettynä, kuten esim if-lauseessa if:n suorittama koodirivi.
Yleistä syntaksista eli kielen yleisestä rakenteesta
PHP:n syntaksi muistuttaa suuresti C-kielen vastaavaa. Koska PHP on tulkattava skriptikieli, joka voidaan upottaa muun sisällön joukkoon, tulee itse koodi erottaa muusta sisällöstä. Se onnistuu seuraavasti:
<? echo "Tämä tulkitaan koodiksi, mikäli PHP:n asetus short-open-tag on On-tilassa. Tämä ei ole kuitenkaan suositeltava tapa, sillä asetus saattaa olla esimerkiksi xml-ristiriidan johdosta Off-tilassa."; ?>
Kuten koodista huomaakin, tämä tulkitaan useissa ympäristöissä PHP-koodiksi, muttei kaikissa. Suositeltava tapa onkin käyttää <?php-tageja seuraavasti:
<?php echo "Tämä on suositeltava tapa sillä se toimii kaikissa ympäristöissä."; ?> //Tulostaa "Tämä on suositeltava tapa sillä se toimii kaikissa ympäristöissä."
Lisäksi käytössä on myös <script> tagilla määritelty tapa:
<script language="php"> echo "Näinkin tämä toimii."; </script> //Tulostaa "Näinkin tämä toimii."
PHP-lauseet päätetään puolipisteeseen. Viimeistä lausetta ei tarvitse päättää puolipisteeseen, mutta on silti hyvä tapa tehdä niin, esimerkiksi mikäli sen jälkeen myöhemmin lisätään lauseita.
<?php echo "Eka lause"; echo "Toka lause"; echo "Kolmas lause"; ?> //Tulostaa: //Eka lause //Toka lause //Kolmas lause
Kommentit
Kommentointi onnistuu PHP:ssä joko //-merkeillä, /* ja */ -yhdistelmällä tai #-merkillä.
<?php //Tämä koodi tulostaa "Terve maailma!" echo "Terve maailma!"; /* Credits and Copyright: Jarkko Iso-Heiko */ # Tämä on myös kommentti ?> //Tulostaa "Terve maailma!"
PHP-tulkki ei siis välitä kyseissä esimerkissä muista merkinnöistä kuin echo-lauseesta.
Lauserakenteet - Aaltosulkeet
Lauserakenteita voidaan muodostaa aaltosulkeilla. Sillä voidaan yhdistää monia lauseita yhdeksi kokonaisuudeksi.
<?php $luku = 5; if ($luku == 5) { echo "Luku on "; echo "5"; } else echo "Luku ei ole 5"; ?> //Tulostaa "Luku on 5"
Eli käytämme tässä esimerkissä ehtolausetta JOS (if) $luku ON (==) 5, niin tulostetaan "Luku on " sekä "5". Koska ehtolause sisältää kaksi echo-lausetta pitää ne sulkea yhteen aaltosulkeilla. Jos olisimme kirjoittaneet tulostettavan tekstin yhteen riviin, aaltosulkeita ei olisi tarvittu.
<?php $luku = 5; if ($luku == 5) echo "Luku on 5"; else echo "Luku ei ole 5"; ?> //Tulostaa "Luku on 5"
Muuttujat
Yleistä muuttujista
Muuttujat ovat muistiin siirrettäviä muutettavissa olevia arvoja. Tälläisen tunnistaa koodissa dollarimerkistä ($). Muuttujat ovat useimmille tuttuja jo peruskoulumatematiikasta. Yhtälö x = 5 + 5 on itse asiassa PHP:n muodollisia syntakseja lukuunottamatta ohjelmointia. Siinä sijoitetaan muuttujaan x arvo 10. Sama PHP:llä:
<?php $x = 5 + 5; //Sijoitetaan muuttujaan $x arvo 5 + 5 eli 10 echo $x; //Tulostaa $x:n arvon, eli "10" ?> //Tulostaa "10"
Muuttujien nimeäminen
Muuttujan nimissä hyväksyttyjä merkkejä ovat aakkoset (skandit mukaanlukien), alaviiva (_), numerot sekä ASCII merkit väliltä 127-255. Yksi rajoitus kuitenkin edellä mainittuihin sääntöihin on, muuttuja ei saa alkaa numerolla. Käytännössä on kuitenkin hyvä pysyä vain numeroissa, kirjaimissa A-Z ja alaviivassa.
<?php $ällötys = "kaalikääryleet"; //Kelpaa $vuosi2005 = "hyvä"; //Kelpaa $1999 = "huono vuosikerta"; //Ei kelpaa ?>
Muuttuja muuttujan nimessä
Muuttujia voidaan käyttää itse muuttujien nimessä, kunhan käytetään aaltosulkeita. Ominaisuuden hyödyllisyys voidaan kyseenalaistaa, sillä lähes kaikissa tapauksissa on huomattavasti järkevämpää käyttää esimerkiksi moniulotteisia taulukoita.
<?php $auto = "Volvo"; $muuttuja = "auto"; echo ${$muuttuja}; //Tulostaa muuttujan $auto arvon eli "Volvo" ?>
Muuttujaan viittaaminen (reference)
Voimme myös luoda uuden muuttujan, joka viittaa johonkin olemassaolevaan muuttujaan. Tällöin muuttujat ovat linkitettyjä keskenään. Kun alkuperäistä muuttujan arvoa muutetaan, muuttuu myös linkitetyn muuttujan arvo. Samoin kun linkitettyä arvoa muutetaan, muuttuu myös alkuperäinen muuttuja. Tätä linkitystä kutsutaan usein viittaukseksi ja se tapahtuu käyttämällä & merkkiä seuraavasti:
<?php $a = 5; $b = &$a; echo $b; //Tulostaa 5 $a = $a + 1; echo $b; //Tulostaa 6 $b = $b + 1; echo $a; //Tulostaa 7; ?>
Viittaus voidaan myös tehdä toisella syntaksilla näin:
<?php $a = 5; $b =& $a; echo $b; //Tulostaa 5 $a = $a + 1; echo $b; //Tulostaa 6 $b = $b + 1; echo $a; //Tulostaa 7; ?>
Tähän aiheeseen liittyy myös kohta muuttujaan viittaaminen funktioissa.
Muuttujatyypit
PHP on vahvasti tyypitön kieli. Käytännössä tämä tarkoittaa, että se on hyvin aloittelijaystävällinen kun muuttujien tyypit tunnistetaan automaattisesti. Tämä ei kuitenkaan tarkoita etteikö eri tyyppisiä muuttujia olisi kielessä olemassa. Muuttujia ei tarvitse eikä voi esitellä ollenkaan muutamaa poikkeusta lukuunottamatta. Muuttujien tyypin saa selville funktiolla gettype($muuttuja). PHP:n muuttujatyypit ovat:
- Merkkijono (string)
- Kokonaisluku (integer)
- Liukuluku (float tai double)
- Totuusarvo (boolean)
- Tyhjä (NULL)
- Taulukko (array tai table)
- Olio (object)
Näiden lisäksi on vielä olemassa erikoismuuttujatyyppi resource, mutta siihen ei puututa tässä oppaassa.
Merkkijono (string)
Merkkijono sisältää nimensä mukaisesti merkkejä jonossa. Merkkijonon voi määritellä joko lainausmerkein ("), heittomerkein (') tai "here document"-syntaksilla.
<?php $merkkijono1 = "Tässä muuttujassa on merkkijono (string)"; $merkkijono2 = 'Tässä muuttujassa on merkkijono (string)'; $merkkijono3 = <<<END Tässä muuttujassa on merkkijono (string) END; ?> //Kaikki muuttujat sisältävät täsmälleen saman yksirivisen merkkijonon
Vaikka kaikki tavat tuottavat tässä saman lopputuloksen, ne silti eroavat toisistaan. Lainausmerkein määriteltyyn merkkijonoon voidaan upottaa muuttujia ja erikoismerkkejä.
<?php $nimi = "JTS"; echo "Moi, minun nimeni on $nimi"; ?> //Tulostaa "Moi, minun nimeni on JTS"
Mikäli on vaarana että muuttuja sekoittuu muuhun tekstiin (haluat vaikka tulostaa $ merkin juuri ennen muuttujaa), voidaan muuttuja eristää muusta tekstistä aaltosulkein:
<?php $rahaa = 100; echo "Moi, minulla on rahaa ${$rahaa}"; ?> //Tulostaa "Moi, minulla on rahaa $100"
Lainausmerkein määriteltäessä on käytössä seuraavia erikoismerkintöjä:
- \n Rivinvaihto
- \t Tabulaattori
- \\ Kenoviiva
- \$ Dollarinmerkki
- \" Lainausmerkki
Heittomerkein määriteltäessä ei voi lisätä suoraan muuttujia eikä erikoismerkkejä. Itse heittomerkin saa muuttujaan \' merkinnällä.
<?php $nimi = "JTS"; echo 'Moi, minun nimeni on $nimi'; ?> //Tulostaa "Moi, minun nimeni on $nimi"
Merkkijonoja voidaan yhdistää pisteellä (.). Tähän on olemassa kaksi erilaista tapaa. Merkintä on hieman erilainen, mutta lopputulos identtinen.
<?php $alku = "Linja"; $loppu = "auto"; $yhdiste = $alku . $loppu; //Yhdistää $alku ja $loppu merkkijonot yhteen $alku .= $loppu; //Lisää $loppu muuttujan $alku muuttujaan ($alku = $alku . $loppu;) ?>
Kokonaisluku (integer)
Kokonaislukujen (integer) sekä liukulukujen (float) erona ovat desimaalit. Kokonaisluvut eivät siis saa sisältää desimaaleja. Kokonaislukujen muistiavaruus on yleensä 32-bittinen jolloin lukua 2 147 483 647 suuremmat tai lukua -2 147 483 646 pienemmät kokonaisluvut ovat tyypiltään liukulukuja, joiden muistiavaruus on suurempi.
<?php $luku1 = 2147483647; //Muuttujan tyyppi on kokonaisluku $luku2 = 2147483648; //Muuttujan tyyppi on liukuluku ?>
Liukuluku (float tai double)
Liukuluvut voivat sisältää desimaaleja. Desimaalierottimena toimii yleisesti piste. Lisäksi liukuluvuilla voidaan ilmaista kymmenen potensseja "e"-merkillä (versaalilla tai gemenalla eli isolla tai pienellä kirjaimella).
<?php $luku1 = 1.5; //Muuttujan tyyppi on liukuluku $luku2 = 1E3; //Saa arvon 100 $luku3 = 5e-2; //Saa arvon 0.05 ?>
Totuusarvo (boolean)
Totuusarvomuuttujalla voi olla vain kaksi arvoa, tosi (TRUE) tai epätosi (FALSE). Kirjainkoolla ei ole väliä.
<?php $muuttuja = false; ?>
Kaikki muuttujat voidaan muuttaa totuusarvoiksi ja se onkin oleellista eritoten ehtolauseissa. Kaikki seuraavat muuttujat tulkitaan totuusarvoiltaan epätosiksi (FALSE):
| Totuusarvo (boolean): | FALSE |
| Kokonaisluku (integer): | 0 |
| Liukuluku (float): | 0.0 |
| Merkkijono (string): | "0" tai tyhjä merkkijono |
| Taulukko (array tai table): | tyhjä taulukko |
| Tyhjä: | NULL |
Kaikki muut muuttujat paitsi yllämainitut tulkitaan totuusarvoiltaan tosiksi (TRUE). Seuraava esimerkki suorittaa ehtolauseen koodin, sillä kokonaisluku 0 tulkitaan vertailussa == epätodeksi:
<?php $x = 0; if ($x == false) echo "Muuttujan x arvo muutettuna boolean muuttujaksi on FALSE."; ?>
Ehtolauseissa voidaan myös käyttää myös tyyppiä vertailevaa merkintää, jolloin vertailuun lisätään yksi ylimääräinen = merkki:
<?php $x = 0; if ($x === false) echo "Muuttuja x on boolean-tyyppinen muuttuja, jonka arvo on FALSE."; ?>
=== merkintää käytettäessä siis muuttujan tulee olla paitsi arvoltaan sama, niin myös tyypiltään identtinen vertailtavan arvon kanssa. ===-vertailua tuleekin käyttää esimerkiksi strpos funktion arvoa tarkistettaessa, sillä se voi palauttaa haettavan merkin kohdaksi paikan 0, joka == vertailulla tulkitaan arvoltaan FALSE muuttujaksi, eli arvoksi ettei haettavaa tietoa olisi löynyt laisinkaan (vaikka näin asia ei oikeasti olekaan). Katso myös kohta vertailuoperaattorit.
Tyhjä (NULL)
Tyhjä on nimensä mukaan tyhjä muuttujatyyppi. Isoilla ja pienillä kirjaimilla ei ole eroa.
<?php $muuttuja = null; //Muuttuja ilman arvoa, sama kuin muuttujaa ei olisi määritelty lainkaan ?>
Taulukko (array tai table)
Taulukolla voidaan antaa yhdelle muuttujalle useita arvoja. Taulukko sisältää paitsi arvoja (value) myös avaimia (key), joiden perustella eri arvot löydetään taulukosta. Taulukko voidaan määritellä useilla tavoilla; yksi tapa on käyttää käskyä array():
<?php $taulukko = array("Eka", "Toka", "Kolmas"); ?> //Luo taulukon $taulukko jossa on kolme arvoa, "Eka", "Toka" ja "Kolmas"
Koska määritimme ainoastaan arvot, PHP antaa niille avaimet automaattisesti, ensimmäisen taulukon solun avain on 0, toisen 1 ja kolmannen 2.
<?php $taulukko = array("Eka", "Toka", "Kolmas"); echo $taulukko[1]; ?> //Tulostaa "Toka"
Taulukolle voidaan myös antaa itse avaimet jotka voivat olla joko kokonaislukuja taikka merkkijonoja.
<?php $taulukko = array("Ensimmäinen" => "Eka", "Toinen" => "Toka", "Kolmas" => "Kolmas"); echo $taulukko["Toinen"]; ?> //Tulostaa "Toka"
Taulukkoon voidaan myös lisätä arvoja automaattisella numeerisella avaimella seuraavasti:
<?php $taulukko[] = "Eka"; $taulukko[] = "Toka"; $taulukko[] = "Kolmas"; ?> //Luo samanlaisen taulukon kuin ensimmäisessä taulukkoesimerkissä
Myös avain voidaan määritellä hakasulkumerkinnällä:
<?php $taulukko["Ensimmäinen"] = "Eka"; ?> //Tekee taulukon joka vastaa määritystä $taulukko = array("Ensimmäinen" => "Eka);
Taulukko voi myös olla moniulotteinen, eli taulukon jokainen arvo voi olla uusi taulukko.
<?php $taulukko = array("numerot" => array("nolla", "yksi", "kaksi", "kolme", "neljä")); echo $taulukko["numerot"][0]; ?> //Tulostaa "nolla"
Taulukon sekä avaimet että arvot voivat olla lähes mitä tietotyyppiä tahansa, ja niitä voi olla sekaisin samassa taulukossa. Suosittelen kuitenkin käyttämään avaimissa vain tietotyyppejä kokonaisluku sekä merkkijono.
<?php $taulukko = array(1 => "Yksi", "Kaksi" => 2); //Tekee taulukon jossa solussa 1 on arvo "Yksi", ja solussa "Kaksi" on arvo 2 ?>
Myös lomakkeen inputteja voi taulukoida
<?php print_r($testi); echo "<br>" ?> <html> <head> <title>Testi</title> </head> <body> <form method="post" name="testiformi" action="testi.php"> <input type="text" name="testi[0]"><?php echo $testi[0]; ?></input> <input type="text" name="testi[1]"><?php echo $testi[1]; ?></input> <input type="text" name="testi[2]"><?php echo $testi[2]; ?></input> /* for($i; $i<3; $i++) { * echo '<input type="text" name="testi['.$i.']">'.<?php echo $testi[0]; ?>.'</input>'; * } */ </form> </body> </html>
Olio (object)
Katso luku 1.8 (oliot ja luokat).
Muuttujien tyyppien yhdistämisestä/muunnoksista
PHP sallii esimerkiksi merkkijonon ja kokonaisluvun yhteenlaskun. Tällöin merkkijono yritetään tulkita mahdollisimman hyvin luvuksi, joko liuku- tai kokonaisluvuksi riippuen tilanteesta. Merkkijonon numeerinen tulkinta kuitenkin edellyttää että sen alku on numeerisesti tulkittavissa. Myös . ja E merkinnät tulkitaan numeerisiksi vastineikseen. Mikäli merkkijono alkaa muilla kuin numeerisella arvolla tulkitaan sen numeeriseksi arvoksi 0.
<?php $merkkijono = "215mk on yhtä kuin 36.2euroa"; $luku = 15; echo $merkkijono + $luku; ?> //Tulostaa "230" jonka tyyppi on kokonaisluku, $merkkijono tulkitaan siis kokonaisluvuksi 215 <?php $merkkijono = "euroina 215mk on 36.2euroa"; $luku = 15; echo $merkkijono + $luku; ?> //Tulostaa "15" koska $merkkijono tulkitaan luvuksi 0
Muuttujan tietotyyppi voidaan muuntaa halutuksi myös esimerkiksi C:stä tai Javasta tutulla cast-tyypityksellä. Tällöin haluttu kohdetyyppi merkitään sulkuihin muuttujan tai arvon eteen. Mahdollisia muunninsanoja ovat:
- kokonaisluvuille (integer) ja (int)
- boolean-muuttujalle (boolean) tai (bool)
- liukuluvulle (float), (double) tai (real)
- merkkijonolle (string)
Lisäksi assosiatiivinen taulukko voidaan muuttaa olioksi käyttäen muunninta (object) niin, että taulukon avaimet ovat luotavan olion attribuuttien nimiä ja arvot vastaavasti niiden arvoja.
Huomaa, että PHP:ssä ei ole erillistä muuttujatyyppiä yksittäiselle merkille. Tämän vuoksi esimerkiksi lukua ei voida suoraan muuttaa merkiksi cast-tekniikalla. Siihen tarvitaan erillinen chr-funktio, joka palauttaa annettua numeroa vastaavan ASCII-merkin. Vastaavasti yksittäisen merkin (tai siis tarkalleen ottaen merkkijonon ensimmäisen merkin) saa muutettua sitä vastaavaksi numeroksi ord-funktiolla.
<?php $numero = (float) "27.2" + (int) "tekstiä"; echo $numero . "\n"; // Tulostaa "28.2" $string = chr( 87 ) . chr( 105 ) . chr( 107 ) . chr( 105 ); echo $string . "\n"; // Tulostaa "Wiki" $boolTrue = (boolean) "" === false; // saa arvokseen true $string = (string) $boolTrue; // saa arvokseen 1 echo ord( $string ) . "\n"; // Tulostaa "49" $taulu = array("avain" => "arvo"); $olio = (object) $taulu; echo $olio->avain; // Tulostaa "arvo" ?>
PHP:n dokumentaatiossa löytyy listaus PHP type comparison tables josta näkee tyypin määräytymisen vertailutilanteissa.
Vakiot
Vakiot eroavat sikäli muuttujista ettei niitä voida muuttaa taikka poistaa suorituksen aikana. Vakiot ovat superglobaaleja, eli ne näkyvät kaikkialla (myös funktioiden sisällä ilman globalia). Vakiot voivat olla tyypiltään joko totuusarvoja (boolean), kokonaislukuaja (integer), liukulukuja (float) taikka merkkijonoja (string). Isot ja pienet kirjaimet eroavat (case-sensitive). Vakiot määritellään define() funktiolla.
<?php define("PII", 3.14159265); echo PII; ?> //Tulostaa "3.14159265"
Ennalta määritellyt muuttujat sekä vakiot
Apache ja PHP varaavat ennalta tiettyjä muuttujia jotka sisältävät tietoja järjestelmästä ja sen hetkisestä tilanteesta. Näiden muuttujien arvoja käyttäjä ei voi muuttaa mutta voi kutsua niitä normaalisti. Web-sovelluksia tehdessä tärkeimmät muuttujat ovat taulukkomuotoiset $_GET ja $_POST muuttujat jotka sisältävät käyttäjän välittämiä GET ja POST methodin arvoja. Niistä tarkempaa tietoa löydät luvusta 1.9 (tavat tuoda ulkopuolista tietoa selaimesta). Täydellisen listan ennalta määritellyistä muuttujista löydät PHP:n sivuilta: PHP: Predefined Variables.
Palvelimen ennalta määritellyt muuttujat ($_SERVER)
Taulukkomuotoinen muuttuja $_SERVER sisältää palvelinohjelmiston antamia tietoja esimerkiksi ajettavasta tiedostosta sekä kävijästä joka sivua on hakenut. Huomaa kuitenkin että kaikki palvelinohjelmistot eivät välttämättä anna näitä tietoja. $_SERVER on superglobaali muuttuja, eli sitä ei tarvitse ajaa global käskyn lävitse että se olisi käytettävissä funktioissa ja olioissa. Huomaa että samat tiedot sisältävä $HTTP_SERVER_VARS on kuitenkin eri muuttuja, ja että se ei ole superglobaali kuten $_SERVER. Alla muutama yleisesti käytetty palvelimen ennalta määritelty muuttuja (muuttujan $_SERVER alkio, käyttö siis esimerkiksi <?php echo $_SERVER['PHP_SELF']; ?>):
- PHP_SELF - Sisältää ajettavan tiedoston polun (myös tiedostonimen) suhteutettuna palvelimen juurihakemistoon. Eli esimerkiksi osoitteessa http://www.esimerkki.com/foo/bar.php muuttuja $_SERVER['PHP_SELF'] sisältäisi "/foo/bar.php".
- HTTP_USER_AGENT - Mikäli käyttäjä lähettää tiedon selaimestaan palvelimelle se löytyy tästä muuttujasta.
- REMOTE_ADDR - IP-osoite jolla sivu haettiin. Huomaa että tämä ei välttämättä ole itse kävijän oma IP-osoite, sillä hän on voinut käyttää välityspalvelinta jolloin osoite on välityspalvelimen osoite.
- REMOTE_HOST - Kävijän host-nimi
- REMOTE_PORT - Portti jolla sivua haettiin
- PHP_AUTH_USER - Mikäli käytetään serverin HTTP-kirjautumista tämä muuttuja sisältää käyttäjänimen. Saman tiedon sisältää myös REMOTE_USER.
- PHP_AUTH_PASSWD - Mikäli käytetään serverin HTTP-kirjautumista tämä muuttuja sisältää salasanan.
Ennalta määritellyt vakiot
On myös olemassa ennalta määriteltyjä vakioita. Täydellisen listan löydät seuraavista linkeistä:
Alla muutama mainittavan arvoinen ennalta määritelty vakio:
-
__FILE__- Sisältää kyseisen skriptin tiedostonimi -
__LINE__- Sisältää sen hetkisen rivin numeron -
PHP_VERSION- Sisältää PHP versionumeron
Operaattorit
Operaattoreita käytetään esimerkiksi vertaillessa eri muuttujien sisältöjä tai vaikkapa suoritettaessa normaaleja laskutoimituksia.
Aritmeettiset operaattorit (laskutoimitukset)
| Operaattori | Toiminto | Esimerkki |
| + | Yhteenlasku | $x = 5 + 5; |
| - | Vähennyslasku | $x = 10 - 5; |
| * | Kertolasku | $x = 2 * 3; |
| / | Jakolasku | $x = 16 / 4; |
| % | Jakojäännös | $x = 15 % 4; |
Sijoitusoperaattorit
Yksinkertaisin ja itseasiassa ainoa puhdas sijoitusoperaattori on = merkintä. Sillä sijoitetaan vasemmalla alevaan muuttujaan sijoitusoperaattorin oikealla puolella oleva arvo. Sijoitusoperaattoreita voi olla useita yhdessä lauseessa.
<?php $x = 5; //Sijoittaa muuttujaan $x arvon 5 $x = $y = $z = 5; //Sijoittaa muuttujiin $x, $y sekä $z arvon 5 ?>
Tämän lisäksi on olemassa käteviä lyhennettyjä merkintöjä (tuttuja mm. Javasta):
| Operaattori | Toiminto | Esimerkki |
| += | Lisää ja sijoita | $x += 5; //Sama kuin $x = $x + 5; |
| -= | Vähennä ja sijoita | $x -= 5; //Sama kuin $x = $x - 5; |
| *= | Kerro ja sijoita | $x *= 5; //Sama kuin $x = $x * 5; |
| /= | Jaa ja sijoita | $x /= 5; //Sama kuin $x = $x / 5; |
| %= | Jakojäännös ja sijoita | $x %= 5; //Sama kuin $x = $x % 5; |
| ++ | Lisää yksi | $x++; //Sama kuin $x + 1; |
| -- | Vähennä yksi | $x--; //Sama kuin $x - 1; |
Vertailuoperaattorit
Vertailuoperaatioissa nimensä mukaisesti arvoja verrataan keskenään ja palautetaan sen perusteella joko tosi (TRUE) tai epätosi (FALSE).
| Operaattori | Toiminto | Esimerkki |
| == | on yhtä suuri kuin | ("15mk" == 15) TOSI |
| === | on yhtä suuri ja tyyppi on sama | ("15mk" === 15) EPÄTOSI |
| > | on suurempi kuin | ("15 tuhatta" > 10) TOSI |
| < | on pienempi kuin | ("15 tuhatta" < 20) TOSI |
| >= | on suurempi tai yhtä suuri kuin | ("15 tuhatta" >= 15) TOSI |
| <> tai != | on erisuuri kuin | ("15 tuhatta" <> 15) EPÄTOSI (koska "15 tuhatta" muutettuna kokonaisluvuksi on yhtäkuin 15, katso seuraava esimerkki) |
| !== | on erisuuri tai eri tyyppiä kuin | ("15 tuhatta" !== 15) TOSI |
| ? : | vertaileva sijoitusoperaattori (ternary) | $muuttuja = $luku > 1 ? "Luku on suurempi yksi" : "Luku on yksi tai pienempi"; |
Kuten huomaat automaattiset tyyppimuunnokset voivat tuottaa yllättäviä tilanteita. Onkin suositeltavaa käyttää esimerkiksi merkkijonojen vertailuissa strcmp()-funktiota, tai === merkintää. Aiheesta on myös esimerkki luvussa Totuusarvo (boolean).
Loogiset operaattorit
Loogisilla operaattoreilla voidaan esimerkiksi yhdistää tiettyjä ehtoja tyyliin JOS $nimi = "matti" JA $ikä = 15 TEE. Operaatioille on yleensä kaksi merkintätapaa, on ihan tottumuskysymys kumpia käyttää. Kummatkin on hyvä osata.
| Operaattori | Toiminto | Esimerkki |
| AND tai && | sekä | ($nimi == "matti" AND $ikä == 15), mikäli molemmat ovat tosia |
| OR tai || | tai | ($nimi == "matti" OR $ikä == 15), mikäli toinen tai kummatkin ovat tosia |
| XOR | tai (poissulkeva) | ($nimi == "matti" XOR $ikä == 15), mikäli toinen on tosi, mutta eivät kumpikin |
| ! | negaatio | (!$nimi), tosi kun $nimi on epätosi |
Kontrollirakenteet
Kontrollirakenteet ovat tuttuja kaikista ohjelmointikielistä. Niillä voidaan esimerkiksi hyvin vähällä vaivalla tulostaa kaikki luvut 1 ja 100000000 väliltä.
If..Elseif...Else - Valintarakenne
Nimensä mukaisesti voidaan toteuttaa käskyjä jos jokin ehto täyttyy, tai vaihtoehtoisesti toteuttaa mikäli ehto ei täyty. Monivalinnat onnistuvat elseif-rakenteella.
<?php $luku = 5; if ($luku == 5) echo "Luku on 5"; else echo "Luku ei ole 5"; ?> //Tulostaa "Luku on 5"
<?php $kengannumero = 43; if ($kengannumero < 30) echo "Jalkasi on todella pieni!"; elseif ($kengannumero < 36) echo "Jalkasi on pieni"; elseif ($kengannumero < 40) echo "Jalkasi on normaalikokoa"; elseif ($kengannumero < 45) echo "Jalkasi on suuri"; else echo "Jalkasi on jättiläismäinen!"; ?> //Tulostaa "Jalkasi on suuri"
Heti kun ehto täyttyy if...elseif rakenteessa hypätään muiden vaihtoehtojen ylitse. Näin käyttäjälle asti tulostuu vaihtoehdoista vain yksi.
Ehtoja voi yhdessä lausekkeessa olla rajaamaton määrä. Ehtojen yhdistäminen onnistuu loogisilla operaattoreilla.
<?php $ika = 65; //Ikä $sukupuoli = "mies"; if ($ika > 60 AND $sukupuoli == "mies") { echo "Henkilö on yli 60-vuotias mies."; } else { echo "Henkilö on joko nainen, tai ei ole vielä yli 60-vuotias."; } ?> //Tulostaa "Henkilö on yli 60-vuotias mies."
Switch - Valintarakenne
Switchillä sekä if...elseif rakenteella voidaan toteuttaa täsmälleen samoja valintarakenteita. Switch rakenne eroaa kuitenkin merkittävästi if rakenteesta. Switch rakenteen suorituksen aluksi suoritetaan sille annettu lauseke jonka arvon perusteella valitaan sen täyttävä valinta. Jos sellaista ei löydy käytetään tapausta Default.
<?php $i = 5; switch($i) { case 5: echo "Luku on 5"; break; default: echo "Luku ei ole 5"; } ?> //Tulostaa "Luku on 5"
Huomaathan ettei valinnoissa (case) käytetä aaltosulkeita vaan tuplapistettä. Huomaa myös komento break. Se päättää yksittäisen valinnan, jos sitä ei määritellä niin ehdon täyttyessä suoritetaan valintoja niin kauan kunnes rakenne loppuu tai break havaitaan. Valinnoissa voidaan käyttää myös merkkijonoja:
<?php $juoma = "Ohrapirtelö"; switch($juoma) { case "Ohrapirtelö": echo "Olut"; break; default: echo "Jotain muuta"; } ?> //Tulostaa "Olut"
Rakenteelle on myös olemassa valinnainen kirjoitusasu jolloin aaltosulkuja ei tarvita laisinkaan:
<?php $i = 1; switch($i): case 0: echo "\$i on nolla"; break; case 1: echo "\$i on yksi"; break; default: echo "\$i ei ole nolla eikä yksi"; endswitch; ?> //Tulostaa "$i on yksi"
While - Toistorakenne
Whilellä suoritusta jatketaan kunnes sille annettu ehto muuttuu epätodeksi. Ehtolause ajetaan ennen jokaista kierrosta, joten sille annettuja lauseita ei välttämättä suoriteta yhtään kertaa.
<?php $luku = 10; while ($luku-- > 0) echo $luku; ?> //Tulostaa luvut yhdeksästä nollaan
Do...While - Toistorakenne
Do...While rakenne eroaa While rakenteessa siinä että ehtolause suoritetaan vasta itse lauseiden ajon jälkeen. Täten lauseet suoritetaan aina vähintään yhden kerran vaikka ehto ei täyttyisi ollenkaan.
<?php $luku = 10; do echo $luku; while ($luku-- > 0); ?> //Tulostaa luvut kymmenestä nollaan
For - Toistorakenne
For rakenteeseen annetaan kolme lausetta. Ensimmäinen suoritetaan vain ensimmäisellä ajokerralla, toinen lause suoritetaan joka kierroksen alussa ja kolmas lause suoritetaan jokaisen kierroksen lopuksi. Suoritusta jatketaan niin kauan kuin toinen lause on tosi. Jokainen lause voi myöskin olla tyhjä, jolloin toinen lause tulkitaan todeksi. Eli silmukkaa suoritetaan kunnes siitä poistutaan manuaalisesti esimerkiksi break; komennolla.
<?php for ($i = 0; $i < 5; $i++) echo $i; ?> //Tulostaa luvut nollasta neljään
Foreach - Taulukon läpikäyntirakenne
Koska taulukot voivat sisältää myös ei numeerisia arvoja on PHP:ssä taulukon läpikäymiseen oma rakenne, foreach. Se käy kaikki taulukon alkiot läpi ja palauttaa sen arvon (value) ja myös avaimen (key) käyttäjän niin halutessa.
<?php $taulukko = array("eka", "toka", "kolmas", "neljäs" => "neljäs"); //Tulostaa kaikki arvot foreach ($taulukko as $arvo) echo "$arvo<br />\n"; //Tulostaa kaikki arvot sekä avaimet foreach ($taulukko as $avain => $arvo) echo "$avain: $arvo<br />\n"; ?>
Foreachin sisällä operoidaan alkion kopiolla, josta seuraa muutama huomioitava seikka: 1) tehdyt muutokset eivät välity taulukkoon asti, vaan vaikuttavat vain foreachin sisällä olevaan alkioon, ja 2) jos alkiot ovat suurikokoisia, taulukon läpikäynti vaatii merkittävästi enemmän muistia kuin for-silmukka, koska alkiothan ovat foreachia käyttäessä muistissa kahteen kertaan.
Funktiot
PHP:n sisäänrakennetut funktiot
PHP sisältää poikkeuksellisen suuren oletus-funktiokirjaston, PHP4 sisältää yli tuhat valmista funktiota käyttettäväksi ja lisää tulee uusiin versioihin jatkuvasti. Käytettävissä olevat funktiot voi hakea get_defined_functions()-funktiolla.
Itse määriteltävät funktiot
Määrittely ja kutsuminen
Funktio määritellään syntaksilla function funktion_nimi($parametri1, $parametri2). Funktiota kutsutaan yksinkertaisesti kirjoittamalla funktion nimi ja määrittelemällä sen vaatimat argumentit.
<?php function ensimmäinen_funktioni($nimi) { return "Tämä on käyttäjän $nimi ensimmäinen funktio"; } echo ensimmäinen_funktioni("JTS"); ?> //Tulostaa "Tämä on käyttäjän JTS ensimmäinen funktio"
Eli koodi määrittelee funktion joka palauttaa merkkijonon "Tämä..." jonka sitten echo tulostaa. Tulostus voidaan tehdä myös funktion sisältä:
<?php function ensimmäinen_funktioni($nimi) { echo "Tämä on käyttäjän $nimi ensimmäinen funktio"; } ensimmäinen_funktioni("JTS"); ?> //Tulostaa "Tämä on käyttäjän JTS ensimmäinen funktio"
Lisäksi parametreille voi antaa oletusarvoja jolloin niitä ei välttämättä tarvitse syöttää, tällöin käytetään annettua oletusarvoa.
<?php function ensimmäinen_funktioni($nimi = "JTS") { echo "Tämä on käyttäjän $nimi ensimmäinen funktio"; } ensimmäinen_funktioni(); ?> //Tulostaa "Tämä on käyttäjän JTS ensimmäinen funktio"
Muuttujien tuominen funktion ulkopuolelta
Funktioilla on oma muuttuja-avaruus ellei toisin määrätä. Eli funktion sisällä määritellyt muuttujat eivät toimi funktion ulkopuolella. Samoin funktion ulkopuolella määritellyt muuttujat eivät toimi oletuksena funktioiden sisällä. Tämä voidaan kuitenkin toteuttaa tekemällä muuttujista globaaleja.
<?php $nimi = "JTS"; function ensimmäinen_funktioni() { echo "Tämä on käyttäjän $nimi ensimmäinen funktio"; } ensimmäinen_funktioni(); ?> //Ei toimi oikein koska muuttuja $nimi ei ole globaali, tulostaa "Tämä on käyttäjän ensimmäinen funktio"
<?php $nimi = "JTS"; function ensimmäinen_funktioni() { global $nimi; echo "Tämä on käyttäjän $nimi ensimmäinen funktio"; } ensimmäinen_funktioni(); ?> //Toimii, tulostaa "Tämä on käyttäjän JTS ensimmäinen funktio"
Globaaleja voi määritellä useita yhdellä global-kutsulla käyttämällä pilkkua erottimena.
Staattiset eli pysyvät muuttujat
Funktion sisällä tehdyt muuttujien luomiset ja muutokset eivät oletuksena vaikuta funktioiden ulkopuolelle, sillä oletuksena sen muuttujat tuhotaan funktion käytön loputtua. Jos muuttuja on jo valmiiksi funktion ulkopuolella, ja se tuodaan sieltä funktion näkyvyyteen global-avainsanalla, silloin muutokset luonnollisesti jäävät voimaan. Mikäli halutaan, että funktion sisällä määritelty muuttuja jää muistiin, voidaan käyttää pysyviä eli staattisia muuttujia. Muuttuja määritellään staattiseksi käskyllä static. Huomioi kuitenkin ettei staattinen muuttuja siltikään toimi kuin kyseisen funktion sisällä.
<?php function kasvata_lukua() { $luku = 0; $luku++; echo $luku; } kasvata_lukua(); //Tulostaa 1 kasvata_lukua(); //Tulostaa 1 ?> // tässä tapauksessa luku ei kasva: // muuttujaan $luku tehdyt muutokset eivät säily funktion suorituksen loputtua
<?php $luku = 0; function kasvata_lukua() { global $luku; $luku++; echo $luku; } kasvata_lukua(); //Tulostaa 1 kasvata_lukua(); //Tulostaa 2 // jos muuttuja on globaalissa avaruudessa, muutokset siihen säilyvät. ?>
<?php function kasvata_lukua() { static $luku = 0; $luku++; echo $luku; } kasvata_lukua(); //Tulostaa 1 kasvata_lukua(); //Tulostaa 2 ?> //Eli nyt muuttuja $luku pidetään muistissa myös funktion suorituksen loputtua.
Muuttujaan viittaaminen funktioissa
Viittausta voidaan käyttää myös funktioissa. Sillä tavalla voidaan käyttää funktiota käsittelemään sen oman muistiavaruutensa ulkopuolista muuttujaa.
<?php $foo = 0; function bar(&$foo){ $foo++; } bar($foo); //Kasvattaa muuttujan $foo arvoa yhdellä bar($foo); //Kasvattaa muuttujan $foo arvoa yhdellä echo $foo; //Tulostaa "2" ?>
Viittaus voidaan tehdä myös funktiota kutsuttaessa määrittelyn sijaan:
<?php $foo = 0; function bar($foo){ $foo++; } bar(&$foo); //Kasvattaa muuttujan $foo arvoa yhdellä bar(&$foo); //Kasvattaa muuttujan $foo arvoa yhdellä echo $foo; //Tulostaa "2" ?>
Myös itse funktiohin viittauksista pitäisi kirjoittaa...
Oliot ja luokat
Olio on luokan ilmentymä. Luokka puolestaan on kokoelma hyvin pitkälti funktion tapaisia toimintoja, eli metodeja, sekä muuttujia, joita luokkien yhteydessä nimitetään attribuuteiksi. Yhdestä luokasta voi luoda mielivaltaisen määrän olioita. Jokaisella oliolla attribuuttien arvot voivat vaihdella, mutta attribuuttien nimet ja metodit ovat kaikilla saman luokan olioilla yhtenäisiä. Näin luokka on kuin kaava, jonka avulla luodaan olioita.
<?php class LuokanNimi { var $malli_attribuutti = "alustusarvo"; var $_nimi; /** * Luokan niminen metodi, eli muodostin tai konstruktori, * jota kutsutaan, kun uusi olio luodaan. * PHP5:ssa muodostinfunktissa luokan nimen tilalle tulee __construct */ function LuokanNimi( $nimi ) { $this->_nimi = $nimi; } /** * Tavallinen metodi, jonka nimi on kerroNimi. */ function kerroNimi() { return "Nimeni on " . $this->_nimi . "."; } } $olio1 = new LuokanNimi( "Testiolio" ); $olio1->malli_attribuutti = "arvo"; $olio2 = new LuokanNimi( "Toinen olio" ); print $olio1->kerroNimi() . " Malliattribuutin arvo: " . $olio1->malli_attribuutti . "<br />"; print $olio2->kerroNimi() . " Malliattribuutin arvo: " . $olio2->malli_attribuutti; /* Tulostaa: * Nimeni on Testiolio. Malliattribuutin arvo: arvo * Nimeni on Toinen olio. Malliattribuutin arvo: alustusarvo */ ?>
Kuten esimerkistä huomasimme, käytetään olion luomiseen luokasta sanaa new luokan nimen edessä. Luokan nimen jälkeen voi seurata suluissa muodostimelle välitettävät parametrit. Luokan nimen tilalla voi tarvittaessa käyttää myös muuttujaa. Olion attribuutteihin ja metodeihin päästään käsiksi käyttäen operaattoria -> oliomuuttujan ja metodin tai attribuutin nimen välissä. Attibuutin arvona voi olla mitä tahansa, tai sille ei tarvitse välttämättä asettaa arvoa. Määritettäessä attribuuttia, tulee sitä edeltää varattu sana var tai staattisuusilmaisin (static).
Koska PHP:ssä tietotyypillä ei ole yhtä suurta merkitystä kuin monissa muissa oliopohjaisissa ohjelmointikielissä, ovat kaikki oliotkin tietotyypiltään object-tyyppisiä. Luokan nimi voidaan kuitenkin selvittää kutsumalla get_class-funktiota. PHP5:ssä on myös mahdollista testata instanceof-operaattorilla, onko olio luotu tietystä luokasta tai periikö se sen. Myös $olio instanceof RajapinnanNimi on true, jos $olio käyttää rajapintanaan RajapinnanNimi-rajapintaa
<?php // jatkuu edellisestä koodista... if( $olio1 instanceof LuokanNimi ) { print "Olio1 on luotu luokasta LuokanNimi"; } else { print "Olio1:n luokka on " . get_class( $olio1 ); } // Tulostaa: Olio1 on luotu luokasta LuokanNimi. ?>
Olio-ominaisuudet PHP5:ssä ovat edistykselliset edellisiin PHP:n versioihin verrattuna. PHP:n 5. version mukana käyttöön tulivat muun muassa näkyvyysastemääritykset, abstraktit luokat, rajapinnat, staattiset metodit ja attribuutit, virheidenkäsittely, final-määrite, destruktori ja olion tyypin vihjaaminen parametrilistassa. Koska PHP5 on yleistymässä vauhdilla, käsittelee tämä opas olio-ohjelmointiominaisuuksia juuri PHP5:n näkökulmasta.
Perintä
Luokka voi periä toisen luokan, niin sanotun isäntäluokan, jolloin se saa käyttöönsä tämän kaikki julkiset metodit ja attribuutit. Periminen ilmaistaan varatulla sanalla extends luokan nimen jälkeen ja tämän jälkeen ilmoitetaan luokka, joka peritään. Luokka voi kuitenkin ylikirjoittaa haluamansa metodit omillaan, jolloin niitä kutsutaan $this-olion kautta aina. Isäntäluokan versiota ylikirjoitetusta metodista voi kutsua parent-osoittimella: parent::metodinNimi().
<?php class A { function laske( $x ) { return pow( $x, 3 ) - 2*$x; } function tervehdi() { print "Hei, olen A!\n"; } } // Luokka B perii luokan A: class B extends A { function tervehdi() { parent::tervehdi(); print "Hei, olen B!\n"; } } $b = new B; $b->tervehdi(); print $b->laske( 2 ) . "\n"; if( $b instanceof A ) print "B on A:n instanssi."; /* Tulostaa: * Hei, olen A! * Hei, olen B! * 4 * B on A:n instanssi. */ ?>
Näkyvyysasteet
Luokan attribuutti tai metodi voi näkyä joko julkisesti (public) olion käyttäjälle, yksityisesti (private) vain oliolle itselleen, tai suojattuna (protected) itse oliolle sekä siitä periytyville olioille. Yksityiset attribuutit ja metodit merkitään yleisesti asettamalla nimien eteen alaviiva.
Näkyvyysasteiden avulla voidaan erotella toisistaan luokan sisäiset toiminnot ja sen käyttöliittymä. Luokkaa käyttävän ei tarvitse tietää sen sisäisestä toiminnasta mitään, riittää vain kontrollien hallitseminen. Tilannetta voidaan verrata autoon, josta ajajan ei tarvitse tuntea kuin ohjauslaitteisto, ei moottorin ja muiden osien teknistä toteutusta. Käytön helppouden ja virheettömyyden takaamiseksi metodit ja attribuutit on hyvä varustaa aina vain välttämättömimmällä näkyvyysasteella. Mielessä kannattaa aina pitää, että jos määrettä ei anna, on metodi tai attribuutti aina julkinen. Asia on näin ainakin siitä syystä, että saavutettaisiin yhteensopivuus PHP4:n kanssa, jossa näkyvyysmääreitä ei ollut käytössä.
Hyvänä tapana oliopohjaisessa ohjelmoinnissa voidaan pitää, että kaikki ei-vakioiset attribuutit pidetään yksityisinä ja arvon asetus ja lukeminen tapahtuu erikseen mahdollisesti määriteltyjen settereiden (setAttribuutinNimi) ja gettereiden (getAttribuutinNimi) avulla. PHP5:ssa on kuitenkin tähän tarkoitukseen erikseen erikoismerkityksen omaavat __set( $attribuutin_nimi, $arvo ) ja __get( $attribuutin_nimi ) -metodit, jotka voidaan luokalle haluttaessa määrittää. Niiden avulla on mahdollista rajoittaa melko helposti olion attribuuttien luku- ja kirjoitusoikeuksia.
<?php class Kulkuneuvo { protected $_kayttoKohde; function getKayttokohde() { return $this->_kayttoKohde; } } class Auto extends Kulkuneuvo { private $_merkki; private $_malli; public $kuski; public function __construct( $merkki, $malli ) { $this->_kayttoKohde = "maantie"; $this->_merkki = $merkki; $this->_malli = $malli; } public function getMerkki() { return $this->_merkki; } public function getMalli() { return $this->_malli; } } $auto = new Auto( "Ford" , "Focus" ); // Nyt voimme kutsua: print $auto->getMerkki() . "\n"; // Tulostaa: Ford print $auto->getMalli() . "\n"; // Tulostaa: Focus print $auto->getKayttoKohde() . "\n"; // Tulostaa: maantie // Samoin voimme suoraan vaihtaa kuskia: $auto->kuski = "Maija"; // Mutta mikään seuraavista ei ole sallittua: /* print $auto->_merkki . "\n"; * $auto->_malli = "Mondeo"; * $auto->_kayttoKohde = "vesistö"; */ ?>
Pieni esimerkki PHP:n __set ja __get -metodien ylikirjoittamisesta. Niiden hyöty on siinä, että käyttöliittymä voidaan edelleen pitää selkeänä, mutta vaiva on pieni, kun syötteille halutaan esimerkiksi tehdä jokin operaatio ennen niiden vastaanottamista tai lukemista, tai ne halutaan vaikkapa sijoittaa johonkin normaalista poikkeavaan paikkaan.
<?php class Luokka { private $_taulu = array(); public function __set( $attribuutti, $arvo ) { // tallennetaan arvo pienin kirjaimin $this->_taulu[ $attribuutti ] = strToLower( $arvo ); } public function __get( $attribuutti ) { return $this->_taulu[ $attribuutti ]; } } $olio = new Luokka(); $olio->nimi = "Matti Meikäläinen"; $olio->koti = "Mureakuha"; print $olio->nimi . "\n"; // Tulostaa: matti meikäläinen print $olio->koti; // Tulostaa: mureakuha ?>
Staattiset metodit ja attribuutit
Staattisuus metodeilla ja attribuuteilla mahdollistaa niiden käytön ilman olion tekemistä luokasta. Staattiset metodit eivät voi käyttää olion attribuutteja tai metodeja, jotka eivät ole staattisia. Staattisten attribuuttien arvo on kaikissa olioissa sama. Staattisiin metodeihin ja attribuutteihin tulee viitata luokan, ei olion kautta, ja käyttää viittauksessa :: operaattoria -> operaattorin sijasta. PHP5 esittelee uutuutena metodeille myös avainsanan final. Metodeja, jotka on määritelty finaleiksi, ei voi muuttaa tai ylikirjoittaa.
<?php class MuutosLaskuri { static $_laskuri = 0; public static final function kasvata() { return ++self::$_laskuri; } } print MuutosLaskuri::kasvata() . "\n"; // Tulostaa: 1 print MuutosLaskuri::kasvata() . "\n"; // Tulostaa: 2 ?>
Abstraktit luokat
Abstraktista luokasta ei voida sellaisenaan luoda oliota. Abstraktissa luokassa määritellään ne attribuutit ja metodit, jotka sen perivällä luokalla on ja lisäksi voidaan määritellä abstrakteja metodeja, joille ei anneta sisältöä vielä abstraktissa luokassa, mutta sen perivässä luokassa kyseinen metodi tulee olla. Abstrakti luokka määritellään varatulla sanalla abstract samoin kuin siinä olevat abstraktit metoditkin.
Esimerkki tietokannan alkiosta, jossa pitää olla tietojen tuomista tietokannasta ja sinne viemistä varten funktiot tuoArvot ja vieArvot. Muutoin itse Alkio-luokan perivä luokka voi olla minkälainen tahansa. Myös Alkio-luokassa voisi olla kaikille alkioille yhteisiä toimintoja määriteltynä. Jos halutaan, että tällaista toimintoa ei voida ylikirjoittaa Alkio-luokan perivässä luokassa, voidaan käyttää varattua sanaa final, joka ilmaisee, ettei metodi ole muutettavissa perivässä luokassa.
<?php abstract class Alkio { // Alkion perivässä luokassa tulee siis olla metodit // tuoArvot ja vieArvot. public abstract function setArvot( $arvot ); public abstract function getArvot(); // Kriittinen toiminto, joka ei saa olla // ylikirjoitettavissa Alkio:n perivässä luokassa: protected final function _muutosTapahtunut() { // Viestitetään kuvitteelliselle tietokannalle, // että tämä alkio on muuttunut ja se täytyy tallentaa Tietokanta::alkioMuuttunut( $this ); } } class Kappale extends Alkio { private $_esittaja; private $_nimi; public function setArvot( $arvot ) { $this->_esittaja = $arvot['esittäjä']; $this->_nimi = $arvot['kappalenimi']; } public function getArvot() { return array( "esittäjä" => $this->_esittaja, "kappalenimi" => $this->_nimi ); } public function getEsittaja() { return $this->_esittaja; } public function getNimi() { return $this->_nimi; } public function setEsittaja( $esittaja ) { $this->_esittaja = $esittaja; $this->_muutosTapahtunut(); } public function setNimi( $nimi ) { $this->_nimi = $nimi; $this->_muutosTapahtunut(); } } ?>
Rajapinnat
Koska PHP:ssä luokka voi periä vain yhden luokan, mutta tosimaailman tarpeisiin kuuluu kuitenkin, että yksi asia voi kuulua useampaan eri joukkoon, on mahdollista käyttää rajapintoja. Rajapinta voi sisältää vain julkisia metodeja, joita ei ole määritelty. Täten rajapintaa käyttävän luokan tulee määrittää kaikki nämä metodit. Rajapinta tarjoaa siis käyttäjälle varman tiedon siitä, mitä metodeja luokan käyttöliittymä ainakin tarjoaa, ja samaa rajapintaa käyttävät eri luokistakin luodut oliot voidaan näin käsitellä vaivattomammin samoilla toimenpiteillä.
Rajapinta esitellään pitkälti samaan tapaan kuin luokkakin, sanan class tilalla käytetään vain sanaa interface. Sanalla implements puolestaan ilmaistaan luokan esittelyssä mahdollisen extends-määritteen jälkeen luokan käyttävän määrättyjä pilkulla erotettuja (mikäli useampia) rajapintoja. Tässäpä hiukan laajempi abstraktimpi esimerkki:
<?php interface Geometria_2D_Rajapinta { public function laskePintaAla(); } interface Geometria_3D_Rajapinta { public function laskeTilavuus(); public function laskePintaAla(); } interface Piirtaja_Rajapinta { public function piirra( PiirtoPinta $pinta ); } class Kuvio { protected $_xSijainti; protected $_ySijainti; protected $_zSijainti; protected $_vari; public function __construct( $vari, $x, $y, $z = false ) { $this->_vari = $vari; $this->_xSijainti = $x; $this->_ySijainti = $y; $this->_zSijainti = $z; } public function getVari() { return $this->_vari; } public function getSijainti() { $koordinaatit = array( $this->_xSijainti, $this->_ySijainti ); if( !( $this->_zSijainti === false ) ) { $koordinaatit[] = $this->_zSijainti; } return $koordinaatit; } public function piirra ( PiirtoPinta $pinta) { // oletusmetodi piirtämiselle } } // Nelio on Kuvio, joka käyttää rajapintoja Geometria_Rajapinta ja Piirtaja_Rajapinta class Nelio extends Kuvio implements Geometria_2D_Rajapinta, Piirtaja_Rajapinta { private $_sarmanPituus; public function __construct( $vari, $x, $y, $sarma ) { // Kutsutaan Kuvion muodostinta parent::__construct( $vari, $x, $y ); $this->_sarmanPituus = $sarma; } public function getSarmanPituus() { return $this->_sarmanPituus; } public function laskePintaAla() { return pow( $this->_sarmanPituus, 2 ); } public function piirra( PiirtoPinta $pinta ) { // Neliön piirtäminen } } // Pallo on yhtä aikaa pohjimmiltaan Kuvio, mutta se käyttää // myös rajapintoja Geometria_3D_Rajapinta ja Piirtaja_Rajapinta. class Pallo extends Kuvio implements Geometria_3D_Rajapinta, Piirtaja_Rajapinta { private $_sade; public function __construct( $vari, $x, $y, $z, $sade ) { // Kutsutaan Kuvion muodostinta parent::__construct( $vari, $x, $y, $z ); $this->_sade = $sade; } public function getSarmanPituus() { return $this->_sarmanPituus; } public function laskePintaAla() { return 4 * M_PI * pow( $this->_sade, 2 ); } public function laskeTilavuus() { return 4/3 * M_PI * pow( $this->_sade, 3 ); } public function piirra( PiirtoPinta $pinta ) { // Pallon piirtäminen } } // Oletetaan, että käytössä on kuvitteellinen PiirtoPinta-luokka: $piirtoPinta = PiirtoPinta::getInstance(); $kuviot = array(); $kuviot[] = new Nelio( "punainen", 10, 20, 5 ); $kuviot[] = new Pallo( "sininen", 20, 30, 10, 8 ); $kuviot[] = new Pallo( "keltainen", 50, 20, 5, 10 ); foreach( $kuviot as $kuvio ) { // tutkitaan, voidaanko kuvio piirtää, ts. toteuttaako se rajapinnan Piirtaja_Rajapinta if ($kuvio instanceof Piirtaja_Rajapinta) { $kuvio->piirra( $piirtoPinta ); } if( $kuvio instanceof Geometria_2D_Rajapinta ) { // Voidaan tutkia, käyttääkö $kuvio määriteltyjä rajapintoja, ja jos // käyttää, kutsutaan rajapinnoissa määriteltyjä funktioita $piirtoPinta->tulostaMerkkijono( "Pinta-ala: " . $kuvio->laskePintaAla() ); } if( $kuvio instanceof Geometria_3D_Rajapinta ) { $piirtoPinta->tulostaMerkkijono( "Tilavuus: " . $kuvio->laskeTilavuus() ); } } // Olkoon tässä nyt vaikka pieni kuvitteellinen PiirtoPinta, ettei // sen puute suotta synnytä erroreita: class PiirtoPinta { public static function getInstance() { return new PiirtoPinta(); } public function tulostaMerkkijono( $mj ) { print $mj . "\n"; } } ?>
Olioiden järjestäminen
Oliot voidaan lajitella tietyn ominaisuutensa mukaan käyttämällä PHP:n usort-funktiota. Sille voidaan antaa lajiteltavaksi oliotaulukko ja määrittää esimerkiksi tietty metodi kyseisten olioiden luokasta hoitamaan lajittelu halutun ominaisuuden mukaan. Katso seuraava esimerkki:
<?php class Tohveli { private static $_lajitteluPeruste; private $_ominaisuudet; // sisältää attribuutit, joiden mukaan tohvelit voidaan järjestellä public function __construct($koko, $materiaali) { $this->_ominaisuudet = array(); $this->_ominaisuudet['koko'] = $koko; $this->_ominaisuudet['materiaali'] = $materiaali; } public static function asetaLajitteluPeruste($tietue) { self::$_lajitteluPeruste = $tietue; } // Palauttaa attribuutit, joiden mukaan tohvelit voidaan järjestellä public function getAttribuutit() { return array_keys($this->_ominaisuudet); } public static function lajittele($a, $b) { $peruste = self::$_lajitteluPeruste; if( $a->$peruste > $b->$peruste ) { return 1; } return ($a->$peruste === $b->$peruste) ? 0 : -1; } private function __get($attr) { return $this->_ominaisuudet[$attr]; } } // Luodaan tohvelitaulukko $tohvelit = array(); $tohvelit[] = new Tohveli(42, "muovi"); $tohvelit[] = new Tohveli(41, "kumi"); $tohvelit[] = new Tohveli(43, "puuvilla"); $tohvelit[] = new Tohveli(40, "muovi"); // Järjestetään tohvelit koon mukaan Tohveli::asetaLajitteluPeruste("koko"); usort($tohvelit, array("Tohveli", "lajittele")); // Tulostetaan tohvelit print_r($tohvelit); ?>
Kirjoita vielä ainakin virheiden käsittelystä.
Tavat tuoda ulkopuolista tietoa selaimesta
PHP:n ollessa vahvasti internetohjelmointiin painotettu ohjelmointikieli on myös selvää että se sisältää tuen erilaisille internetissä käytetyille tiedonvälitystekniikoille. Tuki löytyy lomakkeiden GET- ja POST-tekniikoille, sekä kekseille ja istunnoille löytyy myös suora tuki ennalta varattujen muuttujien muodossa. Kaikki nämä muuttujat ovat superglobaaleja, eli niitä ei tarvitse esitellä global-funktiolla missään vaiheessa.
GET ($_GET)
Tämä tiedonvälitystapa on erittäin yleinen jo monien sivustojen sivurakenteen muodossa. GET-parametrejä voidaan syöttää vaikka käsin osoiterivin perään, esimerkiksi tämän muokkaussivun osoite on: http://wiki.mureakuha.com/index.php?title=PHP-opas&action=edit Ja se sisältää GET-parametrit title (jonka arvona on "PHP-opas") sekä action (jonka arvona on "edit").
Eli ensimmäinen GET-parametri syötetään ensin antamalla osoiterivin perään kysymysmerkki ("?") jonka jälkeen syötetään avain/arvo-pari erottamalla ne yhtäkuin-merkillä ("="). Seuraavat parametrit erotetaan toisistaan kysymysmerkin sijaan ja-merkillä ("&"). PHP:ssä löydät nämä syötetyt muuttujat omasta ennalta määritellystä muuttujasta synktaksilla $_GET['avain'] joka sisältää kyseistä avainta vastaavan arvon.
Tämän tiedonvälitystekniikan suurin etu on liene sen helppo käyttöönotto. Sinun ei tarvitse tehdä lomaketta, pelkkä oikein muotoiltu osoite/linkki riittää.
<?php if (isset($_GET['avain'])) { echo $_GET['avain']; } ?> //Tulostaa osoiterivillä annetun "avain"-muuttujan sisällön mikäli sellainen on asetettu.
POST ($_POST)
POST tiedonvälitystavalla on selkeästi eri rooli kuin GET:illä. Sillä voidaan kuljettaa suuriakin tietomääriä toisin kuin GET-tekniikalla jonka suositeltu maksimipituus tekstinä on 250 merkkiä. POST-tekniikalla voidaan myös kuljettaa tiedostoja, tosin ne on siirretty PHP:ssä oman muuttujansa alle ($_FILES). Selaimia käytettäessä POST on käyttäjälle näkymätön (eli se ei siis tee esimerkiksi osoiteriville mitään), mutta vastaavasti hän joutuu käytännössä aina täyttämään jonkin lomakkeen ja lähettämään tiedot.
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="POST"> Nimi: <input type="text" name="nimi" /><br /> <input type="submit" /> </form> <?php if (isset($_POST['nimi'])) echo "Nimesi on ".$_POST['nimi']; ?> //Tulostaa käyttäjän syöttämän nimen
Esimerkissä ensin teemme lomakkeen, joka laitetaan lähettämään tietonsa juuri samaan tiedostoon $_SERVER['PHP_SELF']-muuttujalla. Sen jälkeen teemme syöttökentän nimellä "nimi" sekä teemme lähetysnapin. Sen jälkeen vain tulostamme kyseisen nimi-muuttujan mikäli sellainen on annettu.
Tiedostojen lähettäminen ($_FILES)
POST-methodilla voidaan siirtää myös tiedostoja. Alla esimerkki lomakkeesta joka lähettää oikeaoppisesti tiedostoja:
<form action="vastaanota.php" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <!--Määritellään maksimikoko kilotavuina, helposti kierrettävissä mutta ihan käytettävyydenkin kannalta hyvä olla--> <input type="hidden" name="MAX_FILE_SIZE" value="1024" /> <input type="submit" /> </form>
Eli säädimme lähetettävän maksimikoon 1 megatavuun. Huomaa kuitenkin että joku voi hyvinkin lähettää lomakkeen ilman tätä piilotettua määrettä, joten koon tarkistus pitää tehdä myös tiedot vastaanottavaan PHP-skriptiin. Oletuksena PHP:n vastaanottavan tiedoston maksimikoko on säädetty 2 megatavuun php.ini tiedoston asetuksissa. Jos haluat siirtää isompia tulee sinun täytyy muuntaa tätä asetusta suoraan php.ini tiedostosta (tai säätää tätä asetusta .htaccessilla). Huomaa ettei asetuksenmuuttaminen itse PHP-tiedostossa ini_set()-funktiolla onnistu koska tällöin lähetetty tiedosto on jo käsitelty PHP:n toimesta ennenkuin uusi asetus astuu voimaan.
Tiedoston lähetyksen onnistuessa vastaanottavalle PHP-skriptille välittyy siirrettävästä tiedostosta seuraavat PHP:n määrittelemät muuttujat:
- $_FILES['file']['name'] - Tiedoston nimi (ilman mitään polkuja)
- $_FILES['file']['tmp_name'] - Tilapäistiedoston nimi polkuineen
- $_FILES['file']['size'] - Tiedoston koko tavuina
- $_FILES['file']['type'] - Sisältää tiedoston metatyypin mikäli selain sellaisen lähettää
- $_FILES['file']['error'] - Sisältää tietoa mahdollisesti tapahtuneista virheistä
Tiedot siis sijaitsevat taulukossa $_FILES['name'] jossa name on lomakkeen kentän nimi josta tiedosto lähetetään.
Huomaa että tiedosto tallennettaan nimenomaan PHP:n tilapäiskansioon, tiedoston tilapäisnimen polkuineen löydät $_FILES['file']['tmp_name']-muuttujasta. Käyttäjän tehtäväksi jää siirtää tämä tiedosto haluttuun paikkaan. Mutta ennen sitä on hyvä tehdä tarkistuksia ladatulle tiedostolle, muutenhan käyttäjä on voinut ladata palvelimellesi vaikka PHP-tiedoston joka antaisi tiedoston lataajalle käytännössä täydellisen hallinnan koko palvelimellesi.
Ensimmäinen esimerkki olkoon yksinkertaisin mahdollinen tapa vastaanottaa tiedosto (yhteensopiva aiemman lomake-esimerkin kanssa):
<?php if ($_FILES['file']['name']) { if (move_uploaded_file($_FILES['file']['tmp_name'], "./".$_FILES['file']['name'])) { echo "Tiedosto siirretty onnistuneesti."; } } ?>
Esimerkki siis vain siirtää lähetetyn tiedoston kansioon jossa skripti on. Tätä esimerkkiä ei kuitenkaan kannata käyttää juuri missään olosuhteissa sillä sitä voidaan käyttää erittäin helposti esimerkiksi vihamielisen koodin siirtämiseen.
Toisessa esimerkissä otetaan vastaan vain kuvia jotka täyttävät asetusten mukaiset vaatimukset:
<?php //Asetukset alkavat //Sallittuihin päätteisiin avaimeksi täältä saatu avain halutuille kuvatyypeille: // http://fi.php.net/manual/fi/function.getimagesize.php $asetukset['sallitut_päätteet'] = array(1 => "gif", 3 => "png", 2 => "jpg"); $asetukset['kuvan_maxleveys'] = 400; $asetukset['kuvan_maxkorkeus'] = 300; $asetukset['kuvan_maxkoko'] = 20; //Kilotavuina $asetukset['latauskansio'] = './uploads/'; //Asetukset päättyvät if (!empty($_FILES['file']['name'])) { //Tarkistukset alkavat //Kuvan päätteen tarkistus alkaa //Haetaan viimeisen pisteen jälkeen tulevat merkit, jotka siis määräävät kuvan päätteen $kuvan_pääte = substr(strtolower($_FILES['file']['name']), strrpos($_FILES['file']['name'], ".")+1); if (in_array($kuvan_pääte, $asetukset['sallitut_päätteet']) === false) { $virhe .= "Väärä pääte, sinun oli $kuvan_pääte kun sallitut päätteet ovat "; $virhe .= implode(", ", $asetukset['sallitut_päätteet']).".<br />\n"; } //Kuvan päätteen tarkistus päättyy //Kuvan koon tarkistus ja validointi alkaa //Getimagesize hakee kuvasta erinäisiä tietoja, kuten sen fyysisen koon. //Samoin se palauttaa virheen mikäli kuva ei ole kuva laisinkaan if ($kuvan_tiedot = getimagesize($_FILES['file']['tmp_name'])) { $kuvan_leveys = $kuvan_tiedot[0]; $kuvan_korkeus = $kuvan_tiedot[1]; $kuvan_tyyppi = $asetukset['sallitut_päätteet'][$kuvan_tiedot[2]]; $kuvan_koko = round(filesize($_FILES['file']['tmp_name']) / 1024, 1); //Leveyden tarkistus if ($kuvan_leveys > $asetukset['kuvan_maxleveys']) $virhe .= "Kuva on liian leveä, {$kuvan_leveys} px kun maksimileveys on {$asetukset['kuvan_maxleveys']} px.<br />\n"; //Korkeuden tarkistus if ($kuvan_korkeus > $asetukset['kuvan_maxkorkeus']) $virhe .= "Kuva on liian korkea, {$kuvan_leveys} px kun maksimikorkeus on {$asetukset['kuvan_maxkorkeus']} px.<br />\n"; //Koon tarkistus if ($kuvan_koko > $asetukset['kuvan_maxkoko']) $virhe .= "Kuva on liian suuri, $kuvan_koko Kt kun maksimikoko on {$asetukset['kuvan_maxkoko']} Kt.<br />\n"; //Tyypin tarkistus if (in_array($kuvan_tyyppi, $asetukset['sallitut_päätteet']) === false) $virhe .= "Kuvan tyyppi ei ole tuettu, sallitut päätteet ovat ".implode(", ", $asetukset['sallitut_päätteet']).".<br />\n"; //Tarkistetaan ettei kuvan nimi ole jo käytössä if (is_file($asetukset['latauskansio'].$_FILES['file']['name'])) $virhe .= "Tällä nimellä on jo tiedosto ladattuna, valitse eri nimi.<br />\n"; } else exit('Kuvaa ei tunnistettu kuvaksi.'); //Kuvan koon tarkistus ja validointi päättyy if ($virhe) exit($virhe); //Tarkistukset päättyvät //Kuvan siirtäminen haluttuun paikkaan alkaa if (move_uploaded_file($_FILES['file']['tmp_name'], $asetukset['latauskansio'].$_FILES['file']['name'])) echo "Tiedosto siirretty onnistuneesti. "; else { //Poistetaan väliaikaistiedosto unlink($_FILES['file']['tmp_name']); exit("Tiedoston siirtäminen lopulliseen kansioon epäonnistui."); } //Kuvan siirtäminen haluttuun paikkaan päättyy } ?>
Keksit ($_COOKIE)
Keksit (eng. cookie, tunnetaan Suomessa myös evästeinä) ovat yksi tapa tallentaa tietoa. Siinä tiedon säilyttää nimenomaan käyttäjän selain, joten ensinnäkään kekseillä ei kannata säilyttää yksin mitään kriittisiä tietoja kahdesta syystä: 1. tiedot voivat kadota koska hyvänsä 2. tiedot on helppo kaivaa esille käyttäjän koneesta. Eritoten jälkimmäinen asia tulisi ottaa huomioon arkaluontoisten tietojen osalta. On ikävää jos palvelusi käyttäjien salasanat voidaan kaivaa helposti paikallisen kirjaston selaimen kekseistä. Arkaluontoisten väliaikaisten tietojen tallentamiseen suosittelen käyttämään istuntoja sillä niitä käytettäessä itse tiedot ovat tallennettuina palvelimella eivätkä käyttäjän selaimessa.
Keksin asettaminen
Keksi asennetaan käyttäen setcookie-funktiota. Funktion tärkeimmät syötetään ovat keksin nimi, sen arvo sekä kestoaika. Kestoaika tulee syöttää Unix-aikaleimana, eli käyttännössä se kannattaa syöttää muodossa time()+10000 jossa 10000 on haluttu määrä sekunteja eteenpäin tästä hetkestä. Kestoaikaan liittyy eräs huomioitava "ominaisuus", sillä keksin kestoajan umpeutuminen riippuu lopulta käyttäjän järjestelmän kellosta. Eli mikäli käyttäjän järjestelmän kello on merkittävästi väärässä voivat keksit tuhoutua omia aikojaan. Kaikki parametrit paitsi nimi ovat valinnaisia (eli niitä ei välttämättä tarvitse syöttää laisinkaan).
<?php setcookie("Nimi", "JTS"); ?> //Asettaa keksille "Nimi" arvon "JTS"
Emme antaneet esimerkissä keksille kestoaikaa. Tällöin selaimet lähes poikkeuksetta tuhoavat keksin seuraavan sammutuksen yhteydessä. Tehdään seuraavassa esimerkissä rasittava "ikikeksi" joka ei vanhene seuraavaan 100-vuoteen.
<?php setcookie("Nimi", "JTS", time()+3155692600); ?> //Asettaa keksille "Nimi" arvon "JTS" ja asettaa keksin tuhoutumaan vasta 100-vuoden päästä
Esimerkissä 3155692600 on siis arviolta 100-vuotta muutettuna sekunteiksi.
Keksin arvon hakeminen
Asetettujen keksien arvot löytyvät sille varatusta taulukosta $_COOKIE. Jos olemme asettaneet nimellä "Nimi" keksin, voimme tulostaa sen yksinkertaisesti seuraavasti:
<?php echo $_COOKIE['Nimi']; ?> //Tulostaa keksin "Nimi" arvon mikäli sellainen on asetettu
Huomaa etteivät selaimet anna oletuksena lukea muiden keksien tietoja kuin niiden jotka on asetettu juuri kyseiseltä palvelimelta.
Keksin tietojen muuttaminen
Keksin tietojen muuttaminen tapahtuu yksinkertaisesti ylikirjoittamalla vanha keksi uudella arvolla (lukuunottamatta nimeä jota ei voida muuttaa).
Keksin tuhoaminen
Keksi tuhotaan yksinkertaisesti muuttamalla kestoajan päättymishetki menneisyyteen, jolloin käyttäjän selaimen tulisi tuhota vanhentunut keksi (olettaen että käyttäjän järjestelmän kello on oikeassa ajassa).
<?php setcookie("Nimi", "", time()-86400); ?> //Asettaa keksille "Nimi" tyhjän arvon ja asettaa keksin tuhoutumaan päivä sitten
Kyseinen keksi asettaa päättymisajankohdaksi 24 tuntia sitten, jolloin keksi tuhotaan automaattisesti selaimen toimesta.
REQUEST ($_REQUEST)
$_REQUEST on muuttuja, joka sisältää $_GET, $_POST ja $_COOKIE muuttujien tiedot. Tällöin tiedon välitystavalla ei ole väliä, mutta toisaalta päällekkäiset tiedot eri välitystavoilla voivat aiheuttaa ongelmatilanteita (esim. samannimiset muuttujat $_GET ja $_COOKIE muuttujataulukoissa).
Istunnot ($_SESSION)
Istuntojen (eng. session) merkittävin ominaisuus on että niissä itse tiedot tallennetaan palvelimelle. Käyttäjä tunnistetaan uniikilla istunto-id:llä joka luodaan ja lähetetään käyttäjälle kun istunto tehdään. Yleisimmin id tallennetaan käyttäjän selaimeen keksinä, mutta myös istunto-id:n kuljetus GET-methodilla on mahdollista. Tämä voi joissain tapauksissa olla tietoturvariski, sillä tällöin ilman eri toimenpiteitä kuka tahansa voi päästä istunnon tietoihin käsiksi tietäessään käytettävän osoitteen. Voit pakottaa istunnot käyttämään keksejä asettamalla php.ini:stä session.use_only_cookies -asetuksen päälle. Jos sinulla ei ole oikeuksia muuttaa asetusta sieltä, tai haluat muuttaa sitä vain hakemistopuukohtaisesti, voit tehdä muutoksen myös .htaccessiin seuraavasti: (olettaen, että käytössä on Apache ja että AllowOverride on päällä)
php_value session.use_only_cookies On
Istunnon aloittaminen
Istunto aloitetaan session_start-funktiolla. Funktio myös tarkastaa onko istuntoa jo olemassa, ja mikäli näin on jatkaa kyseistä istuntoa.
<?php session_start(); ?> //Aloittaa istunnon tai jatkaa olemassa olevaa istuntoa
Tietojen tallentaminen istuntoon
Tietoja tallennetaan yksinkertaisesti määrittämällä halutut arvot $_SESSION taulukkoon.
<?php session_start(); $_SESSION['nimi'] = 'JTS'; ?> //Aloittaa istunnon tai jatkaa olemassa olevaa istuntoa sekä määrittää istunnon muuttujalle "nimi" arvon "JTS"
Tietojen hakeminen istunnosta
Tallennetut tiedot löytyvät istunnon aloituksen/jatkamisen jälkeen $_SESSION-taulukosta.
<?php session_start(); echo $_SESSION['nimi']; ?> //Tulostaa istunnon muuttujan "nimi" arvon
Istunnon tuhoaminen
Käyttämättömät istunnot tuhotaan oletuksena 24min jälkeen (php.ini asetus). Samoin istunto-id keksi tuhotaan oletuksena selaimen sammutuksessa. Voit myös itse tuhota istunnon session_unset- ja session_destroy-funktioilla.
<?php session_start(); session_unset(); session_destroy(); ?>
