24. Esimerkki (Osa 2) 429 OPPITUNTI 24 Esimerkki (Osa 2) Luvussa 23, "Esimerkki (Osa 1)" rakensimme ympäristön, joka sallii käyttäjien kirjoittautua palveluun ja lisätä kerho- ja tapahtumatiedot järjestelmään. Nyt voimme luoda skriptejä, jotka ovat välttämättömiä, jotta tavallinen käyttäjä voisi selata järjestelmän tietoja. Tämän tunnin aiheita ovat: Kuinka luodaan funktioita, jotka erottavat tietoa useista tauluista yhdellä kyselyllä Kuinka luodaan funktioita, jotka muuttavat SQL-kyselyn rakennetta vietyjen parametrien mukaan Kuinka tallennetaan hakuasetuksia, joita istuntofunktiot käyttävät Kuinka valmistetaan puhdas tekstitieto esitettäväksi HTML-ympäristössä
430 24. Esimerkki (Osa 2) Tapahtumapäiväkirjan julkiset näkymät Nyt kun jäsenet voivat rekisteröidä kerhonsa ja tapahtumansa tietokantaamme, voimme rakentaa näkymiä, joiden kautta tavalliset käyttäjät voivat ottaa esille tuota informaatiota. Nämä näkymät antavat käyttäjälle mahdollisuuden selata tietoja hakemisen sijaan, vaikkakin tuon lisäominaisuuden laittaminen mukaan ei olisi lainkaan vaikeaa. Tässä jaksossa rakennamme näytöt, joiden kautta käyttäjä voi nähdä listauksia, jotka vastaavat hänen aluettaan tai kiinnostuksen kohdettaan halutun kuukauden kohdalla. viewevents.php Tämä viewevents.php-näkymä antaa käyttäjälle mahdollisuuden selata annettuja tapahtumia. Se on samanlainen kuin reviewevents.php-näkymä, jota käsittelimme edellisellä tunnillamme, mutta antaa käyttäjälle kuitenkin enemmän mahdollisuuksia ja joustavuutta. Se ei kuitenkaan salli tiedon muuttamista. Tämän tiedoston koodi on listauksessa 24.1. Listaus 24.1 viewevents.php 1: <?php 2: include("dblib.inc"); 3: include("date.inc"); 4: include("clublib.inc"); 5: 6: if ( isset($actionflag) && $actionflag == "showevents" ) 7: $session[viewevents] = $form; 8: elseif ( $session[viewevents] ) 9: $form = $session[viewevents]; 10: else 11: { 12: $d_array = getdate( time() ); 13: $session[viewevents][area] = "ANY"; 14: $session[viewevents][type] = "ANY"; 15: $session[viewevents][months] = $d_array[mon]; 16: $session[viewevents][years] = $d_array[year]; 17: } 18: 19: $range = getdaterange( $session[viewevents][months], 20: $session[viewevents][years] ); 21: function displayevents( ) 22: {
24. Esimerkki (Osa 2) 431 23: global $range, $session; 24: 25: $events = getevents( 0, $range, $session[viewevents][area], 26: $session[viewevents][type] ); 27: if (! $events ) 28: 29: print "No events yet for this combination<p>"; 30: return; 31: } 32: print "<table border=1>\n"; 33: print "<td><b>date</b></td>\n"; 34: print "<td><b>event</b></td>\n"; 35: print "<td><b>club</b></td>\n"; 36: print "<td><b>area</b></td>\n"; 37: print "<td><b>type</b></td>\n"; 38: foreach ( $events as $row ) 39: { 40: print "<tr>\n"; 41: print "<td>".date("j M Y H.i", $row[edate])."</td>\n"; 42: print "<td><a href=\"viewevent.php?event_id=$row[id]&".sid."\">". 43: html($row[ename])."</a></td>\n"; 44: print "<td><a href=\"viewclub.php?club_id=$row[eclub]&".sid."\">". 45: html($row[name])."</a></td>\n"; 46: print "<td>$row[areaname]</td>\n"; 47: print "<td>$row[typename]</td>\n"; 48: print "</tr>\n"; 49: } 50: print "</table>\n"; 51: } 52:?> 53: 54: <html> 55: <head>
432 24. Esimerkki (Osa 2) 56: <title>view events</title> 57: </head> 58: <body> 59: <?php 60: include("publicnav.inc"); 61:?> 62: <h1>view Events</h1> 63: <p> 64: <form action="<?php print $PHP_SELF;?>"> 65: <input type="hidden" name="actionflag" value="showevents"> 66: <input type="hidden" name="<?php print session_name()?>" 67: value="<?php print session_id()?>"> 68: <select name=form[months]> 69: <?php writemonthoptions( $range[0] );?> 70: </select> 71: 72: <select name=form[years]> 73: <?php writeyearoptions( $range[0] );?> 74: </select> 75: 76: <select name=form[area]> 77: <option value="any">any Area 78: <?php writeoptionlist( "areas", $form[area] )?> 79: </select> 80: 81: <select name=form[type]> 82: <option value="any">any type of event 83: <?php writeoptionlist( "types", $form[type] )?> 84: </select> 85: 86: <input type = "submit" value="change"> 87: </form> 88: </p>
24. Esimerkki (Osa 2) 433 89: 90: <?php 91: displayevents( ); 92:?> 93: 94: </body> 95: </html> Aloitamme koodin sisällyttämällä kirjastotiedostot dblib.inc, date.inc ja clublib.inc. Saamme näin pääsyn tiedostojen funktioihin. Lisäksi tiedostojen dblib.inc ja clublib.inc lisääminen takaa, että avaamme tietokantayhteyden ja käynnistämme istunnon. Sen jälkeen tarkistamme, onko käyttäjä lähettänyt lomakkeen sivulle, testaamalla muuttujaa nimeltä $actionflag. Vastaava kenttä (actionflag) on upotettu piilomuuttujana sivun lomakkeelle. Jos käyttäjä on lähettänyt lomakkeen, hänen valintansa tulee ohittaa aiemmin tallennetut asetukset. Edellisellä tunnilla näit, kuinka rekisteröimme assosiatiivisen taulukkomuuttujan käyttäjän istunnon kanssa tallentaaksemme kirjautumistiedot. Tällä tunnilla lisäämme samaan taulukkoon uusia elementtejä, jotka pitävät yllä käyttäjän asetuksia. Muuttuja $session rekisteröitiin käyttäjän istunnon kanssa, kun laitoimme mukaan clublib.phptiedoston. session_start(); session_register( "session" ); Käännämme nyt $session-muuttujan moniulotteiseen taulukkoon siten, että sijoitamme assosiatiiviset taulukkoelementit elementtiin nimeltä $session[viewevents]. Näin luokittelemme asetusmuuttujat sellaisiksi, että ne kuuluvat vain tälle näytölle. Käyttäjän valitsemat vaihtoehdot ovat alue, tyyppi, kuukaudet ja vuodet. Sijoitamme lomakkeen valinnat samannimisiin $session[viewevents]-elementteihin. Jos käyttäjä ei ole lähettänyt lomaketta, hän on saattanut tehdä niin aiemmin. Siinä tapauksessa on $session[viewevents]-taulukko asetettuna, mutta $actionflag-muuttuja ei. Jos niin on, asetamme $formtaulukkoon samat arvot. Se takaa, että lomake näkyy oikein asetuksin. Jos käyttäjä ei ole lähettänyt näytön lomaketta ja $session[viewevents]-elementti on tyhjä, meidän tulee muodostaa taulukko, joka perustuu oletusarvoihin. Käytämme getdate()-funktiota päivämääräindeksitaulukon muodostamiseksi. Tuota taulukkoa käytetään asettamaan $session[viewevents][months]- elementti nykyisen kuukausi-indeksin mukaiseksi ja $session[viewevents][years]-elementti nykyisen vuoden mukaan. Nyt tiedämme, että $session[viewevents][months]- ja $session[viewevents][years]-elementti sisältää nykyisen kuukauden ja vuoden ja sen, ovatko tiedot peräisin lomakkeen lähettämisestä, käyttäjäistunnosta vai oletuksena olevasta nykyisestä päivämäärästä. Viemme nuo arvot uudelle date.inc-tiedoston funktiolle nimeltä getdaterange(). Tuo funktio ottaa vastaan kuukauden ja vuoden ja palauttaa taulukon, jossa on kaksi aikaleimaa, jotka merkitsevät kuukauden alkua ja loppua. Listaus 24.2 Ote tiedostosta date.inc 1: function getdaterange( $mon, $year )
434 24. Esimerkki (Osa 2) 2: { 3: $start = mktime( 0, 0, 0, $mon, 1, $year ); 4: $end = mktime( 0, 0, 0, $mon+1, 1, $year ); 5: $end--; 6: return array( $start, $end ); 7: } Tämän funktion palauttama taulukko tallennetaan globaaliin $range-muuttujaan. Luomme funktion nimeltä displayevents(), joka kirjoittaa valitut tapahtumatiedot selaimelle. Sitä kutsutaan HTML-asiakirjan rungosta. Saadaksemme tapahtumatietotaulukon kutsumme getevents()-funktiota, joka on tiedostossa dblib.inc, jonka laitoimme mukaan aiemmin. Kohtasimme tämän funktion jo edellisellä tunnilla, mutta käytimme vain osan sen mahdollisuuksista. Listaus 24.3 Ote tiedostosta dlib.inc 1: function getevents( $club_id=0, $range=0, $area=0, $type=0 ) 2: { 3: global $link; 4: $query = "SELECT clubs.name, events.*, areas.area as areaname, 5: types.type as typename "; 6: $query.= "FROM clubs, events, areas, types WHERE "; 7: $query.= "clubs.id=events.eclub 8: AND events.area=areas.id 9: AND events.type=types.id "; 10: if (! empty( $club_id ) && $club_id!="any" ) 11: $query.= "AND events.eclub='$club_id' "; 12: if (! empty($range) ) 13: $query.= "AND events.edate >= '$range[0]' AND 14: events.edate <='$range[1]' "; 15: if (! empty($area) && $area!= "ANY" ) 16: $query.= "AND events.area='$area' "; 17: if (! empty($type) && $type!= "ANY" ) 18: $query.= "AND events.type='$type' "; 19: $query.= "ORDER BY events.edate"; 20: $result = mysql_query( $query, $link ); 21: if (! $result )
24. Esimerkki (Osa 2) 435 22: die ( "getidevents fatal error: ".mysql_error() ); 23: $ret = array(); 24: while ( $row = mysql_fetch_array( $result ) ) 25: array_push( $ret, $row ); 26: return $ret;s 27: } Vaikka tämän funktion nimenä onkin getevents(), se sieppaa paljon enemmän tietoa. Kuten voit nähdä, se ottaa vastaan neljä argumenttia: kerhon ID:n, päivämäärärajat, jotka ovat taulukossa kahtena aikaleimana, aluekoodin ja tyyppikoodin. Kaikki nämä argumentit ovat valinnaisia ja voit korvata ne joko nollalla tai arvolla false, jos et halua niitä mukaan SQL-kyselyyn. Funktio muodostaa dynaamisesti SQL-kyselyn, joka perustuu sille vietyihin argumentteihin. Ydinkysely liittää yhteen kaikki tietokannan taulut ja takaa, että kerhon, alueen ja tyypin nimi ovat mukana tulosjoukossa. $query = "SELECT clubs.name, events.*, areas.area as areaname, types.type as typename "; $query.= "FROM clubs, events, areas, types WHERE "; $query.= "clubs.id=events.eclub AND events.area=areas.id AND events.type=types.id "; Sen jälkeen lisätään muita ehtoja kyselyyn sen mukaan, onko funktion argumentteja asetettu. Parametrit $type ja $area ohitetaan myöskin, jos ne sisältävät merkkijonon "ANY". Käytännössä tämä merkitsee sitä, että mitä enemmän argumentteja funktio saa, sitä kapeamman tulosjoukon se palauttaa. Jos mitään argumentteja ei anneta, funktio palauttaa tapahtumataulukon jokaisen tapahtuman. Jos funktiolle annetaan $club_id-argumentti, se palauttaa vain kyseisen kerhon tapahtumat. Jos argumenttina annetaan $range-taulukko, palautetaan vain tuon aikavälin tapahtumat, ja niin edelleen. Lopuksi kysely lähetetään ja tulos palautetaan moniulotteisena taulukkona. Sen jälkeen meidän on vain käytävä taulukko läpi silmukassa. Käytämme jokaista edate-kenttää päivämäärän muotoilemiseksi date()-funktion yhteydessä. Sitten muodostamme linkin tiedostoon viewevent.php, joka antaa lisätietoa tapahtumasta. Sitä varten muodostamme kyselymerkkijonon, joka sisältää tapahtuman ID:n ja SID-vakion. Tässä silmukassa muodostamme myös HTML-hyperlinkin tiedostoon viewclub.php luoden kyselymerkkijonon, joka sisältää kerhon ID:n ja SID-vakion. Lopuksi tulostamme tapahtuman tyypin ja alueen nimet. Olet saattanut huomata, että edellisellä tunnilla käytimme funktiota nimeltä html(), kun tulostimme jäsenkohtaista tapahtumatietoa yhteenvetolomakkeella. Kun käymme läpi tapahtumatietoa writeevents()- funktiossa, kutsumme html()-funktiota uudelleen. Tämä funktio on käyttäjän määrittelemä ja se elää clublib.inc-kirjastossa. Se ottaa vastaan merkkijonon ja palauttaa muunnetun version, joka sopii selaimen tulostettavaksi. Erikoismerkit muunnetaan HTML-merkeiksi ja rivinvaihdot saavat BR-elementit mukaansa.
436 24. Esimerkki (Osa 2) Listaus 24.4 Ote tiedostosta clublib.inc 1: function html( $str ) 2: { 3: if ( is_array( $str ) ) 4: { 5: foreach ( $str as $key=>$val ) 6: $str[$key] = htmlstr( $val ); 7: return $str; 8: } 9: return htmlstr( $str ); 10: } 11: function htmlstr( $str ) 12: { 13: $str = htmlspecialchars( $str ); 14: $str = nl2br( $str ); 15: return $str; 16: } Kuten voit nähdä, kyseessä on kaksi funktiota. Funktio html() ottaa argumentikseen joko merkkijonon tai taulukon. Jos parametrimuuttuja sisältää taulukon, käymme sen läpi silmukassa ja muunnamme jokaisen arvon. Muutoin muunnos toteutetaan suoraan parametrimuuttujaan. Todellinen muunnos tapahtuu funktiossa htmlstr(), joka käyttää hyväkseen kahta sisäistä funktiota: htmlspecialcharacters() muuntaa jokaisen HTML-ympäristössä esityskelpoisen merkin HTML-entiteetikseen ja nl2br() lisää BR-tagit merkkijonoon tilanteen mukaan. Kun olemme asettaneet oletustiedot ja luoneet funktion, joka tulostaa tapahtumatietoa, kaikki tuo jätetään ja aletaan muodostaa lomaketta, jonka kautta käyttäjä voi valita, kuinka hän haluaa selata tapahtumia. Käyttäjän lomake on helppo rakentaa käyttämällä edellisen tunnin funktiotia, jotka osaavat tulostaa dynaamisesti HTML-koodin mukaisia OPTION-elementtejä. Kuva 24.1 esittää näytetulostuksen tiedostosta viewevents.php.
24. Esimerkki (Osa 2) 437 KUVA 24.1 Tulostus tiedostosta viewevents.php. viewclubs.php Käyttäjä saattaa haluta esittää tietokantatietoa kerhokohtaisesti, ei välttämättä tapahtumakohtaisesti. Tällöin tulosjoukko kaventuu kerhon tyypin ja alueen mukaan. Tällainen vaihtoehto tarjotaan viewclubs.php-näytön kautta. Skripti on listauksessa 24.5. Listaus 24.5 viewclubs.php 1: <?php 2: include("dblib.inc"); 3: include("date.inc"); 4: include("clublib.inc"); 5: if ( isset($actionflag) && $actionflag == "showclubs" ) 6: $session[viewclubs] = $form; 7: elseif ( $session[viewclubs] ) 8: $form = $session[viewclubs]; 9: else 10: { 11: $session[viewclubs][area] = "ANY"; 12: $session[viewclubs][type] = "ANY"; 13: } 14: function displayclubs( ) 15: { 16: global $session; 17: $clubs = getclubs( $session[viewclubs][area],
438 24. Esimerkki (Osa 2) 18: $session[viewclubs][type] ); 19: if (! $clubs ) 20: { 21: print "No clubs yet that fit these conditions<p>\n"; 22: return; 23: } 24: print "<table border=1>\n"; 25: print "<td><b>club</b></td>\n"; 26: print "<td><b>area</b></td>\n"; 27: print "<td><b>type</b></td>\n"; 28: foreach ( $clubs as $row ) 29: { 30: print "<tr>\n"; 31: print "<td><a href=\"viewclub.php?club_id=$row[id]&".sid."\">". 32: html($row[name])."</a></td>\n"; 33: print "<td>$row[areaname]</td>\n"; 34: print "<td>$row[typename]</td>\n"; 35: print "</tr>\n"; 36: } 37: print "</table>\n"; 38: } 39:?> 40: <html> 41: <head> 42: <title>view clubs</title> 43: </head> 44: <body> 45: <?php 46: include("publicnav.inc"); 47:?> 48: <P> 49: <h1>view Clubs</h1> 50: <p>
24. Esimerkki (Osa 2) 439 51: <form action="<?php print $PHP_SELF;?>"> 52: <input type="hidden" name="actionflag" value="showclubs"> 53: <input type="hidden" name="<?php print session_name()?>" 54: value="<?php print session_id()?>"> 55: <select name=form[area]> 56: <option value="any">any Area 57: <?php writeoptionlist( "areas", $form[area] )?> 58: </select> 59: <select name=form[type]> 60: <option value="any">any type of club 61: <?php writeoptionlist( "types", $form[type] )?> 62: </select> 63: <input type = "submit" value="change"> 64: </form> 65: </p> 66: <?php 67: displayclubs( ); 68:?> 69: </body> 70: </html> Kuten voit nähdä, tämä skripti on rakenteeltaan ja logiikaltaan samanlainen kuin edellinen esimerkki. Tallennamme tämän sivun istuntomuuttujat $session[viewclubs]-elementtiin. Jos käyttäjä on lähettänyt sivun lomakkeen, päivitämme istuntomuuttujat. Jos käyttäjä ei ole lähettänyt lomaketta, mutta istuntomuuttujat ovat saatavilla, sijoitamme $session[viewclubs]-arvon $form-muuttujaan. Jos kaikki muu epäonnistuu, täytämme $session[viewclubs]-taulukon oletusarvoilla. Luomme funktion displayclubs(). Sen sisältä kutsutaan dblib-inc-tiedoston uutta funktiota, getclubs()- funktiota. Tämä funktio ottaa vastaan valinnaisesti joko kerhotaulun tyyppikentän tai aluekentän arvon: Listaus 24.6 Ote tiedostosta dlib.inc 1: function getclubs( $area="", $type="" ) 2: { 3: global $link; 4: $query = "SELECT clubs.*, areas.area as areaname, 5: types.type as typename ";
440 24. Esimerkki (Osa 2) 6: $query.= "FROM clubs, areas, types WHERE "; 7: $query.= "clubs.area=areas.id AND clubs.type=types.id "; 8: if ( $area!= "ANY" &&! empty( $area ) ) 9: $query.= "AND clubs.area='$area' "; 10: if ( $type!= "ANY" &&! empty( $type ) ) 11: $query.= "AND clubs.type='$type' "; 12: $query.= "ORDER BY clubs.area, clubs.type, clubs.name"; 13: $result = mysql_query( $query, $link ); 14: if (! $result ) 15: die ( "getidevents fatal error: ".mysql_error() ); 16: $ret = array(); 17: while ( $row = mysql_fetch_array( $result ) ) 18: array_push( $ret, $row ); 19: return $ret; 20: } 21: Funktio getclubs() rakentaa dynaamisen SQL-kyselyn, joka perustuu sille vietyihin argumentteihin. Oletuksena se yhdistää kerho-, alue- ja tyyppitaulut. Jos sille viedään $type- tai $area-argumentteina jotain muuta kuin tyhjä merkkijono tai "ANY"-merkkijono, se kaventaa edelleenkin WHERE-osaa SQL-lauseesta annettujen arvojen mukaisesti. Kuten ennenkin, se palauttaa nytkin moniulotteisen taulukon. Käymme silmukassa läpi getclubs()-funktion palauttaman taulukon ja kirjoitamme nimen, alueen nimen ja tyypin nimen selaimelle. Kuten aiemminkin, kerhon nimi muodostaa nytkin osan hyperlinkistä, joka osoittaa tiedostoon viewclub.php. viewclub.php Tämä viewclub.php-näyttö esittää kaiken kerhoon liittyvän tiedon. Se voidaan ottaa esille hyperlinkkien kautta, jotka osoittavat joko tiedostoon viewevents.php tai viewclubs.php. Koodissa on mukana aiempien esimerkkien logiikkaa ja useita funktiota. Koodi on listauksessa 24.7.
24. Esimerkki (Osa 2) 441 LISTAUS 24.7 viewclub.php 1: <?php 2: include("dblib.inc"); 3: include("clublib.inc"); 4: if (! isset($club_id) ) 5: header( "Location: viewclubs.php?".sid ); 6: $club = getclubjoined( $club_id ); 7: $club = html( $club ); 8: if ( $club[mail]!= "" ) 9: $club[mail] = "<A HREF=\"mailto:$club[mail]\">$club[mail]</A>"; 10: function displayevents() 11: { 12: global $club_id; 13: $events = getevents( $club_id ); 14: if (! $events ) 15: { 16: print "No events yet for this club<p>"; 17: return; 18: } 19: print "<table border=1>\n"; 20: print "<td><b>date</b></td>\n"; 21: print "<td><b>event</b></td>\n"; 22: print "<td><b>area</b></td>\n"; 23: print "<td><b>type</b></td>\n"; 24: foreach ( $events as $row ) 25: { 26: print "<tr>\n"; 27: print "<td>".date("j M Y H.i", $row[edate])."</td>\n"; 28: print "<td><a href=\"viewevent.php?event_id=$row[id]&".sid."\">". 29: html($row[ename])."</a></td>\n"; 30: print "<td>$row[areaname]</td>\n"; 31: print "<td>$row[typename]</td>\n"; 32: print "</tr>\n";
442 24. Esimerkki (Osa 2) 33: } 34: print "</table>\n"; 35: } 36:?> 37: <html> 38: <head> 39: <title>view clubs</title> 40: </head> 41: <body> 42: <?php 43: include("publicnav.inc"); 44:?> 45: <p> 46: <h1>view club details</h1> 47: <h4><?php print $club[name]?></h4> 48: <p> 49: Area: <b><?php print $club[areaname]?></b> 50: <br> 51: Type: <b><?php print $club[typename]?></b> 52: <BR> 53: Mail: <b><?php print $club[mail]?></b> 54: </p> 55: Description:<br> 56: <b><?php print $club[description]?></b> 57: <hr> 58: <?php 59: displayevents(); 60:?> 61: </body> 62: </html> Tämä skripti vaatii $club_id-parametrin. Testaamme sen ja palautamme käyttäjän viewclubs.php-näytölle, jos emme löydä parametria. Saadaksemme informaatiota kutsumme dblib.inc-tiedoston funktiota getclubjoined(). Se ottaa argumentikseen kerhon ID:n ja palauttaa taulukon:
24. Esimerkki (Osa 2) 443 Listaus 24.8 Ote tiedostosta dlib.inc 1: function getclubjoined( $id ) 2: { 3: global $link; 4: $query = "SELECT clubs.*, areas.area as areaname, types.type as typename A "; 5: $query.= "FROM clubs, events, areas, types WHERE "; 6: $query.= "clubs.area=areas.id 7: AND clubs.type=types.id 8: AND clubs.id='$id'"; 9: $result = mysql_query( $query, $link ); 10: if (! $result ) 11: die ( "getclubjoined fatal error: ".mysql_error() ); 12: return mysql_fetch_array( $result ); 13: } Kutsumme tätä funktiota getrow()-funktion sijaan (joka voisi myöskin palauttaa kerhotietoa), koska sen muodostama SQL-kysely sisältää alueeseen ja tyyppiin liitetyt nimet. Se tekee sen suorittamalla kerho-, alue- ja tyyppitaulukoiden välisen yhdistämisen ja tuottaa palautettavaan taulukkoon lisäelementtejä nimeltä areaname ja typename. Tallennamme getclubjoined()-funktion palauttaman taulukon muuttujaan nimeltä $club. Tämä $clubtaulukko tulostetaan selaimelle asiakirjan runkoon. Määrittelemme myös funktion nimeltä displayevents(), joka ottaa argumentikseen kerhoon liittyvän tapahtumalistaa viemällä $club_id-muuttujan getevents()- funktiolle. Kuva 24.2 esittää tiedoston viewclub.php tyypillisen tulostuksen. viewevent.php Tämä viewevent.php-tiedosto sisältää skriptimme viimeisen näytön. Se tuottaa todellisen informaation kaikista yksittäisistä tapahtumista ja siihen päästään hyperlinkkien kautta miltä tahansa julkiselta sivulta, joka listaa tapahtumien yhteenvedot. Koodi on listauksessa 24.9. Listaus 24.9 viewevent.php 1: <?php 2: include("dblib.inc"); 3: include("clublib.inc"); 4: if (! isset($event_id) )
444 24. Esimerkki (Osa 2) 5: header( "Location: viewevents.php?".sid ); 6: $event = getevent( $event_id ); 7: html( $event ); 8:?> 9: <html> 10: <head> 11: <title>view event details</title> 12: </head> 13: <body> 14: <?php 15: include("publicnav.inc"); 16:?> 17: <P> 18: <h1>view event details</h1> 19: <h4><?php print $event[ename]?></h4> 20: <p> 21: Club: 22: <b> 23: <?php print "<a href=\"viewclub.php?club_id=$event[eclub]&".sid."\"> 24: $event[clubname]</a>" 25:?> 26: </b> 27: <br> 28: Area: <b><?php print $event[areaname]?></b> 29: <br> 30: Type: <b><?php print $event[typename]?></b> 31: </p> 32: Description:<br> 33: <?php print $event[edescription]?> 34: </body> 35: </html>
24. Esimerkki (Osa 2) 445 Kuten voit nähdä, näyttö on yksinkertainen. Saamme taulukon tapahtumataulukosta käyttämällä dblib.inctiedoston getevent()-funktiota. Viemme sille $event_id-muuttujan, jonka tulisi sisältää ID-arvo, joka tuli meille kyselymerkkijonon kautta. Taulukko on sitten helppoa kirjoittaa selaimelle. Voit nähdä getevent()-funktion listauksessa 24.10. Se sisältää suhteellisen yksinkertaisen SQL-lauseen, joka yhdistää kerho- ja tapahtumataulukot. Listaus 24.10 Ote tiedostosta dlib.inc 1: function getevent( $event_id ) 2: { 3: global $link; 4: 5: $query = "SELECT clubs.name as clubname, events.*, 6: areas.area as areaname, types.type as typename "; 7: $query.= "FROM clubs, events, areas, types WHERE "; 8: $query.= "clubs.id=events.eclub 9: AND events.area=areas.id 10: AND events.type=types.id 11: AND events.id='$event_id'"; 12: $result = mysql_query( $query, $link ); 13: if (! $result ) 14: die ( "getevent fatal error: ".mysql_error() ); 15: return mysql_fetch_array( $result ); 16: } KUVA 24.2 Tulostus tiedostosta viewclub.php.
446 24. Esimerkki (Osa 2) Tulevaisuus Olemme nyt työskennelleet läpi koko tapahtumapäiväkirjaskriptin. Toivon, että se kertoo hieman siitä dynamiikasta, joka liittyy pieneenkin käytännön projektiin, ja antaa tuntuman PHP:n mahdollisuuksiin. Erityisesti sinun tulisi huomata, kuinka helppoa PHP:n istuntofunktioiden on tallentaa käyttäjän asetukset sivulta sivulle. Jos käyttäjämme palaa viewevents.php-sivulle milloin tahansa yksittäisen istunnon aikana, hän näkee samat valinnat, jotka hän on tehnyt tälle näytölle aiemmin tekemänsä vierailun aikana. Ilman istuntofunktioita meidän olisi luultavasti vietävä paljon enemmän informaatiota pyynnöltä toiselle käyttämällä URL-kyselymerkkijonoja. Vaikka tapahtumapäiväkirja ei olekaan aivan täydellinen, se kuitenkin edustaa prototyyppiä, joka kykenee näyttämään käyttäjän toiminnan. Olisi hyvä lisätä muutamia piirteitä, erityisesti hakusanalla hakeminen. Olisi myös hienoa, jos käyttäjä voisi kommentoida tapahtumia. Se lisäisi kokonaan uuden ulottuvuuden skriptiin ja tekisi siitä suositumman ja vuorovaikutteisemman. Voisimme antaa kerhon ylläpitäjille mahdollisuuden sisällyttää sivuille linkkejä kuviin, jotka liittyvät kerhon toimintaan. Voisimme myös antaa kerhon toimittajille maahdollisuuden ladata kuvia suoraan selaimelta palvelimelle. Jäsenet voisivat myös kopioida tapahtumia ja laittaa tapahtumia järjestykseen. Ennen kuin skripti voidaan jaakaa asiakkaalle, haluamme muodostaa myös hallintaympäristön, jossa on työkaluja ei-tekniseen toimintaan, jossa tilejä ja tapahtumia voidaan muokata ja poistaa sekä lisätä ja muokata alue- ja tyyppiluokkia. Olet saattanut myös huomata, että skriptin tulos on nykyään hieman aneeminen. Meidän tulisi ehkä antaa tuotos visuaaliselle suunnittelijalle ja pyytää häntä muokkaamaan ulkoasua. Onneksi suurin osa koodistamme on helposti työstettävää, vaikkakin meitä saatetaan pyytää vielä muokkaamaan silmukoita, jotka tulostavat yhteenvetoja. Yhteenveto Tällä ja edellisellä tunnilla veimme päätökseen työmme, täysin toimivan Web-sovelluksen. Käytimme tekniikoita, joiden avulla tallensimme tilan, todensimme käyttäjiä, muokkasimme ja esitimme tietokantojen tietoa ja paljon muutakin. Moninäyttöistä koodiesimerkkia ei ole helppo esittää kirjassa, mutta yrittäminenkin on hyödyllistä. Olemme ottaneet esille aiheita, joihin törmäät uudelleen ja uudelleen, joten sinun tulee rakentaa strategioita tilainformaation ylläpitämiseen. K&V K No siinä se oli; mitäs seuraavaksi? V Nyt kaikki riippuu sinusta. Tämä kirja sisältää tarpeeksi informaatiota, jotta voit luoda omia kehittyneitä sovelluksiasi ja ympäristöjäsi. Kun käytät antamiamme taitoja ja hakemalla lisätietoa, mikään ei voi estää sinua!
24. Esimerkki (Osa 2) 447 Työpaja Työpaja tarjoaa joukon kertauskysymyksiä, joiden avulla voit tarkistaa, oletko ymmärtänyt materiaalin sisältöä. Yritä ymmärtää vastaukset ennen kuin jatkat seuraaviin lukuihin. Vastaukset ovat liitteessä A. Kysymyksiä 1. Millä funktiolla lisäät elementin taulukon loppuun? 2. Onko mahdollista lisätä elementti taulukkoon käyttämättä funktiota? 3. Millä funktiolla käännät erikoismerkit HTML-muotoon? 4. Millä funktiolla käännät rivinvaihtomerkit BR-tageiksi? 5. SID-vakiolla voit viedä istunnon ID:n toiselle sivulle HTML-linkin kautta. Kuinka voisit saada aikaan saman lomakkeen kautta? Toiminta 1. Tutki tämän tunnin koodia. Onko jokin tekniikoista tai aiheista sopiva omiin projekteihisi? 2. Selaile kirjaa taaksepäin ja tutki muistiinpanojasi. Jos olet seurannut kirjaa ikään kuin kurssin muodossa, muista, että omien muistiinpanojen kertaaminen täydentää suorittamasi kurssin.
448 24. Esimerkki (Osa 2)