ProgeTiigri ppematerjal



Serveripoolsete veebirakenduste koostamine

Jaagup Kippar


2013


Sisukord
Sissejuhatus	5
Algus	6
Tutvustav veebileht	6
PHP algus	7
lesandeid	7
Muutuja, tingimuslause	7
lesandeid	8
Kellaaeg	8
lesandeid	9
Tollikalkulaator	9
lesandeid	11
Ostusumma arvutamine	11
Valik rippmenst	12
lesandeid	13
Andmed massiivist	13
lesandeid	15
Mobiilimalli jrgi veebilehestik	15
ksiku teate lugemine	15
Valmis kujundusmall mobiilile	16
lesandeid	22
Andmebaasitabeli veebivljund	23
SQL	23
lesandeid	25
Tabeli sisu vaatamine	25
lesandeid	27
Teadete valik	27
lesandeid	30
Andmete lisamine ja kustutamine	31
lesandeid	35
Andmete muutmine, laulude lehestik	36
Uue laulu lisamine	37
lesandeid	38
Lauludele punktide lisamine	38
lesandeid	40
Laulude peitmine ja avalikustamine	40
lesandeid	45
Kommenteerimine	45
lesandeid	48
Haldus laulude kaupa	48
lesandeid	53
Jalgrattaeksami haldamise rakendus	54
Kavandamine	54
Jalgrattaeksami ldkirjeldus	54
Kasutajalood	56
Rakenduse lehed	56
Lehtede joonised	58
Andmebaasiskeem	60
Rakenduse kiguks tarvilikud SQL-laused.	62
Veebilehtede loomine 	63
konf.php	63
registreerimine.php	63
teooriaeksam.php	65
slaalom.php	66
ringtee.php	67
t2nav.php	68
lubadeleht.php	69
lubadeleht.php ilusamalt	70
lesandeid	72
Oma lahenduse loomise lesanded	72
Kohviautomaat	73
Viljaladu	73
Toolivahendus	73
Autoveod	73
Arvutikomplektid	74
Hirmude maja	74
Aknaruloode tootmine	74
Tantsuvistlus	75
Suusahppevistlus	75
Andmebaasiksklused	75
Alustabel	75
lesandeid	76
Agregaatfunktsioonid	76
lesandeid	77
Grupeerimine	78
Alampringud	78
Alampringud vrtuse asendajana	79
lesandeid	80
Alampringud loetelu asendajana	80
lesandeid	81
Alampringud tabeli asendajana	81
lesandeid	82
Rekursiivsed alampringud	82
lesandeid	83
Andmetabeli struktuuri muutmine	83
lesandeid	84
Sessioonid, meldimine	85
loendur.php	85
lesandeid	85
meldimisleht.php	86
lesandeid	87
kellaleht.php	87
lesandeid	88
Parool andmebaasis, rollid	88
meldimisleht.php	90
kellaleht.php	91
haldusleht.php	92
lesandeid	93
lesanne  -  Arvutiparanduste halduslehestik	93
Ettevalmistus	94
Haldustd	94
Statistika	94
Lahendusi ja tiendusi	95
Algus	95
Muutuja, tingimuslause	95
Kellaaeg	95
Tollikalkulaator	96
Ostusumma arvutamine	98
Andmed massiivist	99
Andmetabeli veebivljund	105
Andmetabel	105
Tabeli sisu vaatamine	106
Teadete valik	108
Andmete lisamine ja kustutamine	110
Andmete muutmine, laulude lehestik	113
Andmetabeli loomine	114
Ansambli nime lisamine	114
Punktide andmine ansamblitele 	115
Peitmine ja avalikustamine	116
Avalikustatud kandideerivad ansamblid	117
Kommenteerimine	118
Ansamblite hindamise ja kommenteerimise leht	120
Kokkuvte	122

Sissejuhatus

Mrgatav osa tnapevastest arvutirakendustest ttab veebis. Mned neist kasutavad veebihendust vaid lehe kohale tmbamiseks ning edasine t kib kliendi arvutis vi mobiilseadmes. Sellisel juhul piisab veebiserveriks lihtsast failide laust, kust need ksimise peale siis kasutaja arvutisse saadetakse. Kui aga soovitakse rakenduses loodud andmeid mne teise arvutiga vahetada, siis peab veebiserver veidi targem olema. Vahetamist on tarvis teisele kasutajale andmete nitamiseks, samuti kui soovitakse ise oma t talletada ja hiljem teises arvutis edasi teha. Suuremate andmekoguste edasikandmise tarbeks on olemas ka mlupulgad ja muud salvestusseadmed. Kuni aga nnestub sekundite jooksul veebi kaudu andmed sobivasse kohta saada, siis see on pris mugav. 

Veebilehtedele sai serveripoolset tarkust jagada juba 1990ndate algul. CGI-nimelise liidese kaudu vib igas programmeerimiskeeles kirjutatud programm saada veebist andmeid ning saata oma tulemuse kasutajale. Nnda olid algselt veebilehedki kirjutatud C-s, Pascalis, PERLis ja muudes parasjagu levinud keeltes. Veebi levides asuti programmeerimiskeeltele veebisbralikke tiendusi looma ning veebi jaoks suisa eraldi keeli ja tehnoloogiaid kokku panema. heks esimeseks selliseks  sai ka PHP, mille phjal siinne pik koostatud. PHPd kasutatakse pigem vikeste ja keskmise suurustega veebide loomisel ning Eestis ttavate veebide ldarvust on vhemalt kaks kolmandikku PHPga seotud - olgu siis otse selle keele abil tehtud vi kasutatud mnd raamistikku, mis PHPle tugineb. Suuremate veebide loomise puhul konkureerivad tehnoloogiatena Java J2EE koos Servlettide ja JSP-lehtedega ning Microsoft .NETi alla kuuluv ASP.NET raamistik. Kuid ka PHP juurde on loodud vahendeid, mis aitavad lahendustel ttada tuhandete kasutajate ja sadade heaegsete pringutega. 

Veebisisendi ja -vljundiga programmidel on aga mned eriprad. Olenevalt rakendusest, kuid kllalt sageli tuleb vljastada suures koguses muutumatut HTML-teksti ning sinna vahele vaid ksikud kohad, mis programmiga muuta vaja. Teiseks probleemiks veebirakenduste juures on, et kunagi ei saa usaldada sisendit kasutajalt  le veebi vib tulla ligi suvaline hkker ning otsisna asemele panna teele niteks mne videofilmi sisu binaarkujul. Sekelduste vltimiseks on seetttu kasulik lisada sisendile piiranguid ja kontrolle.

Algus
Vahepealsetest keerdkikudest hoolimata paistab, et veebi koostamisel langeb phirhk lhiaastatel ikka HTMLi, sinna juurde kuuluva CSSi ja Javaskripti peale. HTMLi kirjutamise ning sealtkaudu saadavate andmetega saab PHP igati mugavasti hakkama. Seetttu alustamegi ppematerjali lihtsa veebilehe loomisega ning vaikselt lisame sinna programmeerimisvimalusi.

Tutvustav veebileht
HTML-faili tbiks on tekstifail. See thendab, et see fail vib sisaldada ainult teksti vi muid ekraanil nhtavaid smboleid. Tavalise tekstina olev osa paistab jutuna kasutajatele. Teksti osade eristamiseks aga saab teksti sisse panna < ja > mrkide vahele HTMLi mrgendeid, millega  veebilehitsejat juhatada ja dokumendi struktuuri mrkida. 

Veebilehe esmaseks struktuuriks on deklaratsioon (doctype), HTML-dokument ise - mis jb mrgendite <html> ja </html> vahele. Ning dokument jaguneb piseks (head) ning sisuosaks (body). Esimeses neist on andmed dokumendi kohta - kes tegi, millal tegi, kui kaua kehtib, mrksnad, lhikirjeldus jm. Sisuosas (body) olev tekst on ldiselt vaatajale nhtav - vlja arvatud mrgendite nimed, millega teksti juhitakse. 

<!doctype html>
<html>
  <head>

  </head>
  <body>

  </body>
</html>


Head-osas paiknev title on nha veebilehitseja tiitliribal. Kui korraga avatud palju lehti, siis selle jrgi saab vaadata, millist lehte parajasti nha soovitakse. 

Sisus vib teksti jagada likudesse div-mrgendite abil. Reavahetust thistab <br />. Pealkirja mrkimiseks sobivad <h1>koos lpuga </h1> ning <h2> ja </h2>. Sgavama struktuuri puhul ka suuremate numbritega pealkirjad. 

Loetelu piiritleb <ul> ja </ul> (unordered list). Iga loeteluelemendi mber tuleb <li> ja </li>. Selliste vahenditega saabki lihtsa veebilehe kokku.

<!doctype html>
<html>
  <head>
     <title>Jaagupi leht</title>
  </head>
  <body>
     <h1>Jaagup</h1>
	 <div>
	    Sndis 03. mail 1976 
		  Tallinnas. <br /> Kasvas Mustamel.
	 </div>
	 <h2>Huvialad</h2>
	 <ul>
	   <li>Kandlemng</li>
	   <li>Jalgrattasit</li>
	 </ul>
  </body>
</html>
Veebileht nhtuna brauseriaknas:




PHP algus
Eelnev leht saadeti serverist veebilehitsejasse samal kujul nagu ta faillina oli salvestatud. Serveripoolse rakenduse korral aga pannakse failis olev kood enne kima ning siis saadetakse t tulemus brauserisse. PHP puhul tuleb kivitatav kood panna algusthise <?php ning lpu ?> vahele. Ksklus echo trkib tulemuse ekraanile

Arvutus: 
<?php
  echo 3+2;
?>

Vljund lehel

Arvutus: 5

lesandeid

* Hangi vi tee selgeks enesele vimalus PHP-vimelises veebiserveris veebilehtede loomiseks. Windows-masinas sobib niteks XAMPP vi WAMP-nimeline komplekt.
* Koosta tervitav leht ja vaata seda veebiserveri kaudu
* Muuda lehe sisu ning uuendusnupu vajutuse jrel veendu muutuse kajastumises ka veebilehitsejas.
* Kivita konspektis olnud nide kahe arvu liitmise kohta.
* Muuda arve ja tehet, kontrolli tulemusi.

Muutuja, tingimuslause

Programmeerimiskeeltes on levinud vimalus andmeid muutuja ehk mrksna alla meelde jtta. PHPs algavad muutujate nimed dollarimrgiga. See vimaldab neid hiljem vabamalt teksti sisse panna. Lik

  $eesnimi="Juku";
  echo "Tere, $eesnimi!";

trkib aimatavalt vlja Tere, Juku.  Samuti siis 

  $eesnimi="Juku";
  echo "$eesnimi tuli hommikul kooli.<br />";

teatab, kes hommikul kooli tuli. Reavahetus <br /> lause lpus hoolitseb, et jrgnevat juttu alataks jrgmiselt realt.

Valiku jaoks on ksklus if. Tingimus pannakse marsulgude sisse. Kui tingimus vastab tele (praegusel juhul kinganumber on viksem kui nelikmmend), siis tidetakse jrgnevate looksulgude vahele paigutatud plokk. Sama lugu ka alumise tingimusega.

<?php
  $eesnimi="Juku";
  echo "$eesnimi tuli hommikul kooli.<br />";
  
  $kinganumber=37;
  if($kinganumber<40){
     echo "$eesnimi saab veel lasteosakonnast kingi<br />";
  }
  if($kinganumber>45){
     echo "Kodaniku $eesnimi kingad sobivad naelakastideks.";
  }
?>

Vljund ekraanil:

Juku tuli hommikul kooli.
Juku saab veel lasteosakonnast kingi 


lesandeid

Lisa muutuja perekonnanime tarbeks. Anna sinna vrtus ja kasuta seda lausetes.
Koosta eraldi leht, kus kirjas temperatuur. Vljasta, kas vesi on sellel temperatuuril vedel vi muutub jks.
Kellaaeg
Igal lehe avamisel nitamine on kindel kontroll selle kohta, et veebiserveris lehe loomiseks midagi toimub. Kuna samast serverist vidakse lehti vaadata mitmelt poolt, siis on tarvilik teada anda, millise ajavndi kellaaega soovitakse. Edasi juba ksklus date annab soovitud tulemuse. Sulgudes olevad thed nitavad, kuidas kellaaega vormistada. Tekst ikka jutumrkide vahel. Suur H palub tunde nidata 24-tunni ssteemis, i thendab minuteid ning s sekundeid. Koolonid seal vahel trkitakse lihtsalt vlja. 

<!doctype html>
<html>
  <head>
     <title>Kellaleht</title>
  </head>
  <body>
     <h1>Kellaaeg</h1>
	 <?php
	   date_default_timezone_set("Europe/Tallinn");
	   echo date("H:i:s");
	 ?>
  </body>
</html>

Vljund:

18:31:39 

lesandeid
Nita kellaajast vaid tunde ja minuteid
Nita vlja kuupev. Y thistab aastat, m kuud ning d peva. 


Tollikalkulaator
Nagu arvuti snastki vlja lugeda vib, on arvutamine selle masina juures thtis lesanne. Vahel saab arvutada olemasolevate andmete phjal. Kllalt sageli aga on vaja kasutajalt algandmete mramiseks sisestust. Andmete sisestamiseks on veebilehe jaoks olemas vorm ehk sisestuselementide komplekt. Form-elemendi action-atribuudina mratakse, kuhu aadressile andmed ttlemiseks saadetakse. Kui sihtkohaks on ksimrk, siis tuleb sisestus samale aadressile, kus vormgi avanes. 
<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Tollikalkulaator</h1>
     <form action="?">
	     Monitori diagonaal tollides:
		   <input type="text" name="tollid" />
		   <input type="submit" value="OK"  />
     </form>
  </body>
</html>



Andmete kasutamiseks tuleb nad kinni pda. Muutuja $_REQUEST kaudu saab vormi sisestatud vrtused ktte. 
	    echo $_REQUEST["tollid"]*2.54;
korrutab saabunud tollide arvu 2,54ga ning vljastab tulemuse sentimeetrites.

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Tollikalkulaator</h1>
     <form action="?">
	     Monitori diagonaal tollides:
		   <input type="text" name="tollid" />
		   <input type="submit" value="OK"  />
	 </form>
	 <?php
	    echo $_REQUEST["tollid"]*2.54;
	 ?>
  </body>
</html>

Tulemus nha pildina:



Eelmine nide oli kll vimalikult lihtne, aga mnigate puudustega. Lehe avamisel ilmub sinna salaprane mmargune null. Vastavalt serveri seadetele raskemal juhul isegi veateade andmete puudumise kohta. Seega on hea leht viisakamaks teha. Aitab jrgmine lik:

	   if(empty($_REQUEST["tollid"])){
	     echo "Ootan sisestust.";
	   } else {
	     echo $_REQUEST["tollid"]." tolli on ".
		    ($_REQUEST["tollid"]*2.54)." cm.";
	   }

Inimkeelne tlge. Kui saabuvaid tolle pole, siis trkitakse, et "Ootan sisestust.". Muul juhul trkitakse, et mitu tolli on mitu sentimeetrit. Kusjuures empty on selline ksklus, mis loeb thjaks nii parameetri tieliku puudumise (niteks lehe esmakordsel avamisel, kus keegi ei teagi tolle sisestada)  kui lihtsalt thjaks jnud teksti (mis juhtub siis, kui vajutada OK-nupule ilma tollide arvu sisestamata). Leht tervikuna.

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Tollikalkulaator</h1>
     <form action="?">
	     Monitori diagonaal tollides:
		   <input type="text" name="tollid" />
		   <input type="submit" value="OK"  />
	 </form>
	 <?php
	   if(empty($_REQUEST["tollid"])){
	     echo "Ootan sisestust.";
	   } else {
	     echo $_REQUEST["tollid"]." tolli on ".
		    ($_REQUEST["tollid"]*2.54)." cm.";
	   }
	 ?>
  </body>
</html>

Vastuses siis kigepealt oodatakse sisestust. 



Hiljem antakse viisakas vastus.

lesandeid
Koosta kalkulaator sentimeetritest tollide arvutamiseks. Jagamismrgiks on kaldkriips /.
Koosta kalkulaator, kus sisestus on meetrites. Vljastatakse, mitu kilomeetrit see on, mitu detsimeetrit, mitu sentimeetrit ning mitu millimeetrit see on.

Ostusumma arvutamine
Sisestatavaid vrtusi vib olla mitu. Nende kttesaamiseks tuleb nad panna eri nimedega tekstivljadesse. Jrgnevas nites on he vlja nimeks hind ja teise nimeks kogus. Neid kahte korrutades saadakse kokku ostusumma. 

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
Kauba tkihind:
		   <input type="text" name="hind" />
Ostetav kogus:
		   <input type="text" name="kogus" />
		   <input type="submit" value="OK"  />
	 </form>
	 <?php
	   if(empty($_REQUEST["hind"]) or empty($_REQUEST["kogus"])){
	     echo "Ootan sisestust.";
	   } else {
	     echo $_REQUEST["hind"]*$_REQUEST["kogus"];
	   }
	 ?>
  </body>
</html>

 

Valik rippmenst
Tekstivli on sisestuseks mugav teha. Kuna aga kasutaja pseb sinna kike sisestama, siis vib kergesti sisse sattuda ka sobimatut teksti. Kasutajale piiratud arvu valikute andmiseks sobib rippmen. Rippmen loob element tbist select. Elemendi nime jrgi saab endiselt PHP kaudu  kasutaja sisestuse ktte.
       <select name="hind">
	      <option value="">Vali kaup ...</option>
	      <option value="0.70">Leib</option>
	      <option value="0.60">Sai</option>
	      <option value="0.50">Piim</option>
	   </select>

Atribuudi value juurde kirjutatud vrtus lheb serverisse edasiseks ttluseks, tekst enne option-elemendi lppu jb nha kasutajale oma valiku tegemisel. Allpool saab arvutada endist moodi.

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
Kaup:
       <select name="hind">
	      <option value="">Vali kaup ...</option>
	      <option value="0.70">Leib</option>
	      <option value="0.60">Sai</option>
	      <option value="0.50">Piim</option>
	   </select>
Ostetav kogus:
		   <input type="text" name="kogus" />
		   <input type="submit" value="OK"  />
	 </form>
	 <?php
	   if(empty($_REQUEST["hind"]) or empty($_REQUEST["kogus"])){
	     echo "Ootan sisestust.";
	   } else {
	     echo $_REQUEST["hind"]*$_REQUEST["kogus"];
	   }
	 ?>
  </body>
</html>

Tulemus lehel:


lesandeid
Pane nide tle
Muuda tooteid ja hindu, katseta tulemust. 
Loo toodetest kaks rippmend eri nimedega. Nita, kui suur summa tuleb kummagi toote kohta eraldi ning kui palju kahe toote peale kokku.

Andmed massiivist
Paar harva muutuvat vrtust on hea veebilehe sisse kirjutada. Kui aga andmeid rohkem, neid kasutatakse mitmes kohas vi nad kipuvad sageli muutuma, siis on tavaline, et andmete kirjapaneku ja kasutamise kohad erinevad. Andmed on mugav kirja panna eraldi andmebaasi vi eraldi faili. Et seda pole veel pitud, siis piirdume hise massiiviga, mida ka vajadusel mitmel pool kasutada saab. 
Massiivi loomiseks sobib ksklus array(). Edasi vib sinna kshaaval andmed sisse panna. PHP lubab massiivi vtmena kasutada ka teksti. Kui kirjutatakse $kaubad["vorst"]="2.50", siis muutujaks on $kaubad, vtmeks "vorst" ning vrtuseks "2.50". 
   $kaubad=array();
   $kaubad["vorst"]="2.50";
   $kaubad["juust"]="3.00";
   $kaubad["kartul"]="0.45";

Prast vimalik tskliga andmed lbi kia. Ksk foreach vtab kshaaval ette kik vtme ja vrtuse paarid (mis siinsel juhul on $nimetus ja $hind) ning lubab nendega tskli keha sees (ehk looksulgude vahel) toimetada. Tulemusena trkitakse vlja kik valikud nnda, et nimetused jvad kasutajale silma ette valida. Hinnad aga saadetakse prast valiku tegemist ning sisestusnupule vajutamist serverisse.
          foreach($kaubad as $nimetus => $hind){
		     echo "<option value='$hind'>$nimetus</option>";
          }

Serveris tulemuse kokku arvutamine kib ikka endisel moel.

<?php
   $kaubad=array();
   $kaubad["vorst"]="2.50";
   $kaubad["juust"]="3.00";
   $kaubad["kartul"]="0.45";
?>
<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
      Kaup:
       <select name="hind">
	      <option value="">Vali kaup ...</option>
        <?php
          foreach($kaubad as $nimetus => $hind){
		     echo "<option value='$hind'>$nimetus</option>";
          }
        ?>		
       </select>
          Ostetav kogus:
		   <select name="kogus">
		      <option>Vali kogus</option>
		      <option>1</option>
		      <option>2</option>
		      <option>3</option>
		      <option>4</option>
		      <option>5</option>
		   </select>
		   <input type="submit" value="OK"  />
      </form>
      <?php
	   if(empty($_REQUEST["hind"]) or empty($_REQUEST["kogus"])){
	     echo "Ootan sisestust.";
	   } else {
	     echo $_REQUEST["hind"]*$_REQUEST["kogus"];
	   }
      ?>
  </body>
</html>



lesandeid
Pane nide tle, muuda andmeid, kontrolli tulemust.
Pane lehele kaks valikupaari kaupade ja koguste tarbeks. Nita kummagi paari tarbeks summa eraldi ning lppu kogusumma. 
Koosta massiiv, mille vtmeteks on liini bussipeatuste kaugused algpeatusest ning vrtusteks vastavate bussipeatuste nimed. Koosta samade andmetega kaks eri nimedega rippmend. Kasutaja valib kaks peatust, talle teatatakse, kui suur on nende peatuste vahe kilomeetrites. 
Lisaks eelmisele on kolmandas rippmens valik, kas tegemist on tava-, kiir- vi ekspressliiniga. Peidetud vrtustena kuuluvad sinna juurde kilomeetrihinnad. Arvestatakse kokku sidu maksumus.
Mobiilimalli jrgi veebilehestik
Nhtud kskude jrgi veebilehe sisu kokkupanekuga saab sna varsti hakkama. Phjalikum kujundamine aga nuab sageli suuremat svenemist, et taustade vrvid ja piltide laiused ilusti paika saaks. Kui tahta "oma ja head" kujundust saada, siis tuleb see tee ikka lbi kia. Vahel aga on mugav end vraste sulgedega ehtida ning kasutada mnd juba olemasolevat kujundusphja. Mrksna "HTML template" vi "CSS template" alt vib neid veebist hulgem leida ning mndagi neist lubatakse vabalt kasutada.
ksiku teate lugemine
Veebilehestikus on sisu ikka mitme lehe jagu. Kujundus aga viks kokkukuuluvatel lehtedel hesugune vi vhemasti sarnane olla. Enne suurema lehtedeploki hendamist vaatame nidet kahe failiga. hes neist lihtsalt paljas teade, mis tahetakse vajalikult lehele kuvada. Teine mninga kujundusega leht, kuhu siis teade sobivasse kohta sisse loetakse.

Teatefailis teade spordipeva kohta:

teade.txt
Spordipeva tttu sel esmaspeval tavalisi tunde ei toimu.
Kik pilased kohtuvad hommikul kell 9 palliplatsil.


Sisse lugeval lehel tavalise veebilehestiku andmed, lpus lihtsalt require-ksklus soovitud teate sisse vtmiseks. 

Fail:
sisselugemine.php

<!doctype html>
<html>
  <head>
     <title>Tunniplaani leht</title>
  </head>
  <body>
     <h1>Esmaspev</h1>
     <ol>
	   <li>Matemaatika</li>
	   <li>Ajalugu</li>
	   <li>Laulmine</li>
	 </ol>
	 <?php
	    require("teade.txt");
	 ?>
  </body>
</html> 

Leht paistab lehitsejas vlja jrgmiselt.



Nii on mugav vajalikku teadet lihtsalt tekstifaili kirjutada. Ning teate nitamiseks meldud lehed teavad, kust seda nha saab. 

Valmis kujundusmall mobiilile

Kui omal kujundamise soont ei ole vi lihtsalt tahtmine viisaka vlimusega lehestik kiiresti les saada, siis tasub ette vtta mni valmis kujundusmall. Nitena veti Gringo-nimeline mobiililehestiku phi.

http://mobifreaks.com/free-mobile-website-templates/gringo-mobi-free-mobile-website-template/

Tutvumiseks saab lehestiku lahti pakkida ning tema nitfaili ttamist imetleda. 



Oma tunniplaanirakenduse tarbeks teeme avalehest koopia ning kujundame sellest esmaspeva tundide leheklje, paigutades laserva viited ka teiste pevade jaoks meldud failidele. 

blankett.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Tunniplaan</title>
    <link href="kujundus.css" rel="stylesheet" type="text/css" />
</head>

<body>
	<div id="header">
        <div class="nav">
        	<ul>
                <li><a href="esmaspaev.php">E</a></li>
                <li><a href="teisipaev.php">T</a></li>
                <li><a href="kolmapaev.php">K</a></li>
                <li><a href="neljapaev.php">N</a></li>
                <li><a href="reede.php">R</a></li>
            </ul>
        </div>
    </div>
    <div class="clear"></div>
    <h2>Esmaspev</h2>
    <p>
      <ol>
	    <li>Matemaatika</li>
	    <li>Ajalugu</li>
	    <li>Laulmine</li>
	  </ol>
	</p>
        <div class="nav2">
			<p>Design by <a href="http://www.mobifreaks.com">Mobifreaks.com</a></p>
        </div>
</body>
</html>


Kujundusfailist jtame alles vaid ligud, mis on vajalikud he peva blanketti alles jnud elementide tarbeks. 

kujundus.css

@charset "utf-8";
/* CSS Document */
body{
	background:#ffffff;
	font-family:Arial, Helvetica, sans-serif;
	margin:0;
	padding:0;
	}
#header{
	margin:0 auto;
	}
.nav{
	font-size:14px; 
    background:#2d2d2d; 
    -moz-border-bottom-left-radius:6px;
    -webkit-border-bottom-left-radius:6px;
    border-bottom-left-radius:6px; 
    -moz-border-bottom-right-radius:6px;
    -webkit-border-bottom-right-radius:6px;
    border-bottom-right-radius:6px;
    margin:0 5px;
	}
.nav ul{
	list-style-type:none;
    margin:0;
	padding:0;
	}
.nav ul li{
	display:inline;
	margin:0;
	padding:0;
	}
.nav ul li:first-child{
	margin:0 0 0 5px;
	}
.nav ul li:last-child{
	margin:0 5px 0 0;
	}
.nav ul li a{
	display:inline-block;
	color:#f2f2f2;
	padding:10px;
	text-decoration:none;
	}
.nav ul li a:hover{
	color:#565656;
	}

h2{
	font-size:16px;
	font-weight:bold;
	color:#9b9b9b;
	border:#aaaaaa 1px dashed;
	padding:5px;
	margin:0 5px;
	}
p{
	text-align:left;
	font-size:12px;
	color:#2d2d2d;
	margin:5px;
	padding:0;
	line-height:20px;
	}
p a{
    color:#3c9ddb;
    text-decoration:none;
	}
p a:hover{
    color:#4d4444;
    }

.nav2{
	font-size:14px; 
    background:#2d2d2d; 
    -moz-border-top-left-radius:6px;
    -webkit-border-top-left-radius:6px;
    border-top-left-radius:6px; 
    -moz-border-top-right-radius:6px;
    -webkit-border-top-right-radius:6px;
    border-top-right-radius:6px;
    margin:0 5px;
	}
.nav2 p{
	text-align:center;
	color:#f2f2f2;
	margin:0 5px;
	padding:5px 0;
	}
.nav2 p a{
	display:inline-block;
	color:#88aa00;
	padding:5px;
	text-decoration:none;
	}
.nav2 p a:hover{
	color:#565656;
	}

.clear{
	clear:both;
	}

Need omavahel hendatuna kuvavad vlja he peva jaoks kujundatud leheklje.



Lehstiku juures soovime, et lehed oleksid sarnase kujundusega, kuid iga peva leht eraldi sellele pevale vastava sisuga. Korduvad osad eraldame pisesse ja jalusesse, igale pevale vastava osa selle ndalapeva nimelisse faili. Kigepealt pisefail. Sinna jb siis dokumendi algus, piseosa ning menviited. 

p2is.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Tunniplaan</title>
    <link href="kujundus.css" rel="stylesheet" type="text/css" />
</head>

<body>
	<div id="header">
        <div class="nav">
        	<ul>
                <li><a href="esmaspaev.php">E</a></li>
                <li><a href="teisipaev.php">T</a></li>
                <li><a href="kolmapaev.php">K</a></li>
                <li><a href="neljapaev.php">N</a></li>
                <li><a href="reede.php">R</a></li>
            </ul>
        </div>
    </div>
    <div class="clear"></div>


Jalusesse jb muu hulgas viisakuse prast viide lehemalli autorile.

jalus.php

<div class="nav2">
			<p>Design by <a href="http://www.mobifreaks.com">Mobifreaks.com</a></p>
        </div>
</body>
</html>

Edasi juba andmelehed pevade kaupa. lalt loetakse sisse pisefail, alt jalusefail. 

esmaspaev.php

<?php require("p2is.php"); ?>
    <h2>Esmaspev</h2>
    <p>
      <ol>
	    <li>Matemaatika</li>
	    <li>Ajalugu</li>
	    <li>Laulmine</li>
	  </ol>
	</p>
<?php require("jalus.php"); ?>

teisipaev.php

<?php require("p2is.php"); ?>
    <h2>Teisipev</h2>
    <p>
      <ol>
	    <li>Emakeel</li>
	    <li>Matemaatika</li>
	    <li>Tpetus</li>
	  </ol>
	</p>
<?php require("jalus.php"); ?>



kolmapaev.php

<?php require("p2is.php"); ?>
    <h2>Kolmapev</h2>
    <p>
      <ol>
	    <li>Matemaatika</li>
	    <li>Emakeel</li>
	    <li>Kehaline kasvatus</li>
	  </ol>
	</p>
<?php require("jalus.php"); ?>

neljapaev.php
<?php require("p2is.php"); ?>
    <h2>Neljapev</h2>
    <p>
      <ol>
	    <li>Emakeel</li>
	    <li>Ajalugu</li>
	    <li>Matemaatika</li>
	  </ol>
	</p>
<?php require("jalus.php"); ?>

reede.php

<?php require("p2is.php"); ?>
    <h2>Reede</h2>
    <p>
      <ol>
	    <li>Laulmine</li>
	    <li>Ajalugu</li>
	  </ol>
	</p>
<?php require("jalus.php"); ?>



Tulemusena saab liigelda pevade lehtede vahel ning htsena kujundatud lehestikku kasutada. 

lesandeid
Koosta eraldi tekstifail teate jaoks ning tekstifail lehe tegija nimega. Loo uus veebileht, kus lal on pealkiri "Vrske teade", lehe keskel failist sisseloetud teade ise  ning all paremal lehe tegija sisseloetud andmed.
Otsi veebist mni valmiskujundusega lehemall. Pane oma masinasse/serverisse tle. Kujunda leht he anekdoodi nitamiseks. Pane lehe klge men viitega mitmele (veel olematule) anektoodilehele. Jaga eraldi failidesse piseosa, sisu ja jalus. Loo mitme nalja jaoks eraldi sisu. Kujunda kokku hiseks lehestikuks.

Andmebaasitabeli veebivljund
Kord valmis tehtud veebilehti saab mugavasti veebist prast vaadata. Kui aga tahta lehtede sisu vahetevahel muuta, vi siis vastavalt kasutaja soovidele mitmesuguses jrjestuses vi moel kuvada - sellisel puhul aitavad andmebaaside vimalused lehestiku loomisele mrgatavalt kaasa. 
Enamikes andmebaasides paiknevad andmed relatsiooniliselt ehk tabelite kujul. Lihtsamal juhul on veebirakenduse juures tegemist he andmetabeliga. PHPga koos kasutatakse sageli MySQLi nimelist andmebaasiprogrammi, sest nad on meldud suhteliselt sarnasele sihtgrupile. Kokku mned gigabaidid andmeid salvestatuna ning mned pringud sekundis on ssteemile ldiselt jukohased. Mahtude kasvamisel kordades aga tasub juba phjalikuma serveri optimeerimise vi muude vahendite peale melda. 
Harjutamiseks saab serveri mugavasti psti WAMP vi XAMPP-nimelise komplekti abil. Andmebaasi kasutajaliidese eest aitab sealjuures hoolitseda PhpMyAdmin. Samas enamasti vimalik suhtlus ka ksurealt.
SQL
Andmebaasiga suhtlemiseks kasutatakse SQL-keelt. Selles leiduvad ksud andmetabelite loomiseks, sinna andmete lisamiseks, andmete ksimiseks, muutmiseks ja kustutamiseks. 
Tabeli loomiseks ksklus CREATE TABLE. Ksu nimele jrgneb tabeli nimi (praegusel juhul lehed). Ning siis sulgudes komadega eraldatuna tulpade nimed ning nende parameetrid. Iga tabeli esimeseks tulbaks on ldjuhul id - identifikaator, mille abil hiljem ridu eristada ja neile viidata. Parameetrid vivad lihtsamate rakenduste puhul enamasti samaks jda. Selgitused:

INT - tisarv
NOT NULL - vrtus ei tohi puududa
AUTO_INCREMENT - server arvutab lisamisel ise juurde sobiva seni veel kasutamata vrtuse
PRIMARY KEY - selle tulba vrtust kasutatakse edaspidi tabeli vastavale reale viitamisel (niteks muutmise vi kustutamise juures).

Tulp pealkiri siin nites tbiga VARCHAR(50) ehk siis tekst pikkusega kuni 50 thte. Sisu tbiks TEXT, mis thendab, et pikkust ei piirata.

Kokku siis lause jrgmine, mis tasub valmis kirjutada ning MySQLi ksuviibale vi PHPMyAdmini aknasse kopeerida:


CREATE TABLE lehed(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  pealkiri VARCHAR(50),
  sisu TEXT
);


Kui vastuseks tuli Query OK, siis jrelikult ettevtmine nnestus. Muidu tuleb veateateid uurida ja uuesti proovida.

Andmete lisamiseks on loodud ksklus INSERT INTO. Jrgneb tabeli nimi, siis sulgudes tulpade nimed, kuhu lisatavad andmed tulevad. Edasi sna VALUES ning sulgude sisse komadega eraldatult igale tulbale vastav vrtus. Tekstilised andmed paigutatakse lakomade vahele. 

INSERT INTO lehed (pealkiri, sisu) VALUES ('Ilmateade', 'Kuiv ilm');

Tahtes rohkem andmeid lisada, tuleb INSERT lauset lihtsalt mitu korda kivitada, igal korral eraldi andmed sisse pannes. 

mysql> INSERT INTO lehed (pealkiri, sisu) VALUES ('Korvpall', 'Treening reedel kell 18');
Query OK, 1 row affected (0.00 sec)

Kui mned sees, siis on hea vaadata ja kontrollida, et mis sinna tpsemalt sai. Andmete ksimiseks on SQLis loodud ksklus SELECT. Trn thendab, et kuvatakse kikide olemasolevate tulpade andmed. Snale FROM jrgneb tabeli nimi ning ksu lppu kivitamiseks semikoolon. Lehtede tabeli sisu tuleb siis vlja jrgnevalt.

mysql> SELECT * FROM lehed;
+----+-----------+-------------------------+
| id | pealkiri  | sisu                    |
+----+-----------+-------------------------+
|  1 | Ilmateade | Kuiv ilm                |
|  2 | Korvpall  | Treening reedel kell 18 |
+----+-----------+-------------------------+
2 rows in set (0.00 sec)

Nagu nha, id-vrtused on automaatselt ise pandud, kuna vastaval tulbal on juures omadus AUTO_INCREMENT.

Tahtes andmeid veel juurde panna, tuleb taas kivitada INSERT-lause sobivate andmetega. Teksti sisestamisele vastab kige korrasoleku puhul MySQL taas "Query OK", lisades sinna vahel ka mjutatud ridade arvu ja kulunud aja - thtis pigem suuremate andmestike korral.

mysql> INSERT INTO lehed (pealkiri, sisu) VALUES ('Matemaatika', 'Homme tunnikontroll');
Query OK, 1 row affected (0.00 sec)

SQLi selecti abil saab andmeid kergesti sobivas jrjekorras ja kujul vlja ksida. Kui lause lppu lisatakse ORDER BY koos vastava tulba nimega, siis tulevad andmed vlja selle tulba jrgi thestiku jrjekorda panduna (kui vastav tulp oli tekstitulp).


mysql> SELECT * FROM lehed ORDER BY sisu;
+----+-------------+-------------------------+
| id | pealkiri    | sisu                    |
+----+-------------+-------------------------+
|  3 | Matemaatika | Homme tunnikontroll     |
|  1 | Ilmateade   | Kuiv ilm                |
|  2 | Korvpall    | Treening reedel kell 18 |
+----+-------------+-------------------------+
3 rows in set (0.00 sec)

Saab ksida ka ainult he rea vrtusi:

mysql> SELECT pealkiri, sisu FROM lehed WHERE id=3;
+-------------+---------------------+
| pealkiri    | sisu                |
+-------------+---------------------+
| Matemaatika | Homme tunnikontroll |
+-------------+---------------------+

Kui leitakse, et rida pole enam vajalik, siis selle kustutamiseks sobib ksklus DELETE, kus soovitavalt id jrgi mratakse ra, milline rida kustutada. 

mysql> DELETE FROM lehed WHERE id=3;
Query OK, 1 row affected (0.00 sec)

Uue SELECT-pringuga saab kontrollida, mis siis sinna tegelikult alles ji. Kui nd juhtutaks INSERT-lausega taas andmeid lisama, siis sellele reale enam id vrtust 3 vlja ei antaks - vlistamaks niteks olukorda, kus vanale teatele pandud kommentaarid satuksid uue klge. Primaarvtmetulba id vrtuseks tuleks uue rea lisamisel vhemasti 4.

mysql> SELECT * FROM lehed;
+----+-----------+-------------------------+
| id | pealkiri  | sisu                    |
+----+-----------+-------------------------+
|  1 | Ilmateade | Kuiv ilm                |
|  2 | Korvpall  | Treening reedel kell 18 |
+----+-----------+-------------------------+

lesandeid
Tee nide lbi, lisa veel mned read ja kustuta neid.
Loo tabel kassid tulpadega id, kassinimi, toon
Lisa paar kassi
Vljasta kassid
Vljasta kassid toonide jrjekorras
Kustuta ks kass

Tabeli sisu vaatamine

Andmebaasitabelis kannatab andmeid hoida ning SQL-kskude vi mne haldusliidese kaudu saab neid ka sinna lisada vi sealt vaadata. Tavakasutaja aga eeldab, et ta neb vi sisestab veebilehitseja aknast just seda mis talle vaja ning ei taha ega jua end koormata mitmesuguste tehniliste trikkidega. Veebirakenduse loojate ks thtis lesanne ongi andmed sobival kujul kasutajale ette nidata ning samuti veebilehtedel tehtud muutused prast tabelites jrgmiste kasutuskordade tarbeks talletada. 
Sarnaselt kui ise SQL-ksklusi andmebaasi ksureale kirjutades nnestub andmeid lisada ja ksida, saab ka PHP andmebaasiga SQL-kskude kaudu sidet pidada. heks vimaluseks kske veebilehe koodist andmebaasini vahendada on teek nimega MySQL Improved. Nii nagu ksitsi andmebaasiga suheldes peab teadma, kus masinas baas asub, millise kasutajanime ja parooliga sinna ligi pseb ning millise nimega baasiga on tegemist - samad andmed vaja teada ka PHP poolt hendust luues. Kui PHP ja MySQL asuvad samas masinas, siis sobib baasiserveri nimeks localhost. Siin nites pruugin kasutajanimeks ja parooliks juku ning kala. Ja baasi nimeks siin jukubaas2. Eks oma lahendust luues tule siis need vrtused sisse kirjutada, mis parajasti pruukida on vi teenusepakkujalt antakse. XAMPP vaikimisi seadete korral sobib niteks serveriks "localhost", kasutajaks "root", parooliks thi tekst "" ning katsetada saab baasis nimega "test". Avalikuks vljapanekuks pole selline komplekt kll viisakas, aga oma arvutis toimetamiseks kib kll.

Edasi tuleb andmete kttesaamiseks mitu sammu ette vtta. Mne vahendiga saab veidi lihtsamalt, aga MySQL Improved teegi eeliseks on, et kui andmed viisakalt ette valmistada ning andmete SQL-kskudesse panekuks kasutada eelkompileeritud ksklusi (prepared statement), siis pole karta, et pahatahtlikke sisestuste abil veebilehtedelt saaks suuremat kurja teha. Muidu on aastaid olnud probleemiks, et kavalad veebilehtedel sisse kirjutatud laused vivad serveris kima minna ning pahandust tekitada. Lihtsamal juhul oma rakenduse andmeid kustutades vi muutes, kuid keerukamatel juhtudel vivad lgi alla sattuda ka teiste rakenduste andmed vi lausa vlised serverid, kui kord sisse murtud masinat edasiste rnnakute alusena kasutatakse. Seetttu siis siin matejalis andmete vahendajaks MySQL Improved tpi objekt, mida luuakse ksuga new mysqli ja antakse vajalikud hendumisparameetrid kaasa. 
Jrgneva prepare-lausega palutakse $yhendus-nimelises muutuja kaudu kttesaadaval mysqli-objektil ette valmistada SQL-lause lehtede andmetabelist id, pealkirja ja sisu ksimiseks. Edasine bind_result mrab, kuhu muutujatesse saadud andmed pannakse. Andmebaasiga suhtlevad vahendid tehakse nnda, et nad suudaksid toimida ka vga suurte andmekoguste korral ning ei loeks ilmaasjata suuremat kogust vrtusi mllu. Niteks miljon rida on andmebaasis hoidmise jaoks tiesti klbulik kogus. Korraga mllu lugemisel vtab miljon kirjet aga hulga megabaite ning sealt hiljem midagi vajalikku ktte saada vib tlikas olla. 
Edasi tulev execute() paneb kskluse baasis kima. nnetusena ei hoiatata, kui see lause unustatakse, aga lihtsalt andmeid ei saa ktte. 
Vahepeal on mningane osa HTML-i lehe kujunduse kuvamiseks. Baasis tulevate andmetega hakatakse tegelema siis, kui saabub tskkel while($kask->fetch()). Iga fetch-ksklus tstab pringu vastuste juurest he rea bind_param-ksuga mratud muutujatesse ning nendega vib tsklikringi jooksul vajalikud toimetused ette vtta. Nnda on korraga muutujate kaudu mlus vaid he andmerea ehk lehe andmed ning rakendus ei vta serveri mlu kuigivrd. Praegu trkitakse pealkiri lihtsalt <h2> ja </h2> vahele ning nidatakse seetttu suurema ja rasvasena vlja. Sisu tuleb tavalise ligu ehk div-ina. Ksk htmlspecialchars aitab hoolitseda, et kogemata andmete hulka sattunud erismbolid (peamiselt < ja >) ei tekitaks lehe lesehituse juures segadust. 
Lehe vljastuse lppemisel on viisakas andmebaasihendus kinni panna. 
Lehti vljastav kood tervikuna:

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas2");
  $kask=$yhendus->prepare("SELECT id, pealkiri, sisu FROM lehed");
  $kask->bind_result($id, $pealkiri, $sisu);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
     <title>Teated lehel</title>
  </head>
  <body>
     <h1>Teadete loetelu</h1>
     <?php
       while($kask->fetch()){
         echo "<h2>".htmlspecialchars($pealkiri)."</h2>";
         echo "<div>".htmlspecialchars($sisu)."</div>";
       }
     ?>
  </body>
</html>
<?php
  $yhendus->close();
?>

Ning pilt valminud veebilehest:


lesandeid

Tee nide lbi
Loo/otsi les tabel kassid (id, kassinimi, toon). Nita kasside andmed veebilehele.
Pane kasside toonideks inglisekeelsed vrvinimetused
Nita iga kass lehel vastavat vrvi.


Teadete valik

Mnekmne kassi andmed mahuvad hele lehele ra. Aga seda vaid juhul, kui nidatakse vaid kassi nime ja vrvi. Kui juba lisada omaniku andmed ning veidigi suurem kassi pilt, siis veidigi viksema ekraani peal on mugav juba kasse hekaupa vaadata. Jrgnevalt uurimegi, kuidas selliseid lehti koostada, kus vimalik tabeli he rea andmeid eraldi vlja tuua. 

sna mugav on lehele andmeid saata aadressiriba kaudu. Kui kirjutan failinimele taha ksimrgi ning sinna taha id=2 ehk siis nt. teadetevalik.php?id=2 , siis selle vrtuse 2 saan programmis ksida muutujast $_REQUEST["id"]. Vi kui tahan kontrollida, kas failinime jrel saadeti parameeter nimega id, siis kontrollin          if(isSet($_REQUEST["id"]))

Nnda ka jrgmises ligus. Kui parameeter saadeti, siis jrelikult soovitakse vaadata he konkreetse lehe andmeid, mida id nitab. Kui aga parameetrit pole, siis inimene jrelikult ei tea veel lehte selle numbri jrele ksida ning tal on phjust pigem loetelust omale sobiv valida. 

Kui id on olemas, siis saab selle jrgi ksida lehe muud andmed - praeguses nites pealkirja ja sisu. Tavalise SQL-lause juures saab he rea ksimiseks panna WHERE-tingimuse juurde vastava piirangu. Nt  SELECT id, pealkiri, sisu FROM lehed WHERE id=2;

Kuna siin veebirakenduses tahetakse vastavalt kasutaja valikult nha erinevaid lehti, siis peab saama seda arvu muuta. MySQL Improved teek lubab muutuva vrtuse kohale panna ksimrgi ning prast selle vrtuse bind_param-ksu abil asendada. Hiljem tulev rida

            $kask->bind_param("i", $_REQUEST["id"]); 

teatab, et parameetri tbiks on tisarv ehk integer ehk tht i. Ning parameeter saab oma vrtuse muutujast $_REQUEST["id"]. Edasi juba andmete kttesaamine bind_result kaudu mratud muutujatesse nagu ennegi. Eelnevas nites vis andmeid tulla palju ning seetttu tuli nad while-tskli kaudu vlja kuvada. he id jrgi ksides saab ktte ainult he rea, seetttu piisab selle kttesaamiseks hest fetch-ksklusest. Kas ksimine nnestus, seda annab teada if-lause. Andmeid ei saa ksides niteks juhul, kui keegi on aadressirea kaudu sisestanud olematu lehe id-numbri. Muul juhul saab pealkirja ja sisu ilusti ktte ning neid vib lehel kuvada.

         if(isSet($_REQUEST["id"])){
            $kask=$yhendus->prepare("SELECT id, pealkiri, sisu FROM lehed
               WHERE id=?");
               //Kysim2rgi asemele pannakse aadressiribalt tulnud id,
               //eeldatakse, et ta on tyybist integer (i). 
               //(double - d, string - s)
            $kask->bind_param("i", $_REQUEST["id"]); 
            $kask->bind_result($id, $pealkiri, $sisu);
            $kask->execute();
            if($kask->fetch()){
              echo "<h2>".htmlspecialchars($pealkiri)."</h2>";
              echo htmlspecialchars($sisu);
            } else {
              echo "Vigased andmed.";
            }
         } else {
           echo "Tere tulemast avalehele! Vali men&uuml;&uuml;st sobiv teema.";
         }

Tavakasutaja ei pea peast lehtede numbreid teadma. Tema pigem vaatab neid menst ning valib sobiva. Edasi juba saadetakse vastava teate id-number aadressiriba kaudu lehele, leht avaneb uuesti ning nitab ksitud teate sisu. Men kokku saamiseks sobib jrgnev koodilik. Kui viites (a href) jtta faili nime kohale ksimrk, siis avatakse sama fail ilma, et peaks selle faili nime teadma. 

          <?php
             $kask=$yhendus->prepare("SELECT id, pealkiri FROM lehed");
             $kask->bind_result($id, $pealkiri);
             $kask->execute();
             while($kask->fetch()){
               echo "<li><a href='?id=$id'>".
                     htmlspecialchars($pealkiri)."</a></li>";
             }
          ?>

Edasi kirjete kaupa nitav kood tervikuna. 

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas2");
?>
<!doctype html>
<html>
  <head>
    <title>Teated lehel</title>
    <style type="text/css">
       #menyykiht{
         float: left;
         padding-right: 30px;
       }
       #sisukiht{
         float:left;
       }
       #jalusekiht{
         clear: left;
       }
    </style>
	<meta charset="utf-8" />
  </head>
  <body>
    <div id="menyykiht">
        <h2>Teated</h2>
        <ul>
          <?php
             $kask=$yhendus->prepare("SELECT id, pealkiri FROM lehed");
             $kask->bind_result($id, $pealkiri);
             $kask->execute();
             while($kask->fetch()){
               echo "<li><a href='?id=$id'>".
                     htmlspecialchars($pealkiri)."</a></li>";
             }
          ?>
        </ul>
    </div>
    <div id="sisukiht">
       <?php
         if(isSet($_REQUEST["id"])){
            $kask=$yhendus->prepare("SELECT id, pealkiri, sisu FROM lehed
               WHERE id=?");
               //Kysim2rgi asemele pannakse aadressiribalt tulnud id,
               //eeldatakse, et ta on tyybist integer (i). 
               //(double - d, string - s)
            $kask->bind_param("i", $_REQUEST["id"]); 
            $kask->bind_result($id, $pealkiri, $sisu);
            $kask->execute();
            if($kask->fetch()){
              echo "<h2>".htmlspecialchars($pealkiri)."</h2>";
              echo htmlspecialchars($sisu);
            } else {
              echo "Vigased andmed.";
            }
         } else {
           echo "Tere tulemast avalehele! Vali men&uuml;&uuml;st sobiv teema.";
         }
       ?>
    </div>
    <div id="jalusekiht">
       Lehe tegi Jaagup
    </div>
  </body>
</html>
<?php
  $yhendus->close();
?>


Veebilehel kigepealt nha men ning soovitus teema valida



Edasi juba tuleb vastava teema id aadressiribale ning neb valitud pealkirja all peituvat sisu.




lesandeid

Tee nide lbi
Loo tabel koerte kohta (id, koeranimi, kirjeldus, pildiaadress)
Sisesta andmed mnede koerte kohta, pildid otsi veebist
Loo lehestik, kus vasakus servas nha koerte nimed. Nimele vajutades kuvatakse lehel suurelt see koer koos pildi ja kirjeldusega.


Andmete lisamine ja kustutamine

Veebi kaudu on andmeid ilus vaadata. Ainult, et sellisena saab lehed ka ilma serveripoolse programmeerimistoeta tle panna. Vajadusel saab kindla arvu lehti kopeerida ning viited vastavalt sttida ning vibki andmeid soovitult lugeda. Kui aga tahta, et kasutajapoolsed andmed ka kuidagi serverisse talletuks ning teised neid lugeda saaks - seda juba naljalt ilma serveripoolse programmita teha ei nnestu. Muidugi kaasnevad serveris talletamisega ka omad mured: keegi vib hooletusest vi pahatahtlikkusest sinna hulgem andmeid saata ning sellega serveris oleva andmebaasi tis kirjutada vi lihtsalt kahtlaste postitustega suure hulga segadust tekitada. Aga hea ja halb kivad ksikes ning mugavuse nimel tuleb vahel ka mnevrra riskida. Abilisteks hiljem varukoopiad, registreerimised, modereerimised ja muud tiendused. 

Andmete lisamiseks tuleb need kigepealt kasutajalt ktte saada. Selleks sobib sisestusvorm - olgu siis pidevalt lehel nhtaval vi eraldi viite peale nidatav. Sisestusvormist tulevad andmed saadetakse salvestamiseks serverisse. Siinses nites toimib kik sama faili kaudu, kuid iseenesest vib toimetuse jaoks ka eraldi teine vike fail loodud olla. Prast andmete salvestamist on kasulik leht uuesti edasi suunata - kas vi samale lehele, aga nnda, et inimese sisestatud andmed uuesti kaasa ei tuleks - sellisel juhul pole karta, et vrskendusnupu vajutamine andmeid korduvalt salvestama hakkab. 
Lisamisvormi nhtavaks muutumiseks loodi viide parameetriga lisamine.
        <a href='?lisamine=jah'>Lisa ...</a>

Kui selline parameeter juab serverisse, siis nidatakse kasutajale thjad lahtrid, kuhu oma andmed kirja panna. Definition list (dl) koos nimetuse (definition term, dt) ning sisuga (dd, definition data) vimaldab mugavalt sisestuselemendid koos seletustega vlja kuvada. Kaasas on ka varjatud element nimega uusleht, mille abil siis hiljem kontrollida, et kasutaja on uue lehe andmed saatnud. Andmete teele panekuks veebis nupp tbist submit.

         if(isSet($_REQUEST["lisamine"])){
           ?>
             <form action='?'>
              <input type="hidden" name="uusleht" value="jah" />
              <h2>Uue teate lisamine</h2>
              <dl>
                <dt>Pealkiri:</dt>
                <dd>
                 <input type="text" name="pealkiri" />
                </dd>
                <dt>Teate sisu:</dt>
                <dd>
                  <textarea rows="20" name="sisu"></textarea>
                </dd>
               </dl>
               <input type="submit" value="sisesta">
             </form>
           <?php
         }
       ?>

Nupule vajutades avatakse leht uuesti. Kaasa liiguvad eelnevalt vljadesse sisestatud andmed. Eelnevalt varjatult kaasa pandud parameeter nimega uusleht nitab, et nd on paras aeg saabuvad andmed tabelisse kirjutada. Andmete lisamiseks tabelisse on INSERT-lause. Lisatavate vrtuste kohta tulevad algul ksimrgid, bind_param-ksu abil paigutatakse nende asemele tegelikud vrtused. Tekst "ss" bind_param-ksu esimese parameetrina nitab, et mlemad saabuvad vrtused on stringi ehk teksti tpi. Vrtusteks on siis pealkiri ja sisu, mis $_REQUEST-muutujast sisse loetakse. Vltimaks lehe korduslaadimisel uuesti salvestamist, tasub Location-piseksuga lehe avamine edasi suunata - kas vi samale lehele ($_SERVER[PHP_SELF]). Viisakasti siis andmebaasihendus ka sealjuures kinni ning lehe avamisele lpp - exit();

  if(isSet($_REQUEST["uusleht"])){
    $kask=$yhendus->prepare("INSERT INTO lehed (pealkiri, sisu) VALUES (?, ?)");
    $kask->bind_param("ss", $_REQUEST["pealkiri"], $_REQUEST["sisu"]);
    $kask->execute();
    header("Location: $_SERVER[PHP_SELF]");
    $yhendus->close();
    exit();
  }

Nites lisati ka kustutamise moodus. Eraldi vaatamise lehel sai juurde kustutamise viide, kus aadressiga suunatakse samale lehele ning antakse kaasa kustutusid. 

              echo "<h2>".htmlspecialchars($pealkiri)."</h2>";
              echo htmlspecialchars($sisu);
              echo "<br /><a href='?kustutusid=$id'>kustuta</a>";

Lehe pises kustutusid saabumisel kivitatakse DELETE-lause koos etteantud kirje numbriga. 

  if(isSet($_REQUEST["kustutusid"])){
    $kask=$yhendus->prepare("DELETE FROM lehed WHERE id=?");
    $kask->bind_param("i", $_REQUEST["kustutusid"]);
    $kask->execute();    
  }

Lisamis- ja kustutusvimeline kood tervikuna.


<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas2");
  if(isSet($_REQUEST["uusleht"])){
    $kask=$yhendus->prepare("INSERT INTO lehed (pealkiri, sisu) VALUES (?, ?)");
    $kask->bind_param("ss", $_REQUEST["pealkiri"], $_REQUEST["sisu"]);
    $kask->execute();
    header("Location: $_SERVER[PHP_SELF]");
    $yhendus->close();
    exit();
  }
  if(isSet($_REQUEST["kustutusid"])){
    $kask=$yhendus->prepare("DELETE FROM lehed WHERE id=?");
    $kask->bind_param("i", $_REQUEST["kustutusid"]);
    $kask->execute();    
  }
?>
<!doctype html>
<html>
  <head>
    <title>Teated lehel</title>
    <style type="text/css">
       #menyykiht{
         float: left;
         padding-right: 30px;
       }
       #sisukiht{
         float:left;
       }
       #jalusekiht{
         clear: left;
       }
    </style>
  </head>
  <body>
    <div id="menyykiht">
        <h2>Teated</h2>
        <ul>
          <?php
             $kask=$yhendus->prepare("SELECT id, pealkiri FROM lehed");
             $kask->bind_result($id, $pealkiri);
             $kask->execute();
             while($kask->fetch()){
               echo "<li><a href='?id=$id'>".
                          htmlspecialchars($pealkiri)."</a></li>";
             }
          ?>
        </ul>
        <a href='?lisamine=jah'>Lisa ...</a>
    </div>
    <div id="sisukiht">
       <?php
         if(isSet($_REQUEST["id"])){
            $kask=$yhendus->prepare("SELECT id, pealkiri, sisu FROM lehed
               WHERE id=?");
            $kask->bind_param("i", $_REQUEST["id"]); 
            $kask->bind_result($id, $pealkiri, $sisu);
            $kask->execute();
            if($kask->fetch()){
              echo "<h2>".htmlspecialchars($pealkiri)."</h2>";
              echo htmlspecialchars($sisu);
              echo "<br /><a href='?kustutusid=$id'>kustuta</a>";
            } else {
              echo "Vigased andmed.";
            }
         } 
         if(isSet($_REQUEST["lisamine"])){
           ?>
             <form action='?'>
              <input type="hidden" name="uusleht" value="jah" />
              <h2>Uue teate lisamine</h2>
              <dl>
                <dt>Pealkiri:</dt>
                <dd>
                 <input type="text" name="pealkiri" />
                </dd>
                <dt>Teate sisu:</dt>
                <dd>
                  <textarea rows="20" name="sisu"></textarea>
                </dd>
               </dl>
               <input type="submit" value="sisesta">
             </form>
           <?php
         }
       ?>
    </div>
    <div id="jalusekiht">
       Lehe tegi Jaagup
    </div>
  </body>
</html>
<?php
  $yhendus->close();
?>


Lehel algul nha teadete loetelu.



Pealkirjale vajutades neb vastava kirje andmeid. Kustutusviite kaudu saab kirjest lahti.



Nii pole seda teadet ka enam mens nha. Paistab lisamisviide uute andmete sisestamiseks.


Lisamisviite kaudu kuvatakse lisamisvorm
Edasi tuleb need andmed sisse kirjutada. 
 
Prast sisestamist vibki mens uud teadet imetleda. 


lesandeid
Tee nide lbi
Loo/otsi koerte tabel (id, koeranimi, kirjeldus, pildiaadress)
Vimalda koeri veebi kaudu lisada, vaadata ja kustutada

Peohtu registreerimisvorm
Koosta veebileht peokuulutusega
Loo sinna juurde veebileht, kus kasutaja saab oma eesnime, perekonnanime ja elektronposti sisestada. Andmed talletatakse tabelisse (ei nidata veebilehel).
Loo eraldi administraatorileht, kus saab sisestusi nha (sisselogimist pole vaja)
Administraator saab vigaseid sisestusi ka kustutada
Loo teine andmetabel, kus kirjas peo etteasted ja sndmused koos arvatava kellaajaga. Vljasta andmed kellaaegade jrjekorras eraldi veebilehele. Kujunda veebileht koos eelmistega htseks lehekstikuks.
Loo eraldi administraatorileht peo sndmuste lisamiseks ja kustutamiseks. 



Andmete muutmine, laulude lehestik

Lisamise ja kustutamisega saab kllalt palju hekordseid registreerimisi ja vahetamisi korda ajada. Phjalikumate rakenduste juures aga kivad sama andmerea eri tulbad eri kasutajate juurest lbi ning siis tuleb ka rea andmete muutmisele melda nii, et osa vrtusi silib, mned uuenevad. Siin nitena koostame laulude lehestiku, kus haldur saab neid tabelisse lisada, kasutajad lauludele punkte ja kommentaare jagada ning halduril prast vimalik mrata, millised laulud parajasti vlja paistavad ja millised mitte.  Ning kik see lehestik ehitatakse he andmetabeli peale, kus siis eri veerugude vrtusi saab sobivalt kasutada. 

Sellise lehestiku baasipooleks piisab, kui laulude andmed on andmebaasis, tabelis nimega 
 laulud(id, pealkiri, punktid, lisamisaeg, kommentaarid, avalik)
 
SQL-lause tabeli loomiseks:

CREATE TABLE laulud(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  pealkiri VARCHAR(50),
  punktid INT DEFAULT 0,
  lisamisaeg DATETIME,
  kommentaarid TEXT,
  avalik INT DEFAULT 1
);

Sna DEFAULT tulba taga mrab vaikimisi vrtuse - ehk kui laul luuakse, siis pole tal veel htki punkti, aga samas on avalik. Lisamisaja andmetp DATETIME nitab, et heaegselt hoitakse meeles kuupev ja kellaaeg.

Lehestiku koostamise saab jagada suuremateks alamlesanneteks:

* Looge veebileht laulude lisamiseks andmebaasi.
  Sisestada on vaja vaid pealkiri, tulemust neb vaid baasist
  
* Looge veebileht lauludele plusspunkti andmiseks. 
  Iga laulu taga neb talle antud punkte.

* Looge veebileht, mis nitaks vaid avalikke laule 
Selle juures aitab SQL-i poolest pring laulu nr 1 nitel
  SELECT pealkiri FROM laulud WHERE avalik=1
  
* Muutke andmebaasi ksklusega mni laul peidetuks
Tarvilik SQL-ksklus sealjuures
  UPDATE laulud SET avalik=0 WHERE id=1
  Veenduge, et seda laulu avalike laulude lehele ei nhe
  
* Koosta haldusleht, mille abil on vimalik laule peita ja taas avalikuks muuta.

Uue laulu lisamine
Lisamiseks on vaja lisamisvormi ja salvestuskohta. Kui lalpoolses nites kippus mnevrra segadust tekitama, et lisamisvorm avanes vaid vastaval viitel vajutades, siis siin ptud lisamine vimalikult lihtsaks teha. Lisamislahter on kohe lehe avamisel olemas. Ning samal lehel ptakse pealkiri kinni ja lisatakse andmed tabelisse. Lisamisaja vrtuseks NOW() annab serverikella praeguse aja. Kommentaariks lisatakse algul thi tekst, prast saab sinna kasutajate juttu juurde paigutada.

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(!empty($_REQUEST["uuepealkiri"])){
     $kask=$yhendus->prepare(
	  "INSERT INTO laulud(pealkiri, lisamisaeg, kommentaarid) VALUES(?, NOW(), ' ')");
	 $kask->bind_param("s", $_REQUEST["uuepealkiri"]);
	 $kask->execute();
	 echo $yhendus->error;
	 header("Location: $_SERVER[PHP_SELF]");
	 $yhendus->close();
	 exit();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
	<form action="?">
	   Uue laulu pealkiri: 
	     <input type="text" name="uuepealkiri" />
		 <input type="submit" value="Lisa laul" />
	</form>
  </body>
</html>
<?php
  $yhendus->close();
?>


Kigepealt ilmub pealkirja lisamise lahter

Sinna vib kirjutada uue laulu pealkirja, vajutada lisamisnuppu ning ongi see laul tabelis kirjas. 


lesandeid
Pane nide tle.
Koosta tabel koolipeole kutsutava ansambli valimiseks ja hletamiseks. 
Tabel ansamblid(id, ansamblinimi, punktid, kommentaarid, avalik, otsus). Kommentaarid tbist TEXT, otsus VARCHAR(255).
Koosta leht ansambli nime lisamiseks tabelisse. Kontrolli lehe td.


Lauludele punktide lisamine
Punktide lisamis leht koosneb kahest osast. Kigepealt kuvatakse loetelu kigis tabelis olevatest lauludest.  Ning kui kasutaja hele neist vajutab, siis lisatakse laulule punkt. Punkti lisamiseks on viide
<a href='?healaulu_id=$id'>Lisa punkt</a>
ehk siis ksimrgiga viide viib kasutaja samale failile. Kaasa antakse parameeter nimega healaulu_id, vrtuseks selle laulu id, mille nimele parajasti vajutatakse. 
Serveris lehe uuel avamisel kontrollitakse, kas parameeter healaulu_id on olemas. Kui jah, siis pannakse sellele laulule ks punkt juurde, ehk suurendatakse vastava vlja vrtust. 

Vrtuse suurendamiseks he vrra sobib SQL-lause 
UPDATE laulud SET punktid=punktid+1 WHERE id=?
kus siis ksimrgi kohale tuleb prast ksu ettevalmistust vastava laulu id.
Punktide jagamise kood tervikuna

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(isSet($_REQUEST["healaulu_id"])){
     $kask=$yhendus->prepare("UPDATE laulud SET punktid=punktid+1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["healaulu_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare("SELECT id, pealkiri, punktid FROM laulud");
		 $kask->bind_result($id, $pealkiri, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
		    echo "<tr>
			  <td>$pealkiri</td>
			  <td>$punktid</td>
			  <td><a href='?healaulu_id=$id'>Lisa punkt</a></td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>

Tulemusena ilmuvad olemasolevad laulud silma ette. 

Millisele reale vajutati, selle laulu punktide arv suureneb he vrra.

lesandeid
Tee nide lbi
Loo/otsi eelneva lesande ansamblite tabel.
Loo vimalus ka ansamblitele punktide jagamiseks. 
Tekita juurde tulbad, kus on vimalik punkte ka kahe- ja kolmekaupa jagada.

Laulude peitmine ja avalikustamine
"Pris" rakenduste juures enamasti ei kustutata midagi lihtsalt ra, vaid lihtsalt mrgitakse, et vastav kirje/rida on "arhiveeritud". Selliselt on vimalik ka veebiandmete kaudu toimunu ajalugu vaadata ning vajadusel mningaid kohti siluda/taastada. Kui millalgi on vaja surnud ridade arvel andmebaasi mahtu vhendada, siis need enamasti korjatakse kusagile varundustabelisse vi faili kokku ning lastakse seal veel mnda aega olla, kuni loota vib, et sealt enam midagi thtsamat vajalikuks ei osutu. Sarnase avalikustamise ja peitmise mngime lbi ka laulude puhul. Kas laul on avalik vi mitte, seda saab lugeda vastavast tulbast: 0 - peidetud, 1- avalik. Lehel avalike laulude nitamiseks pannakse laulude nitamise juures pringule lihtsalt WHERE-tingimus avalik=1.

avalikudlaulud.php

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
		   "SELECT id, pealkiri, punktid FROM laulud WHERE avalik=1");
		 $kask->bind_result($id, $pealkiri, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
		    echo "<tr>
			  <td>$pealkiri</td>
			  <td>$punktid</td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>

Laulud esiotsa ilusasti avalikult nha.



Laulude peitmiseks saab nende nimed ette kuvada ning taga oleva viite kaudu siis loo peidetuks muuta. Jllegi tuleb kaasa anda loo id ning lehe laosas uuel laadimisel sellele vastavalt reageerida. Vastavalt saadetud peitmise_id-le kivitatakse SQL-lause
UPDATE laulud SET avalik=0 WHERE id=?
mille tulemusena vajutatud viitega laulu tulbale avalik antakse vrtuseks 0 ning laulu enam avalike laulude seas ei kuvata.


haldus3.php

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(isSet($_REQUEST["peitmise_id"])){
     $kask=$yhendus->prepare("UPDATE laulud SET avalik=0 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["peitmise_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare("SELECT id, pealkiri, avalik FROM laulud");
		 $kask->bind_result($id, $pealkiri, $avalik);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
		    echo "<tr>
			  <td>$pealkiri</td>
			  <td>$avalik</td>
			  <td><a href='?peitmise_id=$id'>Peida</a></td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>

Algul kik lood avalikud


Prast vajutust lks Muumioru lugude avalik-tulp nulliks. 

Tulemusena seda lugu avalike laulude all ei kuvata.


Lihtsamal juhul piirduvadki lehe oskused vaid peitmisega. Niteks kui vaja roppe veebikommentaare varju panna, siis tavalisel halduril vib tiesti piisata peitmise-viitest. Erandkorras tagasipaneku vib kasvi eraldi vikese lehena ehitada. Kui aga soov mlemas suunas mramised samale lehele panna, siis ka see vimalik ning nii siinses nites ka tehakse. heks mooduseks oleks teha lehele eraldi tulp peitmise, eraldi avalikustamise tarbeks. Mngase sttimise tulemusena pseb aga he tulbaga - lihtsalt tuleb viiteid ja snu nnda kohendada, et vajutuse peale olemasolevas seisus muutus tekiks. 
Lehe pises on parameetrite kohta kaks valikut. Kui tuleb peitmise_id, siis vastav laul peidetakse. Kui tuleb avamise_id, siis selle id-ga rida muudetakse nhtavaks. 
ige teksti ja viite nitamiseks sobib lik
			$avamistekst="Ava";
			$avamisparam="avamise_id";
			$avamisseisund="Peidetud";
Ehk siis algul eeldatakse, et lugu pole avalik, parameetri nimeks saab avamise_id ning kasutajale nhtav sna on "Peidetud".  Alloleval real trkitakse muutujate vrtused nnda ka lehele. 
			  <td><a href='?$avamisparam=$id'>$avamistekst</a></td>
Kui aga pringust selgub, et laul siiski on avalik, siis pratakse muutujate vrtused mber ning vljatrki tulemusena tekib oluord, kus vajutuse tulemusena pannakse lugu peitu. 
			if($avalik==1){
			   $avamistekst="Peida";
			   $avamisparam="peitmise_id";   
			   $avamisseisund="Avatud";
			}
Nii ongi vimalik samal kohal korduvalt klpsides laulu seisundit avalikust peidetuks ja tagasi muuta. 

haldus4.php 

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(isSet($_REQUEST["peitmise_id"])){
     $kask=$yhendus->prepare("UPDATE laulud SET avalik=0 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["peitmise_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["avamise_id"])){
     $kask=$yhendus->prepare("UPDATE laulud SET avalik=1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["avamise_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare("SELECT id, pealkiri, avalik FROM laulud");
		 $kask->bind_result($id, $pealkiri, $avalik);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
			$avamistekst="Ava";
			$avamisparam="avamise_id";
			$avamisseisund="Peidetud";
			if($avalik==1){
			   $avamistekst="Peida";
			   $avamisparam="peitmise_id";   
			   $avamisseisund="Avatud";
			}
		    echo "<tr>
			  <td>$pealkiri</td>
			  <td>$avamisseisund</td>
			  <td><a href='?$avamisparam=$id'>$avamistekst</a></td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>


Alustuseks nha et eelnevalt peidetud Muumioru lood on endiselt peidus.


Avamisviite peale tuleb lugu avalikuks



Samuti tekib ta siis laulude ldisesse loendisse


lesandeid
Tee nide lbi
Lisa ansamblite lehele avalikustamise ja peitmise vimalus.
Vimalda eraldi peita ja nidata korraga kiki neid ansambleid, kel pole veel htegi punkti.

Kommenteerimine

Veebilehtedele kirjutatakse kommentaare ja tiendusi pris mitmel puhul. Ajalehtedes kommenteeritakse uudiseid, tehnikud mrgivad tehtud tid, siin pame kokku koguda laulude kohta tehtavad kommentaarid. Keerukamal juhul tasub teha kommentaaride jaoks eraldi andmetabel, siis on vimalik neid mugavalt niteks kirjutaja vi loomisaja jrgi jrjestada. Lihtsamal juhul aga piisab iga laulu kohta lihtsalt hest kommentaarivljast vastavas tulbas, kuhu inimeste kirjutatud kommentaarid ksteise otsa lisatakse. 

Lisamise puhul tuleb kuidagi kindlaks mrata, et millise laulu juurde vastav kommentaar kirjutatakse. Siin nites tehakse iga laulu juures olevasse lahtrisse eraldi vorm. Sinna sisse pannakse varjatud vli laulu kohta, millele uus kommentaar kirjutatakse. Edasi lisatakse tekstivli ning sisestusnupp. Korraga saadetakse veebilehitsejast serverisse vaid he vormi andmed - just selle omad, kus sisestusnuppu vajutati. Sellise trikiga saabki hoolitseda, et soovitud laulu id lheb koos kommentaaritekstiga kaasa.

  <td>
    <form action='?'>
	   <input type='hidden' name='uue_kommentaari_id' value='$id' />
	   <input type='text' name='uus_kommentaar' />
	   <input type='submit' value='Lisa kommentaar' />
    </form>
  </td>


Lehe pises vaadatakse, kas saabus uue kommentaari id. Kui jah, siis lisatakse saabunud kommentaari teksti selle laulu kommentaarilahtri teksti lppu ja pannakse reavahetus vahele. Lehe sisu avanemisel saab nnda juba uut kommentaari nha. Ksk htmlspecialchars asendab erismbolid, nl2br asendab tekstis olevad reavahetused HTML-i <br />-kskudega.

haldus5.php

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(isSet($_REQUEST["uue_kommentaari_id"])){
     $kask=$yhendus->prepare(
	   "UPDATE laulud SET kommentaarid=CONCAT(kommentaarid, ?)  WHERE id=?");
	 $kommentaarilisa="\n".$_REQUEST["uus_kommentaar"]."\n";
	 $kask->bind_param("si", $kommentaarilisa, $_REQUEST["uue_kommentaari_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
               "SELECT id, pealkiri, kommentaarid FROM laulud");
		 $kask->bind_result($id, $pealkiri, $kommentaarid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
			$kommentaarid=nl2br(htmlspecialchars($kommentaarid));
		    echo "<tr>
			  <td>$pealkiri</td>
			  <td>$kommentaarid</td>
			  <td>
			    <form action='?'>
				   <input type='hidden' name='uue_kommentaari_id' value='$id' />
				   <input type='text' name='uus_kommentaar' />
				   <input type='submit' value='Lisa kommentaar' />
				</form>
			  </td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>


Tulemusena siis teikib iga laulu nime jrele kommentaari lisamise lahter. Vahepealses tulbas nha laulule eelnevalt lisatud kommentaarid. Lahtrisse vib lisada uue kommentaari.



Prast lisamisnupule vajutamist neb seda kommentaari juba laulu nime jrel.


lesandeid
Tee nide lbi
Lisa kommenteerimisvimalus ansamblivaliku lehele
Lisa kommentaarile automaatselt ka aeg PHP date-kskluse abil

Haldus laulude kaupa
Thelepanekud ppijate juures kipuvad nitama, et kui he toiminguga lehest eraldi aru saadud ning mistetakse selle phjal ka sarnaseid lehti teisel teemal koostada - sellest veel ei pruugi piisata, et mitme toimetuse hele lehele kokkupanek sama hlpsasti kiks. Seetttu ka siin nide, kuidas punktide haldus ning kommentaaride lisamine vimalik samale lehele kokku tsta. Lihtsamal kujul kiks see nnda, et laulu taga on kaks tulpa - ks punktide mramiseks ning teine kommentaari lisamiseks. Ning leval oleks vastavad andmetabeli muutmise plokid jrjestikku, if-lausega saab kontrollida, et kumma toiminguga parajasti tegemist.
Siin aga on keerukamalt ette vetud ning tehtud nnda, et laulude loetelu on eraldi ning sealt valitud laulu andmed nidatakse lehe laosas. Kuna korraga aktiivne vaid ks laul, siis jagub lehel rohkem ruumi temaga seotud ettevtmiste tarbeks. 
Laulude loetellu ksitakse kasutaja lehele vlja avalikud laulud. Iga laulu pealkiri muutub vljatrkil viiteks, mis nitab samale veebilehele, kuid kuhu antakse kaasa valitud laulu id (href='?id=$id'). 

    <table>
	  <?php
	     $kask=$yhendus->prepare(
                "SELECT id, pealkiri, punktid FROM laulud WHERE avalik=1");
		 $kask->bind_result($id, $pealkiri, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
		    echo "<tr>
			  <td><a href='?id=$id'>$pealkiri</a></td>
			  <td>$punktid</td>
			</tr>";
		 }
	  ?>
	</table>


Kui laulu id valiti, sellisel juhul ksitakse lehel prast body algust vlja pring vaid selle laulu andmete ktte saamiseks. 
	  if(isSet($_REQUEST["id"])){
	     $kask=$yhendus->prepare("SELECT id, pealkiri, kommentaarid, punktid, lisamisaeg FROM laulud WHERE id=?");

Sealt edasi vib siis ka laulu kommentaari sisestada vi punkti lisada. 

Andmete tegelik baasi kirjutamine toimub lehe uuel avanemisel kui vastavad parameetrid kaasas. See osa nha kohe uue vljatrki alguses.

laululeht.php

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas1");
  if(isSet($_REQUEST["healaulu_id"])){
     $kask=$yhendus->prepare("UPDATE laulud SET punktid=punktid+1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["healaulu_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["uue_kommentaari_id"])){
     $kask=$yhendus->prepare(
	   "UPDATE laulud SET kommentaarid=CONCAT(kommentaarid, ?)  WHERE id=?");
	 $kommentaarilisa="\n".$_REQUEST["uus_kommentaar"]."\n";
	 $kask->bind_param("si", 
               $kommentaarilisa, $_REQUEST["uue_kommentaari_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Laulud</title>
  </head>
  <body>
    <?php
	  if(isSet($_REQUEST["id"])){
	     $kask=$yhendus->prepare(
             "SELECT id, pealkiri, kommentaarid, punktid, lisamisaeg 
                FROM laulud WHERE id=?");
		 $kask->bind_param("i", $_REQUEST["id"]);
		 $kask->bind_result(
                 $id, $pealkiri, $kommentaarid, $punktid, $lisamisaeg);
		 $kask->execute();
		 if($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
			$kommentaarid=nl2br(htmlspecialchars($kommentaarid));
		    echo "
			  <h2>$pealkiri</h2>
			  <dl>
			    <dt>Punkte:</dt>
				<dd>$punktid</dd>
			    <dt>Lisatud:</dt>
				<dd>$lisamisaeg</dd>
			    <dt>Kommentaarid:</dt>
				<dd>$kommentaarid</dd>
			  </dl>
			  <a href='?healaulu_id=$id'>Lisa punkt</a><br />	
			  <form action='?'>
				   <input type='hidden' 
                              name='uue_kommentaari_id' value='$id' />
				   <input type='text' name='uus_kommentaar' />
				   <input type='submit' value='Lisa kommentaar' />
			  </form>			  
			";
			$kask->close();
		 }
	  }
	?>
    <h1>Laulud</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
               "SELECT id, pealkiri, punktid FROM laulud WHERE avalik=1");
		 $kask->bind_result($id, $pealkiri, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($pealkiri);
		    echo "<tr>
			  <td><a href='?id=$id'>$pealkiri</a></td>
			  <td>$punktid</td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>


Algul avaneb lehel laulude loetelu nagu tavaliselt, igahele taha kirjutatud selle laulu punktide arv.


Laulule vajutades saadetakse uuele lehepringule kaasa selle laulu id (nha aadressiribal).
Saabunud id jrgi ksitakse vlja vastava laulu muud andmed ning nidatakse kasutajale. Samuti pannakse sinna siis viide punkti lisamiseks ning koht kommentaari sisestamiseks.


Punktiviitele vajutamisel lisatakse punkt andmetabelisse ning seda neb lehe jrgmisel avamisel. Mutionu pidu on kaheksale punktile he juurde saanud. 


Ja kommentaarid juavad ka ilusti laulule klge. 



Nnda vib mlema oskuse koos toimimist hel lehel imetleda ning omale jrgmiste rakenduste loomise juures alusnidisena vtta. 


lesandeid
Tee nide lbi
Pane ka ansamblite lehel kommenteerimine ja hlte andmine samale lehele
Vimalda anda ka vastuhli, st hli vajutusega vhemaks vtta


Kohviautomaat

Andmetabeli kuju: (id, jooginimi, topsepakis, topsejuua)
Topside arv pakis nitab, mitu topsitit saab juua he titepakendi sisestamise peale. 
Loo tabel SQL-lausega. Lisa joogina kohv. Titepaki suuruseks 50 topsi jagu pulbrit, algul masin thi, juua pole midagi. Loo SQL-lause juua olevate topside arvu suurendamiseks titepaki jagu. Kivita.
Automaadi kivitatav leht vhendab juua olevate topside arvu he vrra. Vaataja leht nitab seda arvu.
Automaat saab hakkama mitme joogiga (kohv, tee, kakao). Lehel nidatakse vaid neid jooke, millel on vhemasti ks tops juua. Joomise tulemusena vhendatakse vastava joogi olemasolevate topside loendurit. Halduslehel saab joodavate topside arvu kogust suurendada titepaki jagu.

Jalgrattaeksami haldamise rakendus
Jrgnevalt veidi pikem nide enamvhem tegeliku rakenduse veebiliidese kohta, kus sama sndmusega tegelevad mitu asjaosalist. Ehk siis tegemist abivahendiga t juures, kus muidu oleks pris palju sebimist, et vajalikud andmed igel ajal igesse kohta juaksid. 
ksinda pris lihtsalt rakendust tehes saab otsast vaikselt tegema hakata, veidi katsetada ning loodetavasti juabki mne aja prast kasutaja jaoks sobivale tulemusele. Kui aga tegijaid vi kasutajaid mitu, vi lihtsalt vtab rakenduse kokku panek rohkem aega kui paar peva - sellisel juhul tuleb mningane kavandamine ja plaanide lesmrkimine kasuks. Siis rohkem lootust, et tulemus lppkasutajale sobilik on ning ei pea nnda palju td ringi tegema. Et prast arendaja arvates rakenduse enam-vhem valmis saamist kulub vhemalt kolmandik td lppviimistluse jaoks, see on tavaprane. Kllalt kergesti aga kipub juhtuma, et prast esialgse lahenduse pealtnha kikide osade eraldi tle hakkamist kulub veel kaks korda nnda palju aega ja judu, et kuidagi ttavad lahendused vimalikult hsti ttavate mooduste vastu vahetada. Sest veebirakendusest on ju ldiselt kasu vaid siis, kui t jutakse kiiremini ja paremini teha vrrelduna pliiatsi ja paberi ning muude tavaliste vahendite abil tehtuna. Tavamooduseid on sageli aastakmneid kasutatud ja lihvitud. Veebilahenduse mugavaks saamiseks tuleb see kohandumisring ka ette vtta. 
ks levinud moodus rakenduste kavandamisel ja koostamisel on kirja panna vi lbi kia jrgmised osad:

Rakenduse ldkirjelduse lesmrkimine
Kasutajate tegevuste kirjapanek  ksikute kasutajalugude kaupa
Veebilehtede struktuuri kirjapanek
Lehtede lesjoonistamine (paber)prototpidena, tegevuste lbimng
Lehtede kujundamine HTML-prototpidena
Andmebaasiskeem
Andmete ja kujunduse hendamine (ehk esmapilgul philine t)
Lahenduse katsetamine tegijate hulgas
Vajalike tienduste sisseviimine
Lahenduse katsetamine sihtkohas, kohandamine, kuni vib tulemuse klblikuks lugeda.

Kavandamine

Jalgrattaeksami ldkirjeldus

Jalgrattaeksam koosneb kolmest etapist:
Teooriaeksam
 Platsieksam
 Tnavasidueksam

Teooriaeksami sooritamiseks on kmnest ksimusest vaja igesti vastata vhemalt heksa. 

Platsieksamil tuleb reeglitepraselt lbida slaalomirada ning nidata oma siduoskusi ringteel.

Tnavasidueksamil tuleb eksamineeritavate grupil jrjestikku sita ees ja taga oleva eksamineerija vahel jrgides liikluseeskirju.

Teooriaeksam peab olema sooritatud enne platsieksamit. Platsieksam peab olema sooritatud enne tnavasidueksamit. Platsieksami osade lbimise jrjekord pole thtis.




Kasutajalood

Jalgrattalubade taotleja tuleb eksamile registreerimise laua juurde, esitab oma isikut tendava dokumendi. Registreerija sisestab kasutaja andmed (lihtsamal juhul ees- ja perekonnanime) rakenduse kaudu infossteemi

Teoriaeksamiruumi sisenemisel kontrollitakse, et kohaletulnud on end eksamile registreerunud. Keda pole veel kirjas, suunatakse registreerimislaua juurde. Teooriaeksami lahendanud taotlejatele sisestatakse nime juurde tema saadud punktide arv.

Platsieksamil on kaks kontrollpunkti, kummaski eraldi kontrollija koos sisestusseadmega.
Kontrollijad nevad vaid neid nimesid, kes on registreeritud ning kel on kogutud teooriaeksamist vhemalt heksa punkti. Kontrollija saab rakenduses mrata, kas eksamineeritav sai oma lesandega hakkama (vastavalt siis slaalomisiduga vi ringteesiduga vastavalt kontrollpunktile).

Tnavasidueksami inspektorid nevad infossteemis vaid neid lubade taotlejaid, kel on lbitud mlemad platsieksami kontrollpunktid. Vaid neid saavad nad tnavasidueksamile lubada. Tnavasidueksami lpus mrgivad inspektorid, et kellel tnavasidueksam nnestus, kellel mitte.

Lubade vljastamise laua ttajal on vimalik nha kigi eksamineeritavate seisu. Kel pilt olemas, sellele vljastatakse luba ning mratakse sellega eksam lpetatuks. 
Rakenduse lehed

Jalgrattalubade taotleja registreerimine
  Sisestatakse taotleja ees- ja perekonnanimi. Andmed talletatakse kirjena tabelisse.

Teooriaeksam
  Nhakse loetelu registreeritud osalejatest, kes pole veel teooriaeksamil tulemust saanud.
  
  Eksamilesande lahendanu nime juurde saab kirjutada tulemuse.

Slaalom
  Nha on teooriaeksami lbinud eksamineeritavad, kel veel pole kirjas tulemust slaalomi kontrollpunkti kohta. Saab soorituse mrata kas nnestunuks vi ebannestunuks.
  
Ringtee
  Nha on teooriaeksami lbinud eksamineeritavad, kel pole veel kirjas tulemust ringtee kontrollpunkti kohta. Saab soorituse mrata kas nnestunuks vi ebannestunuks.

Tnavasidueksam
  Nha on nimekiri eksamineeritavatest, kes on lbinud platsieksami (ehk siis slaalomi ja ringtee kontrollpunkti) ning pole veel kirja saanud tulemust tnavasidueksamil. Iga eksamineeritava kohta saab mrata tulemuse kas nnestunuks vi ebannestunuks.

Vormistamise leht
  Nha on kikide osalejate tulemused. Kel kik etapid korras, saab loa ktte ja see pannakse kirja.





Alloleval skeemil on kavandatavad lehed teravate nurkadega kastides. Enne ja prast lehekaste olevates marnurkadega kastides kirjeldatakse seisundid enne ja prast lehte.

Lehtede joonised
Jrgmisena on viisakas valmis joonistada ksikud vaated. Olgu siis pastapliiatsi ja paberi abil, lihtsa joonistusprogrammiga vi mnd mockup-triista kasutades.
















Edasi tasub lbi mngida kasutajalood jlgides, et kas ja kui mugavalt on neid joonistatud vaateid kasutades vimalik ssteem lbida. Piisavalt lihtsalt loodud kavanditele saab kergesti kommentaare juurde lisada. Ning kui katsetamise kigus selgub, et mni muu lahendus oleks parem, siis on suhteliselt hlbus ka vana skeem uuega asendada.
Andmebaasiskeem
Rakenduse loomise vimaluste juures on thtis osa andmebaasiskeemil. Kasutada nnestub enamasti vaid neid andmeid, mis baasis olemas. Siin nites piirdutakse andmete hoidmisel he tabeliga. Kuid erisuguste andmete lisandumisel vib tabelite arv kergesti kasvama hakata. Lhidalt kirja panduna on tabel jrgnevate tulpadega. 

jalgrattaeksam(id, eesnimi, perekonnanimi, teooriatulemus, slaalom, ringtee, t2nav, luba)

Andmebaasiprogrammile tabeli loomisel arusaadavaks SQL-lauseks on 

CREATE TABLE jalgrattaeksam(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  eesnimi VARCHAR(30),
  perekonnanimi VARCHAR(30),
  teooriatulemus INT DEFAULT -1,
  slaalom INT DEFAULT -1,
  ringtee INT DEFAULT -1,
  t2nav INT DEFAULT -1,
  luba  INT DEFAULT -1
);


-1 thistab sisestamata tulemust
teooriatulemuse puhul 0-10 thistab saadud punktide arvu
muude tulpade puhul
 1 thistab, et sooritus nnestus
 2 thistab, et sooritus ei nnestunud




Jrgneval skeemil mrgitakse iga seisundit kirjeldava marnurkadega kasti juurde, et kuidas eksamineeritavate hulgast ra tunda seisundile vastajad, et neid saaks soovitud kohas kuvada. Teravnurkadega kasti juures mrgitakse, et milline muutus tehakse veebilehe t tulemusena andmebaasis. 


Rakenduse kiguks tarvilikud SQL-laused.
Lehtede tks vajalikud andmete ksimise, lisamise, muutmise ja kustutamise laused on hea enne eraldi vlja kirjutada ning lehtede joonistega vrrelda. Siis paistab vlja, et milliseid andmeid kust saadakse ning kas kik vajalik on olemas. 

Taotleja registreerimine

INSERT INTO jalgrattaeksam (eesnimi, perekonnanimi) VALUES ('Juku', 'Juurikas');
INSERT INTO jalgrattaeksam (eesnimi, perekonnanimi) VALUES ('Kati', 'Tamm');
INSERT INTO jalgrattaeksam (eesnimi, perekonnanimi) VALUES ('Mati', 'Kask');

Teooriaeksamil loetelu eksamineeritavatest, kes pole veel teooriaeksamil tulemust saanud.

SELECT id, eesnimi, perekonnanimi FROM jalgrattaeksam WHERE teooriatulemus=-1;

Teooriaeksami tulemuse sisestamine

UPDATE jalgrattaeksam SET teooriatulemus=9  WHERE id=1;
UPDATE jalgrattaeksam SET teooriatulemus=10 WHERE id=2;
UPDATE jalgrattaeksam SET teooriatulemus=10 WHERE id=3;


Loetelu eksamineeritavatest, kes saavad slaalomipunktis oma oskusi nidata

SELECT id, eesnimi, perekonnanimi FROM jalgrattaeksam 
    WHERE teooriatulemus>=9 AND slaalom=-1;
        
Slaalomipunkti edukalt lbituks mrkimine

UPDATE jalgrattaeksam SET slaalom=1 WHERE id=2;


Loetelu eksamineeritavatest, kes saavad ringteepunktis oma oskusi nidata

SELECT id, eesnimi, perekonnanimi FROM jalgrattaeksam 
    WHERE teooriatulemus>=9 AND ringtee=-1;
        
Ringteepunkti edukalt lbituks mrkimine

UPDATE jalgrattaeksam SET ringtee=1 WHERE id=2;


Loetelu eksamineeritavatest, kel igus tnavasidueksamile minna

SELECT id, eesnimi, perekonnanimi FROM jalgrattaeksam 
  WHERE slaalom=1 AND ringtee=1 AND t2nav=-1;
  

Hetkeandmete vljund:
  
+----+---------+---------------+
| id | eesnimi | perekonnanimi |
+----+---------+---------------+
|  2 | Kati    | Tamm          |
+----+---------+---------------+


Tnavasidueksami mramine sooritatuks:

UPDATE jalgrattaeksam SET t2nav=1 WHERE id=2;


Lubade laua juures kigi tulemuste ngemine:

SELECT id, eesnimi, perekonnanimi, teooriatulemus, slaalom, ringtee, t2nav, luba FROM jalgrattaeksam;

Lubade vljastamise mrkimine:

UPDATE jalgrattaeksam SET luba=1 WHERE id=2;

Veebilehtede loomine 
Prast selliste eeltde lbi viimist on valmivast rakendusest juba mnevrra lhem ettekujutus olemas ning vib loota, et kokkupandav rakendus ka kasutatav on. Ehkki juhtub kllalt sageli, et prast esialgse versiooni tle panekut tuleb ta veel mitme koha pealt mber teha enne, kui kasutajad tulemusega rahul on. Kasutajalugude, skeemide ja esialgsete SQL-lausete kohendamine on aga algul tunduvalt lihtsam kui valmiskujundusega lahenduse pidev mbermngimine. Samuti eriti suuremate lahenduste puhul ei pruugi kogu kavand sugugi kohe korraga phe mahtuda. ksikuid vaateid ja like aga julgeb ikka eraldi katsetada ning nende pealt juab vaikselt ka suurema lahenduse kokku panna. 
konf.php

Suurema lahenduse puhul on seaded hea panna eraldi konfiguratsioonifaili. Praegusel juhul tulevad siia andmebaasihenduse andmed. Kuid hea on olemasolu korral ka kiksugu muud lisandused hte koondada. Nagu ka lpus kommentaar tleb, siis juhul, kui PHP-fail midagi otse ekraanile vljastama ei pea, siis on lubatud ja soovitatav PHP lpumrk ?>  ra jtta.

<?php
 $baasiaadress="localhost";
 $baasikasutaja="juku";
 $baasiparool="kala";
 $baasinimi="jukubaas";
 $yhendus=new mysqli($baasiaadress, $baasikasutaja, $baasiparool, $baasinimi);
 
 //PHP lpumrki pole vaja, et kogemata midagi vlja ei trkitaks
registreerimine.php
Edasi vib vaikselt hakata vaadetele vastavaid lehti tegema. Mnikord sobib hte faili kokku mitu vaadet. Vi mnel korral on mugav ks vaade ehitada mitmest failist. Kuid alustuseks vib enamasti ks-hele seotus sobida. Kuni lehed on suhteliselt iseseisvad ning neid seob andmete poolest andmebaas, siis saab samale andmestikule mugavasti lehti eraldi klge ehitada ning need ei hakka ksteist segama. 

Eksami kigu poolest esimene tarvilik leht on registreerimisvorm. Andmed sisestatakse veebilehel, talletatakse baasi INSERT-lause abil. ramrkimist vrib nime lisamise teate kuvamine veebilehel. Uuesti lehte avama kutsuva header-kskluse aadressirea parameetrina antakse vajalik teade, mis siis lehe avamisel vlja kuvatakse. 
	header("Location: $_SERVER[PHP_SELF]?lisatudeesnimi=$_REQUEST[eesnimi]");


registreerimine.php

<?php 
  require_once("konf.php"); 
  if(isSet($_REQUEST["sisestusnupp"])){
    $kask=$yhendus->prepare(
        "INSERT INTO jalgrattaeksam(eesnimi, perekonnanimi) VALUES (?, ?)");
	$kask->bind_param("ss", $_REQUEST["eesnimi"], $_REQUEST["perekonnanimi"]);
	$kask->execute();
	$yhendus->close();
	header("Location: $_SERVER[PHP_SELF]?lisatudeesnimi=$_REQUEST[eesnimi]");
	exit();
  }
?>
<!doctype html>
<html>
  <head>
     <title>Kasutaja registreerimine</title>
  </head>
  <body>
    <h1>Registreerimine</h1>
    <?php
	  if(isSet($_REQUEST["lisatudeesnimi"])){
	   echo "Lisati $_REQUEST[lisatudeesnimi]";
	  }
    ?>	
	<form action="?">
	  <dl>
	    <dt>Eesnimi:</dt>
		<dd><input type="text" name="eesnimi" /></dd>
	    <dt>Perekonnanimi:</dt>
		<dd><input type="text" name="perekonnanimi" /></dd>
	    <dt><input type="submit" name="sisestusnupp" value="sisesta" /></dt>
	  </dl>
	</form>
  </body>
</html>

Tulemusena koht, kus nimi sisse kirjutada ning prast sisestusnupule vajutamist juab see andmebaasitabelisse.


Prast vajutust ilmuval uuel lehel neb ametnik kinnitust oma saadetud andmete sisestamise kohta.


teooriaeksam.php

Jrgmisena on vaja registreerunud eksamituppa kutsuda. Kigepealt nha, et kes ldse tulemas on. Ning prast lesannete lahendamist ja kontrollimist tuleb mrkida, millised tulemused saadi. Selleks siis kigepealt SELECT-lause nende registreerunute leidmiseks, kel veel teooriaeksam tegemata (punktide arv -1). Ning prast igahe juures UPDATE-lause, mis osalise punktid paika mrab. Et igahe andmed saaks mugavasti eraldi saata, selleks on iga nime taga olev sisestusvli eraldi vormis, kus pannakse varjatud vljana kaasa ka vastava registreerunu id-number. 

<?php 
  require_once("konf.php"); 
  if(!empty($_REQUEST["teooriatulemus"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET teooriatulemus=? WHERE id=?");
	$kask->bind_param("ii", $_REQUEST["teooriatulemus"], $_REQUEST["id"]);
	$kask->execute();
  }
  $kask=$yhendus->prepare("SELECT id, eesnimi, perekonnanimi 
     FROM jalgrattaeksam WHERE teooriatulemus=-1");
  $kask->bind_result($id, $eesnimi, $perekonnanimi);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
    <title>Teooriaeksam</title>
  </head>
  <body>
    <table>
	  <?php
	    while($kask->fetch()){
		  echo "
		    <tr>
			  <td>$eesnimi</td>
			  <td>$perekonnanimi</td>
			  <td><form action=''>
			         <input type='hidden' name='id' value='$id' />
					 <input type='text' name='teooriatulemus' />
					 <input type='submit' value='Sisesta tulemus' />
			      </form>
			  </td>
			</tr>
		  ";
		}
	  ?>
	</table>
  </body>
</html>


slaalom.php
Platsieksami juures heks punktiks on slaalomisit. Sinna psevad need registreerunud, kes kogusid teooriaeksamil vhemasti 9 punkti ning kes pole veel slaalomitulemust kirja saanud. Tulemus thendaks seda, et slaalomisit on kas korras vi ebannestunud. Kasutajaliides on inspektorile vimalikult lihtne, et seda suudaks kergesti ka platsil kaasas oleva miniseadme pealt vaadata. 

<?php 
  require_once("konf.php"); 
  if(!empty($_REQUEST["korras_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET slaalom=1 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["korras_id"]);
	$kask->execute();
  }
  if(!empty($_REQUEST["vigane_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET slaalom=2 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["vigane_id"]);
	$kask->execute();
  }
  $kask=$yhendus->prepare("SELECT id, eesnimi, perekonnanimi 
     FROM jalgrattaeksam WHERE teooriatulemus>=9 AND slaalom=-1");
  $kask->bind_result($id, $eesnimi, $perekonnanimi);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
    <title>Slaalom</title>
  </head>
  <body>
    <h1>Slaalom</h1>
    <table>
	  <?php
	    while($kask->fetch()){
		  echo "
		    <tr>
			  <td>$eesnimi</td>
			  <td>$perekonnanimi</td>
			  <td>
			    <a href='?korras_id=$id'>Korras</a>
			    <a href='?vigane_id=$id'>Ebannestunud</a>
			  </td>
			</tr>
		  ";
		}
	  ?>
	</table>
  </body>
</html>



ringtee.php

Ringteeharjutus on korraldusliku poole pealt slaalomiga sarnane. Kuna platsiharjutuste lbimise jrjekord pole thtis, siis ringteeharjutusele psemiseks on sama tingimus kui slaalomi puhul - ehk siis peab teooriaeksam tehtud olema. 


<?php 
  require_once("konf.php"); 
  if(!empty($_REQUEST["korras_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET ringtee=1 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["korras_id"]);
	$kask->execute();
  }
  if(!empty($_REQUEST["vigane_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET ringtee=2 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["vigane_id"]);
	$kask->execute();
  }
  $kask=$yhendus->prepare("SELECT id, eesnimi, perekonnanimi 
     FROM jalgrattaeksam WHERE teooriatulemus>=9 AND ringtee=-1");
  $kask->bind_result($id, $eesnimi, $perekonnanimi);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
    <title>Ringtee</title>
  </head>
  <body>
    <h1>Ringtee</h1>
    <table>
	  <?php
	    while($kask->fetch()){
		  echo "
		    <tr>
			  <td>$eesnimi</td>
			  <td>$perekonnanimi</td>
			  <td>
			    <a href='?korras_id=$id'>Korras</a>
			    <a href='?vigane_id=$id'>Ebannestunud</a>
			  </td>
			</tr>
		  ";
		}
	  ?>
	</table>
  </body>
</html>

t2nav.php
Tnavasidule lastakse siis, kui mlemad platsiharjutused edukalt lbitud. Seetttu ka vastav pikem kontroll sealjuures. 
  $kask=$yhendus->prepare("SELECT id, eesnimi, perekonnanimi 
     FROM jalgrattaeksam WHERE slaalom=1 AND ringtee=1 AND t2nav=-1");

Muu osa aga eelmistele failidele suhteliselt sarnane.
<?php 
  require_once("konf.php"); 
  if(!empty($_REQUEST["korras_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET t2nav=1 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["korras_id"]);
	$kask->execute();
  }
  if(!empty($_REQUEST["vigane_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET t2nav=2 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["vigane_id"]);
	$kask->execute();
  }
  $kask=$yhendus->prepare("SELECT id, eesnimi, perekonnanimi 
     FROM jalgrattaeksam WHERE slaalom=1 AND ringtee=1 AND t2nav=-1");
  $kask->bind_result($id, $eesnimi, $perekonnanimi);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
    <title>Tnavasit</title>
  </head>
  <body>
    <h1>Tnavasit</h1>
    <table>
	  <?php
	    while($kask->fetch()){
		  echo "
		    <tr>
			  <td>$eesnimi</td>
			  <td>$perekonnanimi</td>
			  <td>
			    <a href='?korras_id=$id'>Korras</a>
			    <a href='?vigane_id=$id'>Ebannestunud</a>
			  </td>
			</tr>
		  ";
		}
	  ?>
	</table>
  </body>
</html>



lubadeleht.php

Lpetuslaua juures tasub kiki eelnevaid andmeid nha. Et kui mnel osalejal tekib ksimusi, et kuhu maani ta vlja judis, siis seal on paras koht  tulemusi vaadata. Lihtsamal juhul kuvatakse tabeli sisu veebilehele. Ning piisavalt teadlik asjaosaline juba teab sealt vlja vaadata, et milline number mida thendab.


<?php 
  require_once("konf.php"); 
  $kask=$yhendus->prepare(
    "SELECT id, eesnimi, perekonnanimi, teooriatulemus, 
	     slaalom, ringtee, t2nav, luba FROM jalgrattaeksam;");
  $kask->bind_result($id, $eesnimi, $perekonnanimi, $teooriatulemus, 
        $slaalom, $ringtee, $t2nav, $luba);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
    <title>Lpetamine</title>
  </head>
  <body>
    <h1>Lpetamine</h1>
	<table>
	  <?php
	    while($kask->fetch()){
		   echo "
		     <tr>
			   <td>$eesnimi</td>
			   <td>$perekonnanimi</td>
			   <td>$teooriatulemus</td>
			   <td>$slaalom</td>
			   <td>$ringtee</td>
			   <td>$t2nav</td>
			   <td>$luba</td>
			 </tr>
		   ";
		}
	  ?>
	</table>
  </body>
</html>



lubadeleht.php ilusamalt

Lpetaja tlesannete hulka kuulub ka lubade vljastamine - jrelikult ka see toimetus sobib siinse lehe juurde. Ning esimesi pevi tl oleval ametnikul on mugavam vaadata selgesnalisi seletusi, kellel mis on korras ja mis mitte. Selle tarvis lisati vike alamprogramm asenduste tarbeks - numbrile vastavalt antakse vlja sobiv tekst. Nnda neb allolev leht juba mrgatavalt ametlikum vlja. 


<?php 
  require_once("konf.php"); 
  if(!empty($_REQUEST["vormistamine_id"])){
    $kask=$yhendus->prepare(
	  "UPDATE jalgrattaeksam SET luba=1 WHERE id=?");
	$kask->bind_param("i", $_REQUEST["vormistamine_id"]);
	$kask->execute();
  }
  $kask=$yhendus->prepare(
    "SELECT id, eesnimi, perekonnanimi, teooriatulemus, 
	     slaalom, ringtee, t2nav, luba FROM jalgrattaeksam;");
  $kask->bind_result($id, $eesnimi, $perekonnanimi, $teooriatulemus, 
        $slaalom, $ringtee, $t2nav, $luba);
  $kask->execute();
  
  function asenda($nr){
    if($nr==-1){return ".";} //tegemata
    if($nr== 1){return "korras";}	
    if($nr== 2){return "ebannestunud";}	
	return "Tundmatu number";
  }
?>
<!doctype html>
<html>
  <head>
    <title>Lpetamine</title>
  </head>
  <body>
    <h1>Lpetamine</h1>
	<table>
	  <tr>
	    <th>Eesnimi</th>
	    <th>Perekonnanimi</th>
	    <th>Teooriaeksam</th>
	    <th>Slaalom</th>
	    <th>Ringtee</th>
	    <th>Tnavasit</th>
	    <th>Lubade vljastus</th>
	  </tr>
	  <?php
	    while($kask->fetch()){
		   $asendatud_slaalom=asenda($slaalom);
		   $asendatud_ringtee=asenda($ringtee);
		   $asendatud_t2nav=asenda($t2nav);
		   $loalahter=".";
		   if($luba==1){$loalahter="Vljastatud";}
		   if($luba==-1 and $t2nav==1){
		     $loalahter="<a href='?vormistamine_id=$id'>Vormista load</a>";
		   }
		   echo "
		     <tr>
			   <td>$eesnimi</td>
			   <td>$perekonnanimi</td>
			   <td>$teooriatulemus</td>
			   <td>$asendatud_slaalom</td>
			   <td>$asendatud_ringtee</td>
			   <td>$asendatud_t2nav</td>
			   <td>$loalahter</td>
			 </tr>
		   ";
		}
	  ?>
	</table>
  </body>
</html>


lesandeid
Pane nitkoodid kima
Lisa ppuri ees- ja perekonnanime juurde isikukood. Kontrolli toimimist.

Oma lahenduse loomise lesanded
Eelneva jalgrattaeksami lahenduse saab niteks krvale vtta ning nd on paras aeg oma valitud teemal sarnane arendusprotsess lbi kia. Kui tegijal parajasti paremat ideed ei tule, siis heaks harjutuseks on niteks pitsapoe tellimuste haldus. Kigepealt paika rakenduse lihtne ldkirjeldus, et krvaltvaatajalt veidi lhemalt mista oleks, millega tegemist. Siis saab kshaaval paika panna tegevused ja rollid - kel mida phjust ja igus teha. Edasi on viisakas jrjest kirja panna kik vimalikud toimingud, mis veebirakenduses he pitsatellimuse juures on mistlik ette vtta. Ka tasub niteks melda sellele, kas kuidagi peaks rakendus teadma sellest, et esimene pannile pandud pitsa lks krbema ning uue valmimine vtab lisaaega. 
Kui toimetused kirjas, siis tasub asuda vaadete vlja joonistamisele. Esialgu kik lehed lihtsate skeemidena. Nende peal on hea vimalikud olukorrad lbi mngida. Kui aga philised toimetused tunduvad ttama, siis vib mne kujunduse ka phjalikumalt korda teha ning ka HTMLina valmis kujundada - enne kui pris andmetega majandama ja pead valutama hakata.
Omaette rida on andmebaas vlja melda - lihtsamal juhul sobiv andmetabel kokku panna, kus kik he pitsa tellimisega seotud andmed sees. Ning siis leheklgede kaupa SQL-laused valmis kirjutada, et nha, millised andmed kust tulevad ning kuhu lhevad. Sageli selgub selle kigus ka, et mistlik on andmetabelit vi kujunduslehti veidi kohandada, et tulemus mugavamalt saavutatav oleks. 
Ja kui eeltd tehtud, vib usinasti rakenduse kokkupaneku kallale asuda. Olgu siis ksipini vi koos sbraliku seltskonnaga. Kui kujunduspildid ning andmebaasipringud ees, siis vib juba sna julgesti iga lehte eraldi teha ning prast koos ttavat tulemust imetleda. 

Suurema toimetuse krvale vi asemele enesekontrolliks vi kontrolltks mned lesanded, mille kallal viks siinse ppematerjali lbimise jrel olla samuti jaksu judu katsuda. 

Kohviautomaat

Andmetabeli kuju: (id, jooginimi, topsepakis, topsejuua)
Topside arv pakis nitab, mitu topsitit saab juua he titepakendi sisestamise peale. 
* Loo tabel SQL-lausega. Lisa joogina kohv. Titepaki suuruseks 50 topsi jagu pulbrit, algul masin thi, juua pole midagi. Loo SQL-lause juua olevate topside arvu suurendamiseks titepaki jagu. Kivita.
* Automaadi kivitatav leht vhendab juua olevate topside arvu he vrra. Vaataja leht nitab seda arvu.
* Automaat saab hakkama mitme joogiga (kohv, tee, kakao). Lehel nidatakse vaid neid jooke, millel on vhemasti ks tops juua. Joomise tulemusena vhendatakse vastava joogi olemasolevate topside loendurit. Halduslehel saab joodavate topside arvu kogust suurendada titepaki jagu.

Viljaladu

Andmetabel koormad: (id, autonr, sisenemismass, lahkumismass)
* Koosta tabel. Loo SQL lause auto lisamiseks koos autonumbri ja sisenemismassiga. Loo lause valitud id-ga auto lahkumismassi mramiseks. 
* Koosta veebileht, kus saab sisestada autonumbri ja sisenemismassi. Koosta teine veebileht, kus valitud autole saab mrata vljumismassi.
* Koosta leht, kus nha tulnud autod koos andmetega ning maha laetud koormate suurused. Autonumbrile vajutades nidatakse kik selle auto reisid ning arvutatakse kokku toodud vilja kogus.


Toolivahendus

Andmetabel toolid: (id, toon, tellimiskogus, valminudkogus)
* Koosta tabel. Loo SQL-lause tellimuse sisestamiseks (toon tekstina, ja tellimiskogus). Valminuid algul 0. Loo ksklus valminud koguse suurendamiseks he vrra.
* Koosta veebileht tellimuse sisestamiseks. Nita veebilehel toolide tabeli seisu. Loo leht tellimusele vastava valminud koguse suurendamiseks he vrra.
* Valminud kogust saab suurendada vaid tellimustel, kus kogus pole veel tis. Eraldi lehel nita valminud tellimusi. Arvuta kokku, mitu tooli on veel teha.


Autoveod

Andmetabel veod: (id, algus, ots, aeg, autonr, juht, valmis)
* Koosta tabel. Loo SQL-laused tellimuse sisestamiseks (algus, ots, aeg), tellimusele autonumbri mramiseks, tellimusele juhi nime mramiseks. 
* Koosta leht veotellimuse sisestamiseks (algus- ja otspunkt, soovitav aeg). Koosta leht tellitud, kuid ilma juhita vedude ngemiseks. Vimalda veole mrata juht.
* Nita lehel vedusid, mille juht vi autonumber mramata. Vimalda neid mrata. Juhi ja autonumbriga vedude puhul nita eraldi need veod, mis pole veel valmiks mratud, vimalda tehtuks mrata.


Arvutikomplektid

Andmetabel: arvutitellimused(id, kirjeldus, korpus, kuvar, pakitud). Viimased kolm neist arvud vrtusega 0 vi 1.
* Koosta tabel. Loo SQL-lause kirjelduse sisestamiseks. Loo lause mramaks, et valitud tellimuse korpus on komplekteeritud.
* Koosta veebileht tellimuse sisestamiseks. Nita sisestatud tellimuse ja komplekteerimata korpusega tellimusi, vimalda mrata korpus komplekteerituks.
* Eraldi saab valmiks mrata korpuse ja kuvari. Pakkimislehel neb vaid neid lehti, kus korpus ja kuvar olemas, aga komplekt veel pakkimata. Saab mrata pakituks. Luuakse statistikaleht, kus kirjas tellimuste arv ning mitu neist on lpetatud.


Hirmude maja

Lbustuspargis olevate uduste maja klastajate haldamise rakendus. Majas olevate ohtlike atraktsioonide tttu tuleb inimeste le arvet pidada.

Andmetabel: hirmumaja:(id, eesnimi, sisenes, lahkus).
* Loo andmetabel. Loo SQL-lause kasutaja lisamiseks. Lause etteantud id-ga kasutaja sisenemiseks. Lause etteantud id-ga kasutaja lahkumise mrkimiseks. 
* Koosta veebileht pileti ostmiseks. Kasutaja kohta sisestatakse eesnimi. Vimalusel nidatakse lehele tekkival piletil kasutaja eesnime ja id-d ($yhendus->insert_id). 
* Sisenemisukse juures oleval lehel mrgitakse piletit nidanud id-ga inimene sisenenuks, vljumisukse juures oleval lehel lahkunuks. Loetelus saab nha hirmude maja sees olevate inimeste loetelu.


Aknaruloode tootmine

Andmetabel rulood (id, mustrinr, riievalmis, puuvalmis, pakitud)
Tellimisel sisestatakse mustri number. Vastavalt mustrinumbrile tuleb ligata sobiv riie ning vrvida sobiv puuosa. Kui mlemad on olemas, saab nad hendada ja teelesaatmiseks pakki panna. 
* Loo SQL lause soovitud mustrinumbriga tellimuse lisamiseks. Lause mratud id-ga tellimuse riidelikuse valmiks mramiseks. Lause valimis riide- ja puuosadega kuid veel pakkimata ruloode nitamiseks. 
* Koosta veebileht tellimuse lisamiseks. Riideosakonna tline neb koos mustrinumbritega tellimusi, kus riideosa pole veel ligatud. Saab t tegemisel mrata need ligatuks.
* Loo sarnane leht puuosa tegijate jaoks. Komplekteerijate lehel nha tellimused, mida saab pakkima hakata. Pakitud tellimused saab pakituks mrkida. Klient saab oma tellimuse numbri sisestamisel nha oma tellimuse seisu.


Tantsuvistlus

Hambotantsuvistlusel tantsitakse piki tnavat. Sama paari hindab rii iga liige oma ligul.
Andmetabel tantsupaarid (id, hinne1, hinne2, hinne3)
* Loo SQL lause tantsupaari sisestamiseks. Loo lause esimeses punktis hindamata paaride nitamiseks. Loo lause mratud id-ga paarile hinde mramiseks.
* Loo veebileht tantsupaari lisamiseks. Loo veebileht paaride nitamiseks, kes pole veel esimest hinnet saanud. Hindaja saab paarile hinde andmiseks vajutada sobivat tema taga olevat numbrit hest viieni. 
* Loo sarnased lehed teiste hindamislikude tarbeks. Loo koondleht vistluse lpetanud paaride tulemuste vaatamiseks, kus on nha ka iga paari keskmine hinne. 


Suusahppevistlus


Andmetabel suusahyppajad (id, alustanud, kaugus, valmis).
* Loo SQL laused suusahppaja lisamiseks, laskumise alustamise mrkimiseks, alustanud ja veel lpetamata hppaja leidmiseks, talle kauguse mramiseks ning hppealast vljumise mramiseks.
* Loo veebileht suusahppajate lisamiseks. htlasi on nha igahe seis ja tulemus.
* Loo veebileht, millega mratakse laskumine alustatuks. Korraga tohib laskuma lubada vaid he hppaja, muidu antakse veateade. Teised peavad olema selleks ajaks hppealast lahkunud.
* Loo leht kauguse sisestamiseks. Kaugus kirjutatakse parasjagu hppava vistleja juurde. Nita hpanud vistlejate paremusjrjestust koos kohtadega kauguste jrgi.

Andmebaasiksklused
Lihtsamaid andmebaasiksklusi on nd nidete juures kasutatud ning nende abiga saab mrgatava osa veebilehtedel vajalikest pringutest, lisamistest, kustutamistest ja muutmistest korda ajada. Rakenduse kasvades tulevad aga kasuks ka mned lisavimalused mida jrgnevalt tutvustatakse. Mitmega neist saab sama tulemuse saavutada ka PHP koodi abil, kuid SQL-laused vimaldavad tulemuse vahel lihtsamalt ja arusaadavamalt saavutada. 

Alustabel

Jrgnevate nidete aluseks on (niteks vistlusel) osalejate tabel kus iga inimese kohta kirjas eesnimi, kodukoha asula ning snniaasta.

CREATE TABLE osalejad(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  eesnimi VARCHAR(30),
  asula   VARCHAR(30),
  synniaasta INT
);

Tabeli struktuuri ngemiseks sobib ksklus EXPLAIN. Selle kaudu paistab vlja, millised tulbad tabelis on ning milline on iga tulba andmetp.

mysql> EXPLAIN osalejad;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| eesnimi    | varchar(30) | YES  |     | NULL    |                |
| asula      | varchar(30) | YES  |     | NULL    |                |
| synniaasta | int(11)     | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

Osalejate lisamiseks INSERT-ksklused

INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Mrt', 'Mrjamaa', 1993);
INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Mari', 'Mrjamaa', 1995);
INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Johannes', 'Valga', 1935);
INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Leida', 'Valga', 1938);
INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Vaike', 'Valga', 1959);
INSERT INTO osalejad (eesnimi, asula, synniaasta) VALUES ('Siim', 'Haapsalu', 1995);

Tulemusena saab osalejate loetelu vaadata.

mysql> SELECT * FROM osalejad;
+----+----------+----------+------------+
| id | eesnimi  | asula    | synniaasta |
+----+----------+----------+------------+
|  1 | Mrt     | Mrjamaa |       1993 |
|  2 | Mari     | Mrjamaa |       1995 |
|  3 | Johannes | Valga    |       1935 |
|  4 | Leida    | Valga    |       1938 |
|  5 | Vaike    | Valga    |       1959 |
|  6 | Siim     | Haapsalu |       1995 |
+----+----------+----------+------------+

lesandeid

Koosta sarnaselt autode tabel (regnr, mark, aasta)
Tutvu tabeli struktuuriga EXPLAIN-ksu abil
Lisa kmnekonna auto andmed. Sti andmed nnda, et oleksid mned kattuvad margid ning mni kattuv vljalaskeaasta.


Agregaatfunktsioonid

Agregaatfunktsioonid vtavad ette korraga mitu vrtust ning arvutavad nende phjal he tulemuse. Niteks funktsioon COUNT loeb kokku ridade arvu.


mysql> SELECT COUNT(*) FROM osalejad;
+----------+
| COUNT(*) |
+----------+
|        6 |
+----------+

Soovi korral saab vastustulba nime mber nimetada, kui tahetakse tulemuses valemi teksti vltida. 

mysql> SELECT COUNT(*) as kokku FROM osalejad;
+-------+
| kokku |
+-------+
|     6 |
+-------+


Tingimuste seadmine toimub endiselt. Ehk kui arvestatakse vaid ridu, kus asula on Valga, siis vaid need lhevad ka lugemisele.

mysql> SELECT COUNT(*) as kokku FROM osalejad WHERE asula='Valga';
+-------+
| kokku |
+-------+
|     3 |
+-------+

Sarnaselt ttavad ka funktsioonid MIN vhima, MAX suurima ning AVG aritmeetilise keskmise vrtuse leidmiseks. Sisendiks on vrtuste kogum, vljundiks arvutuse tulemus.


mysql> SELECT MIN(synniaasta) FROM osalejad;
+-----------------+
| MIN(synniaasta) |
+-----------------+
|            1935 |
+-----------------+


mysql> SELECT MAX(synniaasta) FROM osalejad;
+-----------------+
| MAX(synniaasta) |
+-----------------+
|            1995 |
+-----------------+
1 row in set (0.00 sec)


mysql> SELECT AVG(synniaasta) FROM osalejad;
+-----------------+
| AVG(synniaasta) |
+-----------------+
|       1969.1667 |
+-----------------+
1 row in set (0.05 sec)

Tekstide puhul on MySQLi juures mugav funktsiooni GROUP_CONCAT, mis etteantud tekstid heks pikaks tekstiks kokku liidab, pannes komad vahele.


mysql> SELECT GROUP_CONCAT(eesnimi) FROM osalejad;
+-------------------------------------+
| GROUP_CONCAT(eesnimi)               |
+-------------------------------------+
| Mrt,Mari,Johannes,Leida,Vaike,Siim |
+-------------------------------------+

lesandeid
Loo/otsi autode tabel autod(regnr, mark, aasta)
Vljasta autode arv
Vljasta suurim vljalaskeaasta
Vljasta vanima auto vljalaskeaasta
Vljasta keskmine vljalaskeaasta tabelites olevatest autodest. 

Grupeerimine
Lisaks niisama kokkuvtete tegemisele on agregaatfunktsioonidest enim kasu gruppide kaupa kokkuvtete juures. SQL vimaldab mugavasti kirja panna pringu nitamaks asulate kaupa, mitu osalejat igast asulast on. 

mysql> SELECT asula, COUNT(*) FROM osalejad GROUP BY asula;
+----------+----------+
| asula    | COUNT(*) |
+----------+----------+
| Haapsalu |        1 |
| Mrjamaa |        2 |
| Valga    |        3 |
+----------+----------+

Sarnaselt nagu COUNT(*) loeb ridu, sarnaselt MIN leiab vhima, MAX suurima vrtuse ning GROUP_CONCAT suudab tekstid jadaks kokku liita. 

SELECT asula, GROUP_CONCAT(eesnimi) FROM osalejad
  WHERE synniaasta>1980
  GROUP BY asula;

+----------+-----------------------+
| asula    | GROUP_CONCAT(eesnimi) |
+----------+-----------------------+
| Haapsalu | Siim                  |
| Mrjamaa | Mrt,Mari             |
+----------+-----------------------+


lesandeid

leidke iga asula kohta vhim snniaasta (neist, kes tabelis on)
leidke iga asula kohta seal olevate inimeste loetelu
leidke prast 1950. aastat sndinud inimeste loetelu asulate kaupa

leidke autode tabelist iga margi kohta vanima auto vljalaskeaasta
leidke iga margi kohta, mitu autot on tabelis
leidke iga vljalaskeaasta kohta, mitu auto on tabelis.




Alampringud
SQL-lauseid saab omavahel kombineerida. Igal pool, kus lauses on mni arv, loetelu vi tabel, on vimalik see sinna tekitada eraldi pringu abil. Nnda saab andmebaasis ra lahendada mned probleemid, mis muidu programmikoodi abi vajaksid. 

Alampringud vrtuse asendajana
Osalejate keskmise snniaasta saab ktte AVG funktsiooni abil. Pringu vastuseks on ks konkreetne arv - mis sellest, et andmebaasissteemi mistes on tegemist tabeliga, kus ks rida ja ks veerg.

mysql> SELECT AVG(synniaasta) FROM osalejad;
+-----------------+
| AVG(synniaasta) |
+-----------------+
|       1969.1667 |
+-----------------+

Kui see arv panna osalejate vljatrki juures vhima snniaasta tingimuseks, saame tulemuseks keskmisest nooremate kasutajate loetelu. 

SELECT eesnimi, synniaasta FROM osalejad WHERE synniaasta > 1969;

+---------+------------+
| eesnimi | synniaasta |
+---------+------------+
| Mrt    |       1993 |
| Mari    |       1995 |
| Siim    |       1995 |
+---------+------------+

ksikult vastuseid otsides vib ksitsi nii teha. Kui aga tahta, et veebilehele automaatselt kuvataks keskmisest nooremad kasutajad, siis on mugav kahest pringust ks teha. Muidu peaks esimese pringu tulemuse kuhugile eraldi muutujasse ksima ning selle hiljem teise pringu sisendisse tagasi saatma. Samas aga vib siin keskmist nitava arvu asmele kirjutada sulgudes vastava pringu ning lahendus ttabki he lausega. 

SELECT eesnimi, synniaasta FROM osalejad WHERE synniaasta > 
  (SELECT AVG(synniaasta) FROM osalejad);


+---------+------------+
| eesnimi | synniaasta |
+---------+------------+
| Mrt    |       1993 |
| Mari    |       1995 |
| Siim    |       1995 |
+---------+------------+


Sarnaselt vib ksida vanima osaleja snniaasta

SELECT MIN(synniaasta) FROM osalejad;

Ning pringuga vljastada kik selle snniaastaga inimesed. 

SELECT eesnimi, synniaasta FROM osalejad WHERE synniaasta=
  (SELECT MIN(synniaasta) FROM osalejad);
  

+----------+------------+
| eesnimi  | synniaasta |
+----------+------------+
| Johannes |       1935 |
+----------+------------+

Hetkel oli selle snniaastaga vaid Johannes, aga suurema rahvahulga puhul satub kergesti mitu inimest samale aastale.

Kui tahta vanimate osalejate vahemikku, siis aitab vike arvutustehe. Otsitakse osalejad, kes on vanimad vi vanimast kuni kmme aastat nooremad.

SELECT eesnimi, synniaasta FROM osalejad WHERE synniaasta<=
  (SELECT MIN(synniaasta)+10 FROM osalejad);

+----------+------------+
| eesnimi  | synniaasta |
+----------+------------+
| Johannes |       1935 |
| Leida    |       1938 |
+----------+------------+

Vajadusel saab valemeid ka pikemalt ning keerulisemalt kombineerida. 

-- Vljasta osalejad, kes jvad snniaastate keskmisesse kolmandikku
-- nt. kui vanim on sndinud 1950 ja noorim sndinud 2010, siis vljastage 
-- 1970-1990 sndinud

SELECT eesnimi, synniaasta FROM osalejad WHERE 
  synniaasta>=
    (SELECT MIN(synniaasta)+(MAX(synniaasta)-MIN(synniaasta))/3 FROM osalejad) 
  AND synniaasta<=
    (SELECT MAX(synniaasta)-(MAX(synniaasta)-MIN(synniaasta))/3 FROM osalejad);

    
+---------+------------+
| eesnimi | synniaasta |
+---------+------------+
| Vaike   |       1959 |
+---------+------------+

lesandeid
Leia kik keskmisest vanemad autod
Leia, mitme auto vljalaskeaastaks on tabelis kige noorema auto vljalaskeaasta.
Alampringud loetelu asendajana
Sellist olukorda tuleb harvem ette, sest sarnased olukorrad saab sageli mugavamalt lahendada tabelite hendamisega vi tingimuste kombineerimisega. Kui aga tahta keerukas pring kontrollitavamateks juppideks lahutada, siis on vastav alampring just omal kohal.

Snniaastate loetelu jrgi leiab osalejad jrgnevalt. 

SELECT * FROM osalejad WHERE synniaasta IN (1935, 1955, 1975, 1995);

+----+----------+----------+------------+
| id | eesnimi  | asula    | synniaasta |
+----+----------+----------+------------+
|  2 | Mari     | Mrjamaa |       1995 |
|  3 | Johannes | Valga    |       1935 |
|  6 | Siim     | Haapsalu |       1995 |
+----+----------+----------+------------+

Alampringu jrgi pan leida osalejaid, kelle eesnimi algab kskik millise tabelis oleva asula nimega. Vajalik vib selline pring olla niteks mne mistatuse vi seosemngu koostamise juures.  Ksklus LEFT(asula, 1) annab asula nime esimese the. Sna DISTINCT seal ees tleb, et korduvad thed tuleb eemaldada. Ehk siis niteks Vru ja Valga puhul oleks mlemal juhul esimene tht V, DISTINCT-piirangu puhul nidatakse aga vaid hte V-thte loetelus.


SELECT DISTINCT LEFT(asula, 1) FROM osalejad;
+----------------+
| LEFT(asula, 1) |
+----------------+
| M              |
| V              |
| H              |
+----------------+

Jrgneva alampringu tulemusena leitakse kik eesnimed, mis algavad kskik millise loetelus oleva asula algusthega

SELECT eesnimi FROM osalejad WHERE LEFT(eesnimi, 1) IN
  (SELECT DISTINCT LEFT(asula, 1) FROM osalejad);

  
+---------+
| eesnimi |
+---------+
| Mrt    |
| Mari    |
| Vaike   |
+---------+
  
lesandeid
Vljasta autode tabelist kik Fordid ja Volkswagenid
Vljasta kikide nende autode registrinumbrid, mis on sama marki, kui kskik milline nimekirjas oleva vhima snniaastaga auto (ehk siis millistel on margi jrgi lootus kaua vastu pidada). 
  
Alampringud tabeli asendajana
Kord pringu vastusena valminud tabelist saab teda mbritseva lausega edasi ksida. Ka on nnda mugav keerulist lesannet jagada viksemateks alamlesanneteks, mille td saab kshaaval kontrollid. Nide:

Pringuga leitakse igast asulast vanima osaleja snniaasta. 

SELECT asula, MIN(synniaasta) as vanimaasta FROM osalejad GROUP BY asula;

+----------+------------+
| asula    | vanimaasta |
+----------+------------+
| Haapsalu |       1995 |
| Mrjamaa |       1993 |
| Valga    |       1935 |
+----------+------------+

Allpool pannakse eelnev pring sulgudesse, nimetatakse ta ajutiseks tabeliks nimega tabel1 ning edasi tehakse pring juba sellele tabelile. Snniaastad vljastatakse kahekohalisena (eeldusel, et kik osalejad on sndinud enne aastat 2000).
 
SELECT asula, vanimaasta-1900 as kahekohaline_vanima_synniaasta FROM 
  (SELECT asula, MIN(synniaasta) as vanimaasta FROM osalejad GROUP BY asula) 
  AS tabel1;

+----------+--------------------------------+
| asula    | kahekohaline_vanima_synniaasta |
+----------+--------------------------------+
| Haapsalu |                             95 |
| Mrjamaa |                             93 |
| Valga    |                             35 |
+----------+--------------------------------+

lesandeid
Vljasta autode andmed nnda, et registrinumbrist oleks nha ainult numbrite osa. AS-ksuga anna vljastatavale tulbale nimeks numbrid.
Kasuta eelnevast pringust tulevat tabelit sisendiks pringule, kus vljastatakse iga erineva numbrikombinatsiooni kohta mitu autot tabelis sellise numbriosaga on. Ehk siis kui autode hulgas on registrinubrid 123ABC ning 123BCD, siis tulemusena  vljastatakse, et kombinatsiooni 123 esineb kaks korda. 

Rekursiivsed alampringud
Siiani piisas andmebaasimootoril, kui alampringu tulemus arvutati vlja ks kord ning edasi hakati juba sealt  vrtusi vtma edasiseks kasutamiseks. Rekursiivsete alampringute puhul aga tuleb alampring iga tulemusrea vljastamisel uuesti tle panna. Nitena leitakse iga asula kohta inimesed, kelle snniaasta on suurem vi vrdne, kui sealt asulast tulevate osalejate keskmine snniaasta. Ehk siis iga asula kohta sealsed vanemad inimesed. 



SELECT eesnimi, asula, synniaasta FROM osalejad AS tabel1 WHERE synniaasta <=
  (SELECT AVG(synniaasta) FROM osalejad AS tabel2 
    WHERE tabel2.asula=tabel1.asula);


+----------+----------+------------+
| eesnimi  | asula    | synniaasta |
+----------+----------+------------+
| Mrt     | Mrjamaa |       1993 |
| Johannes | Valga    |       1935 |
| Leida    | Valga    |       1938 |
| Siim     | Haapsalu |       1995 |
+----------+----------+------------+

Tasub thele panna, et tabel osalejad on siin pringus kaks korda. hel puhul antakse talle nimeks tabel1, teisel puhul tabel2. Nii saab tingimuses mrata, et vrreldakse tabeli he koopia asula tulba vrtust tabeli teise koopia asula tulba vrtusega. Ehk siis trkitakse vlja esimese koopia ridu. Iga rea puhul vetakse tagapool olevas alampringus nende osalejate snniaastate keskmine, kes on prit temaga samast asulast.

lesandeid

Vljasta autod, mis on oma margi ulatuses kige vanema vljalaskeaastaga (neid vib olla ka he margi kohta mitu, kui on samal aastal vlja tulnud)
Vljasta iga auto kohta, kui palju ta on noorem tabelis olevast seda marki kige vanemast sidukist.

Andmetabeli struktuuri muutmine
T kigus tuleb ikka vahel vaja andmetabelisse tulpi lisada, nende nime vi tpi muuta vi tulpi kustutada. Selle juures aitab ksklus ALTER TABLE
Lisamiseks ksklus ADD, edasi juba tulba nimi, tp ja vajadusel vaikevrtus nagu loomise juures ksu CREATE TABLE puhul. Lisatakse tulp sugu, pikkuseks ks tht ning esialgu kirjutatakse kigile sinna vrtus M.

mysql> ALTER TABLE osalejad ADD sugu CHAR(1) DEFAULT 'M';
Query OK, 6 rows affected (0.03 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select  * from osalejad;
+----+----------+----------+------------+------+
| id | eesnimi  | asula    | synniaasta | sugu |
+----+----------+----------+------------+------+
|  1 | Mrt     | Mrjamaa |       1993 | M    |
|  2 | Mari     | Mrjamaa |       1995 | M    |
|  3 | Johannes | Valga    |       1935 | M    |
|  4 | Leida    | Valga    |       1938 | M    |
|  5 | Vaike    | Valga    |       1959 | M    |
|  6 | Siim     | Haapsalu |       1995 | M    |
+----+----------+----------+------------+------+

Naistele oma soo mrkimiseks aitab loetelu IN.

mysql> UPDATE osalejad SET sugu='N' WHERE id IN (2, 4, 5);
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select  * from osalejad;
+----+----------+----------+------------+------+
| id | eesnimi  | asula    | synniaasta | sugu |
+----+----------+----------+------------+------+
|  1 | Mrt     | Mrjamaa |       1993 | M    |
|  2 | Mari     | Mrjamaa |       1995 | N    |
|  3 | Johannes | Valga    |       1935 | M    |
|  4 | Leida    | Valga    |       1938 | N    |
|  5 | Vaike    | Valga    |       1959 | N    |
|  6 | Siim     | Haapsalu |       1995 | M    |
+----+----------+----------+------------+------+
6 rows in set (0.00 sec)

Tulba tbi muutmiseks sna CHANGE. Sellele jrgneb kigepealt tulba vana nimi, siis uus nimi ja uus tp. Kui nime ei muudeta, tuleb nime kaks korda. 

mysql> ALTER TABLE osalejad CHANGE sugu sugu VARCHAR(5);
Query OK, 6 rows affected (0.02 sec)
Records: 6  Duplicates: 0  Warnings: 0

Prast tulba muutmist saab teksti sisu ra vahetada. 

mysql> UPDATE osalejad SET sugu='Naine' WHERE sugu='N';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select  * from osalejad;
+----+----------+----------+------------+-------+
| id | eesnimi  | asula    | synniaasta | sugu  |
+----+----------+----------+------------+-------+
|  1 | Mrt     | Mrjamaa |       1993 | M     |
|  2 | Mari     | Mrjamaa |       1995 | Naine |
|  3 | Johannes | Valga    |       1935 | M     |
|  4 | Leida    | Valga    |       1938 | Naine |
|  5 | Vaike    | Valga    |       1959 | Naine |
|  6 | Siim     | Haapsalu |       1995 | M     |
+----+----------+----------+------------+-------+

Kui lpuks selgus, et sugu pole vaja siiski talletada, siis tulba eemaldamiseks ksklus DROP.

mysql> ALTER TABLE osalejad DROP sugu;
Query OK, 6 rows affected (0.02 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select  * from osalejad;
+----+----------+----------+------------+
| id | eesnimi  | asula    | synniaasta |
+----+----------+----------+------------+
|  1 | Mrt     | Mrjamaa |       1993 |
|  2 | Mari     | Mrjamaa |       1995 |
|  3 | Johannes | Valga    |       1935 |
|  4 | Leida    | Valga    |       1938 |
|  5 | Vaike    | Valga    |       1959 |
|  6 | Siim     | Haapsalu |       1995 |
+----+----------+----------+------------+

lesandeid
Lisa autode tabelile tulp omanik. Tbiks VARCHAR(30), vaikevrtuseks Tamm.
Vaheta UPDATE abil mned perekonnanimed. 
Eemalda tulp omanik. 

Autode leht

Loo/otsi autode tabel (regnr, mark, aasta)
Vimalda andmeid veebi kaudu lisada
Koosta statistikaleht nitamaks iga margi kohta, mitu autot sellest tabelis on.
Lisaks nidatakse iga margi kohta tabelis vanima auto registreerimisaasta
Vajutades sellele aastale, nidatakse eraldi lehel vastavat marki tol aastal registreeritud sidukite registreerimisnumbrid (neid vib olla mitu)
Iga margi vanima aasta krval on kirjas number, mitu masinat sellest margist selle aasta kohta tabelis kirjas on.
Krval nidatakse vastava margi vanimast masinast kuni viis aastat nooremate autode arvu.
Arvule vajutades nidatakse vastavate autode andmed.

Automarkide sisestamiseks luuakse rippmen markide loeteluga. (HTMLi select-element)
Autode lisamise juures on margi sisestamiseks rippmen juba sisestatud autode markide nimedega (DISTINCT-sna SQL-lauses)
Automargi sisestamiseks on tekstivli ja rippmen mlemad. Kui tekstivljas on vrtus (!empty($_REQUEST["margitekst"])), siis vetakse see margi nimeks, muidu vetakse rippmenst valitud vrtus. 

Sessioonid, meldimine
Brauseri lahtioleku ajal mitme jrjestikuse lehe avamise juures histe muutujate meelespidamiseks kasutatakse sessioone. Levinuim on selle kasutamine sisselogimise mrkimiseks, kuid sessioonide abil on mugav meeles pidada ka niteks kasutaja ostukorvi valitud kaupa vi vastaval peval kehtivat taustavrvieelistust. PHPs erilist massiivi nimega $_SESSION saab kasutada eri lehtedel brauseri lahtioleku ajal. Siin lihtsalt demonide sessiooni kasutamisest. 

Sessioonimassiivi kasutamiseks tuleb lehe algusesse panna ksklus session_start(). See saadab brauserisse kpsise, mille abil end jrgmisel korral identifitseerida saab. Justnagu kingsepa juurde saapaid parandada viies antakse vastu plekist  etoon, mille esitamisel jrgmisel korral nende saabaste kohta infot vi suisa saapad ktte saab. 

Muutuja olemasolu kontrollib ksklus isSet. Esmasel sisenemisel on muutuja loendur tundmatu ning sinna kirjutatakse vrtus 0. Igal jrgmisel lehe avamise korral loetakse muutuja sealt taas vlja ning suurendatakse vrtust he vrra ja trkitakse tulemus vlja.

loendur.php

<?php
  session_start();
  if(!isSet($_SESSION["loendur"])){
    $_SESSION["loendur"]=0;
  }
  $_SESSION["loendur"]++;
  echo $_SESSION["loendur"];

Iga kivitamise peale ilmub ekraanile he vrra suurem number. ehk siis esimest korda 

1

ning teist korda 

2

lesandeid
Luba kasutajal mrkida/sisestada oma lemmikvrvikood. Jta see sessioonimuutujas meelde. Igal jrgmisel klastusel nita lehte vastavat vrvi taustaga. 

meldimisleht.php

Thtsaks sessioonide kasutuskohaks on sisse- ja vljalogimised. Siin on pisike nide lehe sisse kirjutatud kasutajatunnustega sisenemiseks. Kuigi turvaliseks sellist lhenemist pidada ei saa, samas pris kogemata tulnud otsimootorid peletab eemale ning kuni lehe lhtekood avalikult kttesaadav pole, senikaua peab ka uudistaja parooli aimamisega pead vaevama. 

Esmasel avamisel kuvatakse lehel kasutajanime ja parooli sisestamise vorm. Andmete saatmisel serverisse ehk kasutajanime-nimelise parameetri leidumisel kontrollitakse kasutajanime ja parooli sobivust. Sobivuse korral jetakse sessioonimuutujasse meelde kasutajanimi. 

Sessioonimuutujas kasutajanime leidumisel nidatakse lubatud tegevuste loetelu, seekord viidet kellaaja vaatamise lehele. Samuti lahkumisksklus, mis kutsub sama lehe vlja parameetriga nimega lahku. Lahkumise peale eemaldatakse kasutajanime hoidev sessioonimuutuja ning lehe avamisel kuvatakse taas sisselogimisvormi.

<?php
  session_start();
  if(isSet($_REQUEST["kasutajanimi"])){
     if($_REQUEST["kasutajanimi"]=="juku" and $_REQUEST["parool"]=="kala"){
          $_SESSION["kasutajanimi"]=$_REQUEST["kasutajanimi"];
     }
  }
  if(isSet($_REQUEST["lahku"])){
     unset($_SESSION["kasutajanimi"]);
  }
?>
<!doctype html>
<html>
  <head>
     <title>Meldimine</title>
  </head>
  <body>
    <?php if(isSet($_SESSION["kasutajanimi"])): ?>
      Tere, <?php echo $_SESSION["kasutajanimi"]; ?>
      <a href="?lahku=jah">lahku</a>
      <ul>
        <li><a href="kellaleht.php">Kellaaja vaatamine</a></li>
      </ul>
    <?php else: ?>
     <form action="?" method="post">
      <dl>
        <dt>Kasutajanimi:</dt>
        <dd><input type="text" name="kasutajanimi" /></dd>
        <dt>Parool:</dt>
        <dd><input type="password" name="parool" /></dd>
        <dd><input type="submit" value="Sisesta" /></dd>
      </dl>
     </form>
    <?php endif ?>
  </body>
</html>





lesandeid

Pane nide tle
Lisa sisselogimisiguslike hulka teine kasutaja kasutajanimega kati ja parooliga karu


kellaleht.php
Parooliga kaitstud lehe nitena pandi siin kokku kellaaega nitav leht. Sessioonimuutujate kasutamiseks vaja lehe algusesse session_start(). Edasi sessioonimassiivis oleva kasutajanime puudumisel saadetakse vlja piseksklus, et tuleb sisselogimiseks liikuda meldimislehele. Ning prast seda on kindlasti tarvilik ksklus exit() - muidu vimalik nt. telnet-henduse abil veebiserverit pommitades ikkagi lehe sisu ktte saada sltumata saadetud headerist. 

<?php
  session_start();
  if(!isSet($_SESSION["kasutajanimi"])){
    header("Location: meldimisleht.php");
    exit();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Kellaaja leht</title>
  </head>
  <body>
     Tere,  <?php echo $_SESSION["kasutajanimi"]; ?> 
       <div style="float: right">
         <a href="meldimisleht.php">avaleht</a>,
         <a href="meldimisleht.php?lahku=jah">lahku</a>
       </div>
     <h1>Kellaaeg</h1>  
     <div>     
       <?php
         date_default_timezone_set("Europe/Tallinn");
         echo date("H:i:s");
       ?>
     </div>
  </body>
</html>






lesandeid

Pane nide tle
Lisa kellalehe krvale veel teine parooliga kaitstud leht, mil pealkirjaks statistika
Statistikalehel talleta andmebaasi, mitu korda sinna sisenenud registreeritud kasutaja, mitmel korral pdnud siseneda anonmne kasutaja.
Nita tulemusi ka lehel


Parool andmebaasis, rollid

Paroole ei soovitata lahtiselt programmikoodi ega andmebaasilahtrite sisse kirjutada, sest sealtkaudu on tegemist ilmselge turvaauguga. Isegi siis, kui vlisele vaatajale pole serveris olev kood vi andmetabelite vrtused otse nhtavad - ka siis juhtub kllalt kergesti, et varukoopia kaudu pseb sisu avalikuks. Selliste murede lahendamiseks on meldud rsifunktsioonid (hash). hesuunaline funktsioon, kus avatekstist rsi saab kergesti, tagurpidi aga vga vaevaliselt ehk siis peaaegu ldse mitte. Rsifunktsioone ja algoritme on mitmeid, MySQLis selleks funktsioon nimega PASSWORD();


mysql> select password('kala');
+-------------------------------------------+
| password('kala')                          |
+-------------------------------------------+
| *C25867096CC67DD77ACB514CE80CC1B06A9438BF |
+-------------------------------------------+

Rsifunktsioon (hash) teeb etteantud tekstist kindla pikkuse ja segase sisuga rsi, mis sama teksti puhul on alati hesugune, natuke muudetud teksti puhul aga juba tundmatuseni moondunud.

mysql> select password('kala2');
+-------------------------------------------+
| password('kala2')                         |
+-------------------------------------------+
| *37974A6F861C147D88F05FC723CCC33D92FAB21B |
+-------------------------------------------+

Samast tekstist tuleb sama algoritmi jrgi alati sama rsi. Et sama levinud parooliga kasutajad poleks paroolide tabelist kergesti leitavad, siis heks vimaluseks paroolide rsimisel on sinna klge lisada ka kasutajanimi. Ehk siis jrgnevalt kasutaja juku parooliga kala annab jrgmise rsi.

mysql> select password('juku_kala');
+-------------------------------------------+
| password('juku_kala')                     |
+-------------------------------------------+
| *A958B818C34DF2761B8182C571C81D8963648AD5 |
+-------------------------------------------+

Kasutajate haldamiseks tabel kasutajanimedega (mis on juba ise unikaalseks primaarvtmeks ning eraldi id-d ei vaja). Lisaks siis vljad paroolirsi tarbeks ning kasutaja rolli mramiseks (eeldusel, et siin rakenduses on igal kasutajal ks roll. 

CREATE TABLE kasutajad(
  knimi VARCHAR(12) NOT NULL PRIMARY KEY,
  paroolir2si CHAR(41),
  roll VARCHAR(12)
);

Mned andmed sisse. 

INSERT INTO kasutajad VALUES ('juku', PASSWORD('juku_kala'), 'haldur');
INSERT INTO kasutajad VALUES ('mati', PASSWORD('mati_uni'), 'inspektor');
INSERT INTO kasutajad VALUES ('sass', PASSWORD('sass_sepp'), 'inspektor');

Vaadates paistab tulemus jrgnevalt

mysql> SELECT * FROM kasutajad;
+-------+-------------------------------------------+-----------+
| knimi | paroolir2si                               | roll      |
+-------+-------------------------------------------+-----------+
| juku  | *A958B818C34DF2761B8182C571C81D8963648AD5 | haldur    |
| mati  | *E3F1BECAEE33C947575193F4BC4A4613AD5136AA | inspektor |
| sass  | *D6CED82E7E50A3801B05CD76B450C365E64A26EA | inspektor |
+-------+-------------------------------------------+-----------+



meldimisleht.php
Serveritabelist uuritakse vastava kasutajanime ning paroolirsiga kasutajat. htlasi ksitakse vlja ka tema roll. Vastavalt rollile otsustatakse, milliseid viiteid mens nidata. 

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  session_start();
  if(isSet($_REQUEST["kasutajanimi"])){
     $kask=$yhendus->prepare(
      "SELECT roll FROM kasutajad WHERE knimi=? AND paroolir2si=PASSWORD(?)");
     $knimiparool=$_REQUEST["kasutajanimi"]."_".$_REQUEST["parool"];
     $kask->bind_param("ss", $_REQUEST["kasutajanimi"], $knimiparool);
     $kask->bind_result($roll);
     $kask->execute();
     if($kask->fetch()){
         $_SESSION["kasutajanimi"]=$_REQUEST["kasutajanimi"];
         $_SESSION["roll"]=$roll;
         $kask->close();
     }
  }
  if(isSet($_REQUEST["lahku"])){
     unset($_SESSION["kasutajanimi"]);
     unset($_SESSION["roll"]);
  }
?>
<!doctype html>
<html>
  <head>
     <title>Meldimine</title>
  </head>
  <body>
    <?php if(isSet($_SESSION["kasutajanimi"])): ?>
      Tere, <?php echo $_SESSION["roll"]." ".$_SESSION["kasutajanimi"]; ?>
      <a href="?lahku=jah">lahku</a>
      <ul>
        <li><a href="kellaleht.php">Kellaaja vaatamine</a></li>
        <?php if($_SESSION["roll"]=="haldur"): ?>
          <li><a href="haldusleht.php">Haldamine</a></li>        
        <?php endif ?>
      </ul>
    <?php else: ?>
     <form action="?" method="post">
      <dl>
        <dt>Kasutajanimi:</dt>
        <dd><input type="text" name="kasutajanimi" /></dd>
        <dt>Parool:</dt>
        <dd><input type="password" name="parool" /></dd>
        <dd><input type="submit" value="Sisesta" /></dd>
      </dl>
     </form>
    <?php endif ?>
  </body>
</html>
<?php
  $yhendus->close();
?>





kellaleht.php
Kellaleht sarnane kui eelnevas nites. Lihtsalt pises kontrollitakse, kas kasutajal on igus lehele siseneda. Kui jah, siis lastakse ta edasi. Kui mitte, siis suunatakse parooli sisestama.

<?php
  session_start();
  if(!isSet($_SESSION["kasutajanimi"])){
    header("Location: meldimisleht.php");
    exit();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Kellaaja leht</title>
  </head>
  <body>
     Tere,  <?php echo $_SESSION["roll"]." ".$_SESSION["kasutajanimi"]; ?> 
       <div style="float: right">
         <a href="meldimisleht.php">avaleht</a>,
         <a href="meldimisleht.php?lahku=jah">lahku</a>
       </div>
     <h1>Kellaaeg</h1>  
     <div>     
       <?php
         date_default_timezone_set("Europe/Tallinn");
         echo date("H:i:s");
       ?>
     </div>
  </body>
</html>








haldusleht.php

Halduslehel kontrollitakse lisaks ka kasutaja rolli. Et ei piisa vaid sisse logimisest, vaid kontrollitakse, et kas kasutajal on ka sisenemistabelis kirjas sobivad igused. 

<?php
  session_start();
  if(!isSet($_SESSION["kasutajanimi"])){
    header("Location: meldimisleht.php");
    exit();
  }
  if($_SESSION["roll"]!="haldur"){
    header("Location: meldimisleht.php");
    exit();  
  }
?>
<!doctype html>
<html>
  <head>
    <title>Haldusleht</title>
  </head>
  <body>
     Tere,  <?php echo $_SESSION["roll"]." ".$_SESSION["kasutajanimi"]; ?> 
       <div style="float: right">
         <a href="meldimisleht.php">avaleht</a>,
         <a href="meldimisleht.php?lahku=jah">lahku</a>
       </div>
     <h1>Haldamise leht</h1>  
     <div>     
       <h2>Registreerimine</h2>
       <h2>Kinnitamine</h2>
     </div>
  </body>
</html>



lesandeid

Kivita nide. Lisa mned kasutajad, veendu lehestiku toimimises.
Lisa kasutaja rolliga "ametnik". 
Koosta leht, kus nha kasutajate tabelise olevate kasutajate arv ning  kasutajate arvud rollide kaupa. 
Korralda igused ja viited nnda, et seda lehte nevad ainult haldur ja ametnik.

lesanne  -  Arvutiparanduste halduslehestik
Jrgneva parandustkoja veebilehestiku loomise harjutus annab phjuse meelde tuletada eelpool kirjeldatud mitmesugused andmebaasiksklused ning annab loodetavasti kogemuse sarnase priselus mitmel kujul ettetuleva veebikaudse td abistava lehestiku loomisel.

Ettevalmistus
Koosta andmebaasitabel parandused (id, kirjeldus, tehnik, kommentaar, valmis). 
Otsi les eelmise lesande juurde kuulunud tabel (knimi, paroolir2si, roll)
Lisa tabelisse mned tehnikud oma kasutajanimede ja paroolidega.
Koosta veebileht arvutil oleva vea kirjelduse lisamiseks paranduste baasi.
Haldustd
Tde vastuvtmise lehel on nha need sisestatud kirjeldused, kus tehnik pole veel valitud.
Lehel on vimalik vigaseid vi pahatahtlikke kirjeldusi kustutada.
Lehel saab sisestada (vi kavalamal juhul rippmenst valida) tga seotud tehniku.
Loo lehestikule sisselogimisleht.
Kaitse tde vastuvtmise leht nnda parooliga, et sinna pseb vaid haldur.
Sisenemislehel saab sisse logida ka tehnik.
Tehnikule nidatakse neid tid, mille titjaks ta on mratud ning mis pole veel valmis.
Tehnik saab valitud tle lisada kommentaare. Kommentaaride juurde salvestatakse ka selle lisamise aeg.
Tehnik saab t mrata valmiks. Siis seda td enam tehniku lehel nha pole.
Juhul, kui tehnikul pole parajasti htki pooleliolevat td, siis on lehel selle kohta vastav teade.
Statistika
Tde vastuvtmise lehe allservas kuvatakse, mitu pooleliolevat td parajasti igal tehnikul on. 
T lisamise juurde lisatakse automaatselt PHP abil lisamisajaga tidetav tulp. Lisamisaeg on nha teistel lehtedel t kirjelduse juures
Automaatselt salvestatakse ka tehniku mramise ning t valmiks saamise aeg. 
Uuri MySQLi funktsiooni TIMEDIFF, nita, kui palju kulus tehnikul t tegemiseks aega
Sorteeri tehtud td kulunud aja jrgi
Nita iga tehniku puhul tema kige rohkem aega nudnud td
nnitle tehnikut iga tema viienda t lpetamise puhul
Lisa kogu ssteemis nnitlus iga kmnenda t lpetamise puhul


Lahendusi ja tiendusi

Algus

Muutuja, tingimuslause

* Lisa muutuja perekonnanime tarbeks. Anna sinna vrtus ja kasuta seda lausetes.

Muutujaid saab rahumeeli juurde lisada ja lausetes kasutada. Lisathelepanekuna/soovitusena siin nites, et juhul, kui PHP kaudu ei kuvata otse veebilehe teksti, vaid kik tegevus toimub kskude ning vljund echo-lause kaudu, sellisel juhul lubatatakse ja soovitatakse php-plokki mitte lpetada. 

<?php
  $eesnimi="Juku";
  $perekonnanimi="Juurikas";
  echo "Tere, $eesnimi $perekonnanimi!";


Tulemus lehel:

Tere, Juku Juurikas! 


* Koosta eraldi leht, kus kirjas temperatuur. Vljasta, kas vesi on sellel temperatuuril vedel vi muutub jks.

Valikuks olevad if-laused saab kirja panna hekaupa. Kui aga soovitakse, et saaks ktte ka olukorra, mis helegi valikule ei vasta, siis aitab vastasel juhul toimiv else. Kusjuures nndamoodi vib ka mitu tingimust htejrge paigutada. 

<?php
//  $temperatuur=-17;
  $temperatuur=0;
  if($temperatuur>0){echo "Vesi on vedel";}
  else if($temperatuur<0){echo "Vesi muutub jks";}
  else {echo "Vesi jb veeks, j jb jks";}


Vljund praegusel juhul:

Vesi jb veeks, j jb jks 


Kellaaeg

* Nita kellaajast vaid tunde ja minuteid
* Nita vlja kuupev. Y thistab aastat, m kuud ning d peva. 


<!doctype html>
<html>
  <head>
     <title>Kellaleht</title>
  </head>
  <body>
     <h1>Kellaaeg</h1>
	 <?php
	   date_default_timezone_set("Europe/Tallinn");
	   echo "Tna on ".date("d.m.Y").".";
       echo "<br />";
       echo "Kell on ".date("H:i");
	 ?>
  </body>
</html>

Vljund:
Kellaaeg
Tna on 07.02.2013.
Kell on 17:29 

Tollikalkulaator

* Koosta kalkulaator sentimeetritest tollide arvutamiseks. Jagamismrgiks on kaldkriips /.

Phinites olnud ksklus empty peab tulemuse thjaks nii muutuja puudumisel, vrtuse puudumisel kui nullilise vrtuse korral. Soovi korral saab aga vastuseid tpsemalt ksida. All nites olev isset on tene vaid muutuja olemasolu korral. See thendab, et kui leht esimest korda avatakse, siis on aadressiribal vaid lehe failinimi ilma jrgneva ksimrgi ja muutujateta. Ning sellisel juhul muutuja $_REQUEST[sentimeetrid] puudub ja kasutajale teatab leht, et ootan sisestust. 
Ksk strlen kontrollib sisestatud teksti pikkust. Ehk kui see annab vrtuse nulli, siis on kll kasutaja thjas tekstivljas sisestusklahvi vajutanud, aga pole midagi serverisse saatmiseks sisse kirjutanud. 
Jrgmine kontroll is_numeric uurib, et kas sisestatud vrtus ikka arvuks muudetav on. Kui keegi lihtsalt mingit juttu kirjutas, siis selle pealt pole arvutil samuti vimalik hakata tolle arvutama.
Alles siis kui kogu kadalipp on nneks linud, siis vib kasutajale soovitud tulemuse arvutada. Kuna jagamisel kipub kergesti palju komakohti tekkima, siis round-funktsioon aitab need paika sttida, praegusel juhul kaks kohta prast koma.

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Tollikalkulaator</h1>
     <form action="?">
	     Sentimeetrite arv:
		   <input type="text" name="sentimeetrid" />
	 </form>
	 <?php
	   if(isset($_REQUEST["sentimeetrid"])){
          if(strlen($_REQUEST["sentimeetrid"])>0){
            if(is_numeric($_REQUEST["sentimeetrid"])){
               echo round($_REQUEST["sentimeetrid"]/2.54, 2)." tolli.";
            } else {
               echo "Sisend pole arv";
            }
          } else {
           echo "Jtsid vastuse sisestamata";
          }
	   } else {
	     echo "Ootan sisestust.";
	   }
	 ?>
  </body>
</html>


* Koosta kalkulaator, kus sisestus on meetrites. Vljastatakse, mitu kilomeetrit see on, mitu detsimeetrit, mitu sentimeetrit ning mitu millimeetrit see on.

Arvutada vib rahulikult iga tehte eraldi tehes. Nitena aga paigutatakse koefitsiendid eraldi massiivi (array) ning siis tulemuse leidmiseks kiakse see foreach-tskliga jrjest lbi, et mugamalt tulemused omale silma ette saada. 

<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Meetermdustiku teisendused</h1>
     <form action="?">
	     Meetrite arv:
		   <input type="text" name="meetrid" />
	 </form>
	 <?php
      if(!empty($_REQUEST["meetrid"])){
       $koef=array();
       $koef["km"]=1000;
       $koef["dm"]=0.1;
       $koef["cm"]=0.01;
       $koef["mm"]=0.001;
       echo "$_REQUEST[meetrid] meetrit on: <ul>";
       foreach($koef as $yhik => $suhe){
         echo "<li>".$_REQUEST[meetrid]/$suhe." $yhik</li>";
       }
       echo "</ul>";
      }
	 ?>     
  </body>
</html>

Vljund:
Meetermdustiku teisendused
Meetrite arv:  
4 meetrit on: 
0.004 km
40 dm
400 cm
4000 mm


Ostusumma arvutamine

* Loo toodetest kaks rippmend eri nimedega. Nita, kui suur summa tuleb kummagi toote kohta eraldi ning kui palju kahe toote peale kokku.


<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
Kaup:
       <select name="hind1">
	      <option value="">Vali kaup ...</option>
	      <option value="0.70">Leib</option>
	      <option value="0.60">Sai</option>
	      <option value="0.50">Piim</option>
	   </select>
Ostetav kogus:
		   <input type="text" name="kogus1" />
		  <br />
Kaup:
       <select name="hind2">
	      <option value="">Vali kaup ...</option>
	      <option value="0.70">Leib</option>
	      <option value="0.60">Sai</option>
	      <option value="0.50">Piim</option>
	   </select>
Ostetav kogus:
		   <input type="text" name="kogus2" />
		   <input type="submit" value="OK"  /> <br />
	 </form>
	 <?php
	   if(!empty($_REQUEST["hind1"])){
          $summa1=$_REQUEST["hind1"]*$_REQUEST["kogus1"];
          $summa2=$_REQUEST["hind2"]*$_REQUEST["kogus2"];
          echo "Ostud $summa1 EUR ja $summa2 EUR, kokku ".
            ($summa1+$summa2)." EUR.";
	   }
	 ?>
  </body>
</html>

Andmete sisestamine:



Rippmende value-atribuutide sisu juab aadressiriba pidi serverprogrammi uue kivituskorra juurde kohale. 


Andmed massiivist

* Pane lehele kaks valikupaari kaupade ja koguste tarbeks. Nita kummagi paari tarbeks summa eraldi ning lppu kogusumma.

Tskliga kirjutatakse kummagi rippmen andmed lehele, samuti valitavad kogused. 


<?php
   $kaubad=array();
   $kaubad["vorst"]="2.50";
   $kaubad["juust"]="3.00";
   $kaubad["kartul"]="0.45";
?>
<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
      Kaup:
       <select name="hind1">
	      <option value="">Vali kaup ...</option>
        <?php
          foreach($kaubad as $nimetus => $hind){
		     echo "<option value='$hind'>$nimetus</option>";
          }
        ?>		
       </select>
          Ostetav kogus:
		   <select name="kogus1">
		      <option>Vali kogus</option>
            <?php
             for($nr=1; $nr<=10; $nr++){
               echo "<option>$nr</option>\n";
             }
            ?>
		   </select>
           <br />
       Kaup:
       <select name="hind2">
	      <option value="">Vali kaup ...</option>
        <?php
          foreach($kaubad as $nimetus => $hind){
		     echo "<option value='$hind'>$nimetus</option>";
          }
        ?>		
       </select>
          Ostetav kogus:
		   <select name="kogus2">
		      <option>Vali kogus</option>
            <?php
             for($nr=1; $nr<=10; $nr++){
               echo "<option>$nr</option>\n";
             }
            ?>
		   </select>

		   <input type="submit" value="OK"  />
      </form>
      <?php
       if(!empty($_REQUEST["hind1"])){
          $summa1=$_REQUEST["hind1"]*$_REQUEST["kogus1"];
          $summa2=$_REQUEST["hind2"]*$_REQUEST["kogus2"];
          echo "Ostud $summa1 EUR ja $summa2 EUR, kokku ".
            ($summa1+$summa2)." EUR.";
	   }
      ?>
  </body>
</html>




Andmed liiguvad taas aadressiriba kaudu ning tulemuse juures saab nad kinni pda ja summad arvutada.



Juurde nide, kuidas PHP-koodis saab ostude kogust mrata ning luua sobiv arv rippmensid.

Lisandub muutuja $ostudekogus. Sobiva arvu kaupa- ja kogusevalikute loomise juures aitab tskkel 

for($ostunr=1; $ostunr<=$ostudekogus; $ostunr++)

Hilisema eristamise tarbeks peab iga rippmen saama eraldi numbri. 

<select name="hind<?php echo $ostunr; ?>">

Esimese puhul siis nimeks hind1, teise juures hind2 jne. 

Samuti tuleb prast summa kokku lugemisel otsida andmeid erinevatest REQUEST-massiivi elementidest. nneks lubab $ostunr-muutuja ka sealt sobivast kohast andmed vlja vtta. 

         $kogusumma=0;
         for($ostunr=1; $ostunr<=$ostudekogus; $ostunr++){
           $summa=$_REQUEST["hind$ostunr"]*$_REQUEST["kogus$ostunr"];
           echo "<li>$summa EUR</li>";
           $kogusumma+=$summa;
         }  

Edasi kood tervikuna.

<?php
   $kaubad=array();
   $kaubad["vorst"]="2.50";
   $kaubad["juust"]="3.00";
   $kaubad["kartul"]="0.45";
   $ostudekogus=5;
?>
<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Summa kalkulaator</h1>
     <form action="?">
     <?php
       for($ostunr=1; $ostunr<=$ostudekogus; $ostunr++){
     ?>
      Kaup:
       <select name="hind<?php echo $ostunr; ?>">
	      <option value="">Vali kaup ...</option>
        <?php
          foreach($kaubad as $nimetus => $hind){
		     echo "<option value='$hind'>$nimetus</option>";
          }
        ?>		
       </select>
          Ostetav kogus:
		   <select name="kogus<?php echo $ostunr; ?>">
		      <option>Vali kogus</option>
            <?php
             for($nr=1; $nr<=10; $nr++){
               echo "<option>$nr</option>\n";
             }
            ?>
		   </select> <br />
      <?php
         }
      ?>   
          
		   <input type="submit" value="OK"  />
      </form>
      <?php
       if(!empty($_REQUEST["hind1"])){
         echo "Ostud: <ol>";
         $kogusumma=0;
         for($ostunr=1; $ostunr<=$ostudekogus; $ostunr++){
           $summa=$_REQUEST["hind$ostunr"]*$_REQUEST["kogus$ostunr"];
           echo "<li>$summa EUR</li>";
           $kogusumma+=$summa;
         }          
         echo "</ol>";
         echo "Kokku $kogusumma EUR";
	   }
      ?>
  </body>
</html>



Titmiseks ilmusid viie kauba tarbeks rippmend nagu tellitud.


Vastuse juures ldi tulemused kokku ning nidati kui palju iga ost kulutas.




* Koosta massiiv, mille vtmeteks on liini bussipeatuste kaugused algpeatusest ning vrtusteks vastavate bussipeatuste nimed. Koosta samade andmetega kaks eri nimedega rippmend. Kasutaja valib kaks peatust, talle teatatakse, kui suur on nende peatuste vahe kilomeetrites.

Lhte- ja sihtpeatuse valimiseks kummalegi oma rippmen. Kuna hest kaugusest teise lahutamisel vib tulemus olla ka negatiivne, siis abs-funktsioon aitab absoluutvrtuse abil sellest murest le saada. 

<?php
   $peatused=array();
   $peatused["Haapsalu"]=0;
   $peatused["Taebla"]=12;
   $peatused["Palivere"]=22;
   $peatused["Risti"]=32;
   $peatused["Nissi"]=50;
   $peatused["Tallinn"]=100;
?>
<!doctype html>
<html>
  <head>
     <title>Arvutamine</title>
  </head>
  <body>
     <h1>Kauguse kalkulaator</h1>
     <form action="?">
      Marsruut:
       <select name="peatus1">
	      <option value="">Vali peatus ...</option>
        <?php
          foreach($peatused as $nimetus => $kaugus){
		     echo "<option value='$kaugus'>$nimetus</option>";
          }
        ?>		
       </select>
       <select name="peatus2">
	      <option value="">Vali peatus ...</option>
        <?php
          foreach($peatused as $nimetus => $kaugus){
		     echo "<option value='$kaugus'>$nimetus</option>";
          }
        ?>		
       </select>
		   <input type="submit" value="OK"  />
      </form>
      <?php
       if(!empty($_REQUEST["peatus1"])){
         echo abs($_REQUEST["peatus2"]-$_REQUEST["peatus1"])." km";
	   }
      ?>
  </body>
</html>





* Lisaks eelmisele on kolmandas rippmens valik, kas tegemist on tava-, kiir- vi ekspressliiniga. Peidetud vrtustena kuuluvad sinna juurde kilomeetrihinnad. Arvestatakse kokku sidu maksumus.





Andmetabeli veebivljund
Andmetabel
	
* Loo tabel kassid tulpadega id, kassinimi, toon
* Lisa paar kassi
* Vljasta kassid
* Vljasta kassid toonide jrjekorras
* Kustuta ks kass



CREATE TABLE kassid(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  kassinimi VARCHAR(30),
  toon VARCHAR(30)
);

INSERT INTO kassid (kassinimi, toon) VALUES ('Miisu', 'hall');
INSERT INTO kassid (kassinimi, toon) VALUES ('Tiisu', 'hall');
INSERT INTO kassid (kassinimi, toon) VALUES ('Nurrik', 'must');
INSERT INTO kassid (kassinimi, toon) VALUES ('Piia', 'valge');

SELECT * FROM kassid;

SELECT id, kassinimi FROM kassid ORDER BY toon DESC;

DELETE FROM kassid WHERE id=2;


Tabeli sisu vaatamine

* Loo/otsi les tabel kassid (id, kassinimi, toon). Nita kasside andmed veebilehele.


<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  $kask=$yhendus->prepare("SELECT id, kassinimi, toon FROM kassid");
  $kask->bind_result($id, $kassinimi, $toon);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
     <title>Kassid</title>
  </head>
  <body>
     <h1>Kasside loetelu</h1>
     <?php
       while($kask->fetch()){
         echo "<h2>".htmlspecialchars($kassinimi)."</h2>";
         echo "<div>".htmlspecialchars($toon)."</div>";
       }
     ?>
  </body>
</html>
<?php
  $yhendus->close();
?>



* Pane kasside toonideks inglisekeelsed vrvinimetused


UPDATE kassid SET toon='gray' WHERE id=1;
UPDATE kassid SET toon='gray' WHERE id=2;
UPDATE kassid SET toon='yellow' WHERE id=3;
UPDATE kassid SET toon='lightblue' WHERE id=4;

* Nita iga kass lehel vastavat vrvi.

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  $kask=$yhendus->prepare("SELECT id, kassinimi, toon FROM kassid");
  $kask->bind_result($id, $kassinimi, $toon);
  $kask->execute();
?>
<!doctype html>
<html>
  <head>
     <title>Kassid</title>
  </head>
  <body>
     <h1>Kasside loetelu</h1>
     <ul>
     <?php
       while($kask->fetch()){
         echo "<li style='color: $toon'>".
            htmlspecialchars($kassinimi)."</li>\n";
       }
     ?>
     </ul>
  </body>
</html>
<?php
  $yhendus->close();
?>



Valminud lehe html-kood. Vrvid kirjutatud stiiliatribuutidesse.

<!doctype html>
<html>
  <head>
     <title>Kassid</title>
  </head>
  <body>
     <h1>Kasside loetelu</h1>
     <ul>
     <li style='color: gray'>Miisu</li>
<li style='color: gray'>Tiisu</li>
<li style='color: yellow'>Nurrik</li>
<li style='color: lightblue'>Piia</li>
     </ul>
  </body>
</html>

Teadete valik

Loo tabel koerte kohta (id, koeranimi, kirjeldus, pildiaadress)
Sisesta andmed mnede koerte kohta, pildid otsi veebist


CREATE TABLE koerad(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  koeranimi VARCHAR(30),
  kirjeldus TEXT,
  pildiaadress TEXT
);

INSERT INTO koerad(koeranimi, kirjeldus, pildiaadress) VALUES(
  'Muki',
  'Korralik karjakrants',
  'http://i623.photobucket.com/albums/tt311/b-rooke10/animals/Siberian-Husky-Puppy-5.jpg'
);
INSERT INTO koerad(koeranimi, kirjeldus, pildiaadress) VALUES(
  'Pauka',
  'Usin valvekoer',
  'http://www.parliste.ee/pildid/koer/koer_10178_1s.jpg'
);
INSERT INTO koerad(koeranimi, kirjeldus, pildiaadress) VALUES(
  'Mimmu',
  'Vike armas koerake',
  'http://2.bp.blogspot.com/_szH5g4slMAo/RzRMgaha_hI/AAAAAAAAAAY/CkYpL30uDmU/S269/koer1.jpg'
);


Loo lehestik, kus vasakus servas nha koerte nimed. Nimele vajutades kuvatakse lehel suurelt see koer koos pildi ja kirjeldusega.

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  $yhendus->query("SET names utf8");
?>
<!doctype html>
<html>
  <head>
    <title>Koerad lehel</title>
    <style type="text/css">
       #menyykiht{
         float: left;
         padding-right: 30px;
         width: 20%;
       }
       #sisukiht{
         float:left;
         width: 60%;
       }
       #jalusekiht{
         clear: left;
       }
       body, html{
         width: 100%;
       }
    </style>
	<meta charset="utf-8" />
  </head>
  <body>
    <div id="menyykiht">
        <h2>Koerad</h2>
        <ul>
          <?php
             $kask=$yhendus->prepare("SELECT id, koeranimi FROM koerad");
             $kask->bind_result($id, $koeranimi);
             $kask->execute();
             while($kask->fetch()){
               echo "<li><a href='?id=$id'>".
                     htmlspecialchars($koeranimi)."</a></li>";
             }
          ?>
        </ul>
    </div>
    <div id="sisukiht">
       <?php
         if(isSet($_REQUEST["id"])){
            $kask=$yhendus->prepare("SELECT id, koeranimi, kirjeldus, pildiaadress
              FROM koerad WHERE id=?");
            echo $yhendus->error;
            $kask->bind_param("i", $_REQUEST["id"]); 
            $kask->bind_result($id, $koeranimi, $kirjeldus, $pildiaadress);
            $kask->execute();
            if($kask->fetch()){
              echo "<h2>".htmlspecialchars($koeranimi)."</h2>";
              echo "<img src='$pildiaadress' alt='$koeranimi' 
                 style='width: 70%' /><br />";
              echo htmlspecialchars($kirjeldus);
            } else {
              echo "Vigased andmed.";
            }
         } else {
           echo "Tere tulemast avalehele! Vali koer.";
         }
       ?>
    </div>
    <div id="jalusekiht">
       Lehe tegi Jaagup
    </div>
  </body>
</html>
<?php
  $yhendus->close();
?>

  


Andmete lisamine ja kustutamine

* Vimalda koeri lisada ja kustutada

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  $yhendus->query("SET names utf8");
  if(isSet($_REQUEST["uusleht"])){
    $kask=$yhendus->prepare("INSERT INTO koerad (koeranimi, kirjeldus, pildiaadress)
       VALUES (?, ?, ?)");
    $kask->bind_param("sss", $_REQUEST["koeranimi"], $_REQUEST["kirjeldus"],
                             $_REQUEST["pildiaadress"]);
    $kask->execute();
    header("Location: $_SERVER[PHP_SELF]");
    $yhendus->close();
    exit();
  }
  if(isSet($_REQUEST["kustutusid"])){
    $kask=$yhendus->prepare("DELETE FROM koerad WHERE id=?");
    $kask->bind_param("i", $_REQUEST["kustutusid"]);
    $kask->execute();    
  }
?>
<!doctype html>
<html>
  <head>
    <title>Koerad lehel</title>
    <style type="text/css">
       #menyykiht{
         float: left;
         padding-right: 30px;
         width: 20%;
       }
       #sisukiht{
         float:left;
         width: 70%;
       }
       #jalusekiht{
         clear: left;
       }
       body, html{
         width: 100%;
       }
       input, textarea{
         width: 90%;
       }
    </style>
	<meta charset="utf-8" />
  </head>
  <body>
    <div id="menyykiht">
        <h2>Koerad</h2>
        <ul>
          <?php
             $kask=$yhendus->prepare("SELECT id, koeranimi FROM koerad");
             $kask->bind_result($id, $koeranimi);
             $kask->execute();
             while($kask->fetch()){
               echo "<li><a href='?id=$id'>".
                     htmlspecialchars($koeranimi)."</a></li>";
             }
          ?>
        </ul>
        <a href='?lisamine=jah'>Lisa ...</a>
    </div>
    <div id="sisukiht">
       <?php
         if(isSet($_REQUEST["id"])){
            $kask=$yhendus->prepare(
             "SELECT id, koeranimi, kirjeldus, pildiaadress
              FROM koerad WHERE id=?");
            echo $yhendus->error;
            $kask->bind_param("i", $_REQUEST["id"]); 
            $kask->bind_result($id, $koeranimi, $kirjeldus, $pildiaadress);
            $kask->execute();
            if($kask->fetch()){
              echo "<h2>".htmlspecialchars($koeranimi)."</h2>";
              echo "<img src='$pildiaadress' alt='$koeranimi' 
                 style='width: 70%' /><br />";
              echo htmlspecialchars($kirjeldus);
              echo "<br /><a href='?kustutusid=$id'>kustuta</a>";
            } else {
              echo "Vigased andmed.";
            }
         } 
         if(isSet($_REQUEST["lisamine"])){
           ?>
             <form action='?'>
              <input type="hidden" name="uusleht" value="jah" />
              <h2>Uue koera lisamine</h2>
              <dl>
                <dt>Koera nimi:</dt>
                <dd>
                 <input type="text" name="koeranimi" />
                </dd>
                <dt>Kirjeldus:</dt>
                <dd>
                  <textarea rows="20" name="kirjeldus"></textarea>
                </dd>
                <dt>Pildi veebiaadress:</dt>
                <dd>
                 <input type="text" name="pildiaadress" style="width: 80%" />
                </dd>
               </dl>
               <input type="submit" value="sisesta">
             </form>
           <?php
         }
       ?>
    </div>
    <div id="jalusekiht">
       Lehe tegi Jaagup
    </div>
  </body>
</html>
<?php
  $yhendus->close();
?>


Tulemus piltkirjas:

Avatud leht, krval lisatava koera pilt koos veebiaadressiga
 
Prast lisamisnupule vajutamist ilmub nhtavale sisestusvorm koera andmete lisamiseks. 
Andmed sisse: koera nimi, kirjeldus ning koera pildi veebiaadress. Sisestusnupule vajutamisel salvestatakse andmed reana koerte tabelisse ning nidatakse lehele. 

   

Koera nimel vajutades ilmub selle koera andmeid nitav leht nhtavale. Kustutusviitele vajutades kaob vastav koer andmebaasist.

  

Andmete muutmine, laulude lehestik
lesandeks lehestiku kokkupanek, kus vimalik koolipeo tarbeks esinevad ansamblid vlja pakkuda, pakututele punkte jagada ning neid kommenteerida.

Andmetabeli loomine

CREATE TABLE ansamblid(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  ansamblinimi VARCHAR(50),
  punktid INT DEFAULT 0,
  kommentaarid TEXT,
  avalik INT DEFAULT 1,
  otsus VARCHAR(255) DEFAULT ''
);
Ansamblinimel pole vaikevrtust vaja, sest see antakse nagunii koos uue kirje loomisega. Otsuse juures on vaikevrtuseks thi tekst. Andmetbiks on VARCHAR(255), ehk suurim pikkus, mida VARCHAR-i abil kirja panna saab. Kigi kommentaaride hoidmiseks aga kardetavasti sellest pikkusest ei piisa, selleks valiti andmetbiks TEXT, kus pikkuspiirangut pole. Samas ei vimalda tp TEXT seada vaikevrtust (kardetavate judlusprobleemide tttu), seetttu see siin puudub ning lisamisel ja arvutamisel NULL-vrtusest hoidumiseks tuleb sinna siis sobiv tekst panna.

Ansambli nime lisamine
Lisamise juures siis pannakse kommentaari kohale praegu thi tekst vaikimisi oleva NULLi asemel, et hiljem saaks sinna kergemini teisi kommentaare juurde liita. 

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  if(!empty($_REQUEST["ansamblinimi"])){
     $kask=$yhendus->prepare(
	  "INSERT INTO ansamblid(ansamblinimi, kommentaarid) VALUES(?, '')");
	 $kask->bind_param("s", $_REQUEST["ansamblinimi"]);
	 $kask->execute();
	 echo $yhendus->error;
	 header("Location: $_SERVER[PHP_SELF]");
	 $yhendus->close();
	 exit();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Ansamblid</title>
  </head>
  <body>
    <h1>Ansambli lisamine hletusele</h1>
	<form action="?">
	   Uue ansambli nimi: 
	     <input type="text" name="ansamblinimi" />
		 <input type="submit" value="Lisa ansambel" />
	</form>
  </body>
</html>
<?php
  $yhendus->close();
?>




Punktide andmine ansamblitele 

Punktide lisamiseks eraldi viited he ja kahe punkti tarbeks. Praegusel juhul ka lehe pises eraldi plokid he ja kahe punkti lisamiseks vastavalt id-d kandva parameetri vrtusele

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  if(isSet($_REQUEST["yhepunkti_id"])){
     $kask=$yhendus->prepare(
          "UPDATE ansamblid SET punktid=punktid+1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["yhepunkti_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["kahepunkti_id"])){
     $kask=$yhendus->prepare(
          "UPDATE ansamblid SET punktid=punktid+2 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["kahepunkti_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Ansamblid</title>
  </head>
  <body>
    <h1>Punktide andmine ansamblitele</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
               "SELECT id, ansamblinimi, punktid FROM ansamblid");
		 $kask->bind_result($id, $ansamblinimi, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $pealkiri=htmlspecialchars($ansamblinimi);
		    echo "<tr>
			  <td>$ansamblinimi</td>
			  <td>$punktid</td>
			  <td><a href='?yhepunkti_id=$id'>Lisa punkt</a></td>
			  <td><a href='?kahepunkti_id=$id'>Lisa kaks punkti</a></td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>



Peitmine ja avalikustamine
Peitmiseks ja nitamiseks iga ansambli taga vastav viide. Lisaks lpus veel vimalik korraga peita kik ansamblid kellele pole veel htegi punkti antud. Vi siis nad kik korraga taas avalikuks muuta.
<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  if(isSet($_REQUEST["peitmise_id"])){
     $kask=$yhendus->prepare("UPDATE ansamblid SET avalik=0 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["peitmise_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["avamise_id"])){
     $kask=$yhendus->prepare("UPDATE ansamblid SET avalik=1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["avamise_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["punktitapeitu"])){
   if($_REQUEST["punktitapeitu"]=="jah"){
     $kask=$yhendus->prepare("UPDATE ansamblid SET avalik=0 WHERE punktid=0");
   } else {
     $kask=$yhendus->prepare("UPDATE ansamblid SET avalik=1 WHERE punktid=0");   
   }
   $kask->execute();
  }

?>
<!doctype html>
<html>
  <head>
    <title>Avalikustamine</title>
  </head>
  <body>
    <h1>Peitmine ja avalikustamine</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
                 "SELECT id, ansamblinimi, avalik FROM ansamblid");
		 $kask->bind_result($id, $ansamblinimi, $avalik);
		 $kask->execute();
		 while($kask->fetch()){
		    $ansamblinimi=htmlspecialchars($ansamblinimi);
		    echo "<tr>
			  <td>$ansamblinimi</td>
			  <td>$avalik</td>
			  <td><a href='?peitmise_id=$id'>Peida</a></td>
			  <td><a href='?avamise_id=$id'>Ava</a></td>
			</tr>";
		 }
	  ?>
	</table>
    <a href="?punktitapeitu=jah">Peida punktitud</a>
    <a href="?punktitapeitu=ei">Nita punktituid</a>
  </body>
</html>
<?php
  $yhendus->close();
?>




Avalikustatud kandideerivad ansamblid

Loetelu nitamaks vaid avalikult kandideerivaid ansambleid, ehk neid, kel baasis tulp avalik on vrtusega 1.

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
?>
<!doctype html>
<html>
  <head>
    <title>Ansamblid</title>
  </head>
  <body>
    <h1>Avalikustatud kandideerivad ansamblid</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
		   "SELECT id, ansamblinimi, punktid 
                    FROM ansamblid WHERE avalik=1");
		 $kask->bind_result($id, $ansamblinimi, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $ansamblinimi=htmlspecialchars($ansamblinimi);
		    echo "<tr>
			  <td>$ansamblinimi</td>
			  <td>$punktid</td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>



Kommenteerimine
Kommentaar liidetakse vastava ansambli kommentaaride lahtri eelnevale vrtusele otsa. Aeg lisatakse ksuga date. Vorming  d.m.Y h:i thendab siis pev.kuu.aasta tund:minut . Tpsemaid seletusi ja vimalusi leiab PHP date-kskluse spetsifikatsioonist http://php.net/manual/en/function.date.php

<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  if(isSet($_REQUEST["uue_kommentaari_id"])){
     $kask=$yhendus->prepare(
	   "UPDATE ansamblid 
            SET kommentaarid=CONCAT(kommentaarid, ?)  WHERE id=?");
     date_default_timezone_set("Europe/Tallinn");
     $kommentaarilisa="\n".$_REQUEST["uus_kommentaar"]."\n".
      date("d.m.Y h:i");
     $kask->bind_param("si", $kommentaarilisa, $_REQUEST["uue_kommentaari_id"]);
     $kask->execute();
     $yhendus->close();
     header("Location: $_SERVER[PHP_SELF]");
  }
?>
<!doctype html>
<html>
  <head>
    <title>Ansamblid</title>
    <style>
      td {vertical-align: top;}
    </style>
  </head>
  <body>
    <h1>Ansamblite kommenteerimine</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
               "SELECT id, ansamblinimi, kommentaarid FROM ansamblid");
		 $kask->bind_result($id, $ansamblinimi, $kommentaarid);
		 $kask->execute();
		 while($kask->fetch()){
		    $ansamblinimi=htmlspecialchars($ansamblinimi);
			$kommentaarid=nl2br(htmlspecialchars($kommentaarid));
		    echo "<tr>
			  <td>$ansamblinimi</td>
			  <td>$kommentaarid</td>
			  <td>
			    <form action='?'>
				   <input type='hidden' 
                              name='uue_kommentaari_id' value='$id' />
				   <input type='text' name='uus_kommentaar' />
				   <input type='submit' value='Lisa kommentaar' />
				</form>
			  </td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>

Ansamblite hindamise ja kommenteerimise leht
Hindamine ja kommenteerimine he lehe peale kokku panduna. Anda saab pluss- ja miinuspunkte.
<?php
  $yhendus=new mysqli("localhost", "juku", "kala", "jukubaas");
  if(isSet($_REQUEST["plusspunkti_id"])){
     $kask=$yhendus->prepare(
          "UPDATE ansamblid SET punktid=punktid+1 WHERE id=?");
	 $kask->bind_param("i", $_REQUEST["plusspunkti_id"]);
	 $kask->execute();
  }
  if(isSet($_REQUEST["miinuspunkti_id"])){
     $kask=$yhendus->prepare(
          "UPDATE ansamblid SET punktid=punktid-1 WHERE id=?");
     $kask->bind_param("i", $_REQUEST["miinuspunkti_id"]);
     $kask->execute();
  }
  if(isSet($_REQUEST["uue_kommentaari_id"])){
     $kask=$yhendus->prepare(
	   "UPDATE ansamblid 
            SET kommentaarid=CONCAT(kommentaarid, ?)  WHERE id=?");
	 $kommentaarilisa="\n".$_REQUEST["uus_kommentaar"]."\n";
	 $kask->bind_param("si", 
               $kommentaarilisa, $_REQUEST["uue_kommentaari_id"]);
	 $kask->execute();
  }
?>
<!doctype html>
<html>
  <head>
    <title>Ansamblid</title>
  </head>
  <body>
    <?php
	  if(isSet($_REQUEST["id"])){
	     $kask=$yhendus->prepare(
             "SELECT id, ansamblinimi, kommentaarid, punktid 
                FROM ansamblid WHERE id=?");
		 $kask->bind_param("i", $_REQUEST["id"]);
		 $kask->bind_result(
                 $id, $ansamblinimi, $kommentaarid, $punktid);
		 $kask->execute();
		 if($kask->fetch()){
		    $ansamblinimi=htmlspecialchars($ansamblinimi);
			$kommentaarid=nl2br(htmlspecialchars($kommentaarid));
		    echo "
			  <h2>$ansamblinimi</h2>
			  <dl>
			    <dt>Punkte:</dt>
				<dd>$punktid</dd>
			    <dt>Kommentaarid:</dt>
				<dd>$kommentaarid</dd>
			  </dl>
			  <a href='?plusspunkti_id=$id'>Lisa punkt</a> 	
			  <a href='?miinuspunkti_id=$id'>Eemalda punkt</a><br />	
			  <form action='?'>
				   <input type='hidden' 
                              name='uue_kommentaari_id' value='$id' />
				   <input type='text' name='uus_kommentaar' />
				   <input type='submit' value='Lisa kommentaar' />
			  </form>			  
			";
			$kask->close();
		 }
	  }
	?>
    <h1>Ansamblite loetelu</h1>
    <table>
	  <?php
	     $kask=$yhendus->prepare(
               "SELECT id, ansamblinimi, punktid 
                  FROM ansamblid WHERE avalik=1");
		 $kask->bind_result($id, $ansamblinimi, $punktid);
		 $kask->execute();
		 while($kask->fetch()){
		    $ansamblinimi=htmlspecialchars($ansamblinimi);
		    echo "<tr>
			  <td><a href='?id=$id'>$ansamblinimi</a></td>
			  <td>$punktid</td>
			</tr>";
		 }
	  ?>
	</table>
  </body>
</html>
<?php
  $yhendus->close();
?>






Kokkuvte

Siinse serveripoolsete veebiraamistike kokkupanemise petuse kaudu tutvuti philiselt hele andmetabelile toetuvate veebilahenduste loomisega. Nagu nha, siis nende tehniliste vahenditega saab tle panna mrgatava osa heks lihtsaks otstarbeks meldud ideedest, olgu tegemist hletamise, kommenteerimise, otsimise, grupeerimise vi mnd toimetust toetava haldamisega. Lehed kannatab ka parooliga kaitsta, nii et igale poole ligi pseb vaid selle jaoks sobiv tegelane. Nd on mnda aega hea lasta oma ideedel vabalt lennata ning proovida mni neist siis ka tegelikult arvutis, veebis ja serveris tle panna. Kindlasti tekib kohti, mis pole kohe nnda mugavalt lahenduvad ning siis tuleb vaadata, kas esimese hooga on mistlik piirduda lihtsustustega vi tasub mujalt soovitusi ja tarkusi juurde otsima hakata. Enamasti tasub teha mlemat. Ehk siis kigepealt lihtsam moodus oma oskuste phjal tle ajada. Juhul, kui ettevetud mte ikka huvi pakub, siis uurida, kuidas muid sarnaseid asju tehtud on ja sealt siis vaikselt killukesi olemasolevale juurde tle meelitada.
