E. lecke (HTML5, CSS3, PHP5, JavaScript)


Új ???? (PHP manual)


Tudáspróba - 2. variáció (egyszerű feleletválasztós teszt PHP-vel és Javascripttel)

Ennek a lényege a következő: Egy egyszerű szerkezetű szövegfájlt alakít tesztté egy PHP és egy Javascript programpáros. Minden feladat egy kérdésből és két vagy több válaszból (max. 5) áll. A válaszok közt csak egy hibátlan van, ezt kell megjelölni, ezért 1 pontot kapunk. Hiba esetén egyszer javíthatunk, de ilyenkor már csak 0,5 pont jár. Az összes kérdés megválaszolása után törölhetjük válaszainkat vagy kérhetünk egy összesített (százalékos) értékelést.

Szükséges fájlok (tömörítve):



A teszt adatfájljainak felépítése

Részletesebben az első öt sorról:

  1. a teszt címe
  2. a teszttel kapcsolatos információ (egy sor, de a <br> HTML paranccsal több sorra is törhető)
  3. a teszt szerzője (pl. Összeállította: xy)
  4. a tesz "születési dátuma" (pl. 2017.03.30.)
  5. a teszttel kapcsolatos linkek (források, hasonló kvízek, olvasmányok, de lehet egy üres sor is)

Az adatfájl elején pontosan öt sornak kell állnia, mert a 6. sort már kérdésnek értelmazi a feldolgozó program!

Részletesebben a "tesztelemekről":

  • minden kérdés egy szövegsor legyen, de ebben lehetnek HTML parancsok (pl. kép, link, egy <br> amivel többsorossá tehető a megjelenítés, felsorolás, sorszámozott lista vagy akár egy komplett táblázat)
  • a válaszok felépítése:
    - a válaszok is egysorosak
    - az első karakter mindegyik sorban egy tabulátor,
    - a válaszok közt csak egy helyes válasz lehet, ezt (a tab után) egy csillag jelölje (tehát a 2. karakter csillag)
  • az utolsó válaszok után egy üres sor álljon

Az adatfájl magyarázattal

Az adatfájl magyarázat nélkül

Kattints ide!


Az Javascript fájl (index1.js) első sorai (értékadások)

var grade  = 0;       // pontszám
var count1 = 0;       // jó válaszok számlálója az üzenethez (mod 4)
var count2 = 0;       // rossz válaszok számlálója az üzenethez (mod 4)

var msg    = 6;       // üzenetek/hibaüzenetek száma
var msg1   = new Array(
   'Eltaláltad! Lottózzál!',
   'Szuper!',
   'A válasz hibátlan!',
   'Jó választás. A helyes választ adta!',
   'Rendben! Ügyes!',
   'Csak így tovább! A válasz helyes ...');
var msg2   = new Array(
   'Nem nyert! No még egyszer!',
   'Nem talált! No még egyszer!',
   'Nem, a válasz helytelen. Próbáld meg újból!!',
   'Hoppá! A válasz helytelen. Próbáld meg újra!',
   'A válasz helytelen. Gondold át, és próbáld meg újra!',
   'Sajnos nem ez a helyes válasz. Próbáld meg újra!');

function correct(qN, aN) {
 .....
 }

function showMessage(correct, count) {
 .....
 }

function showGrade() {
 .....
 }

A Javascript program a használt változók megadásával kezdődik. Látható, hogy az értékadás nagyon hasonlít a PHP-beli társához, csupán a "var" kulcsszót kell elé tenni (tömböknél pedig még a "new"-t).

Az első négy értékadás ezen számlálók kezdőértékét állítja be.

A következő két értékadásban adjuk meg azokat a szövegeket, amelyek közül (véletlenszerű választással) egyet kiír a Javascript program (jó válasz esetén a felsőkből, hibás válasznál az alsókból választ). Ezek természetesen módosíthatók, de bővíthető is a lista, csak ügyelni kell a határolójelekre (bővítéskor az "msg = 6" is javítandó!)!

A PHP által generált HTML kérdőív eseményvezérelt:

A Javascript további soraival nem foglalkozunk.


A kérdőív/form generálása (index2.php)

index2.php program kerete

 <?php

 echo "
 <!DOCTYPE html>
 <html>
 <head>
    <meta charset='utf-8'>
    <title>PHP Quiz 2</title>
    <link rel='stylesheet' href='css/style2.css'/>
 </head>

 <body>
 ";

 $kod = $_GET['kd']; if ( $kod == '' ) { $kod = 'minta'; }   // hívás: prg?kd=name (.txt nélkül)
 $inp = "data/$kod.txt";

 if (!file_exists($inp)) {

    echo "<p style='padding-top:25%;text-align:center;font-size:64px;color:red;'>A \"$inp\" adatfájl nem létezik!</p>";

 } else {
    // Adatfájl beolvasása
    ...
    // Adatfájl elemzése
    ...
    // JavaScript változók feltöltése
    ...
    // Form megjelenítése
    ...
 }

 echo "
 </body>
 </html>
 ";

?>

Az index2.php program eleje "legyártja" a weboldal fejrészét, majd paraméterként bekéri (az index1.php-hez hasonlóan) az adatfájl nevét.

A program "lelke" a pirossal kiemelt elágazás, amely az adatfájl létezését vizsgálja, ha nincs, hibaüzenettel leáll. Ha van, akkor működni kezd a Javascripttel segített quiz (részletek a következő négy fülön), majd végül előállítja a formot lezáró dolgait, és a weboldal lábrészét.

Adatfájl beolvasása

   // Adatfájl beolvasása
   $t = array();
   $f = fopen ($inp,"r"); // $f - fájl azonosító
   while (!feof($f)) { array_push($t, chop(fgets($f,1024))); }
   fclose($f);

   $jojelzo = "*";   // ez jelzi a helyes választ
   $ind_ekerd = 5;   // első kérdés indexe (0,1,...)
   $BD = array('0','B','D','T','P','V');   // válaszok betűjele

Magyarázat soronként:

  1. Az adatfájl sorait tároló üres tömb létrehozása
  2. Az adatfájl megnyitása olvasásra (r - read), a "$f" azonosítja a fájl (így később nem kell megadni a nevét)
  3. Elöltesztelő ciklus (while), míg nincs vége a fájlnak (feof):
    - a fájlt egy sorának olvasása (fgets), maximum 1024 byte-ot
    - sorvég levágása (chop)
    - a beolvasott sor beszúrása a $t tömb végére (array_push)
  4. A nyitott fájl lezárása
  5. A helyes választ jelző karaktert tesszük változóba
  6. Az adatfájl elején címek, szerző, stb. szerepel, itt adjuk meg ezek számát
  7. Egy hatelemű tömb definiálása, ezekkel a betűkkel jelöljük a válaszokat (az elsőt /0./ nem használjuk, tehát maximum 5 válasz lehet; a betűk hasonló hangzásúak /súgás ellen/)

Adatfájl elemzése

   $cim   = $t[0];   // teszt megnevezése 1.
   $info   = $t[1];   // információ
   $szerzo   = $t[2];   // szerző(i)
   $datum   = $t[3];   // dátuma
   $forras   = $t[4];   // forrása(i)

   $ansdb = '0'; $keydb = '0'; $trydb = '0';   // JavaScript változók "feje" 2.
   $kerdb = 0;   // kérdés sorszáma
   $ind = $ind_ekerd;   // ugrás az első kérdésre
   do { 3.
      $kerdb++;   // kérdések számolása 5.
      $ind++;   // első válaszra áll
      $valdb = 0;
      do { 4.
         $valdb++; 6.
         if (substr($t[$ind],1,1) == $jojelzo) { 7.
            $jossz = $valdb;
            $t[$ind] = substr($t[$ind],2); // tab és jelző le
         } else {
            $t[$ind] = substr($t[$ind],1); // tab le
         }
         $ind++; 8.
      } while ($t[$ind] != ''); // üres sornál kilép
      $ansdb .= ",$valdb"; 9.
      $keydb .= ",$jossz";
      $trydb .= ",0";
      $ind++;   // üres sor átlépése
   } while ($t[$ind] != ''); // a második üres sornál kilép
  1. a teszt alapadatainak elhelyezése a "$t" tömbből egyedi változókba
  2. az "ansdb","keydb","trydb" stringváltozók kezdőértékeinek beállítása (majd tömbökbe tesszük ezeket, de a 0. elemüket nem használjuk fel); a "$kerdb" numerikus változó beállítása; "$ind" beállítása 5-re (tehát az index az első kérdés sorára mutat)
  3. külső ciklus – kérdésenként végzi az adminisztrációt (lásd 5. és 9. pont)
  4. belső ciklus – üres sorig fut, tehát egy kérdéshez tartozó összes választ feldolgozza
  5. változók növelése kérdésenként ($kerdb jelzi a kérdés sorszámát), illetve a belső ciklus "$valdb" kezdőértékének beállítása
  6. változó növelése (ez a ciklusváltozó, a válasz sorszámát jelzi)
  7. elágazás aszerint, hogy a válasz első (0.) "tab" karaktere után * van-e, ha igen, megjegyezzük ezen válasz sorszámát ($jossz); mindkét esetben leszedjük a felesleges "tab" illetve "*" karaktereket a sor elejéről
  8. ciklusváltozó növelése (ez mindig arra a sorra mutat, amelyet szeretnénk feldolgozni)
  9. a belső ciklusban gyűjtött adatok "hozzáragasztása" a megfelelő változók végéhez; ciklusváltozó növelése

JavaScript változók feltöltése/átadása

   echo "<script language='JavaScript'>\n";
   echo "\tvar numQ     = $kerdb ;\n";   // kérdések száma összesen
   echo "\tvar answers  = new Array( $ansdb ) ;\n";   // válaszok száma a kérdésenként
   echo "\tvar key      = new Array( $keydb ) ;\n";   // helyes válasz sorszáma kérdésenként
   echo "\tvar tryAgain = new Array( $trydb ) ;\n";   // hibaszámláláshoz kérdésenként
   echo "</script>\n";
   echo "<script language='JavaScript' src='index2.js'></script>\n";
  1. JavaScript betét kezdetét jelző utasítás elhelyezése a HTML oldalba
  2. a "$kerdb" PHP változó értékének átadása a "numQ" JavaScript változónak
  3. az "$ansdb" PHP sztringváltozó (elemek vesszővel elválasztva) elhelyezése az "anwers" JavaScript tömbbe
  4. az "$keydb" PHP sztringváltozó (elemek vesszővel elválasztva) elhelyezése a "key" JavaScript tömbbe
  5. az "$trydb" PHP sztringváltozó (elemek vesszővel elválasztva) elhelyezése a "tryAgain" JavaScript tömbbe
  6. JavaScript betét befejezését jelző utasítás elhelyezése a HTML oldalba
  7. az "index2.js" külső JavaScript script program megadása

Nézzük meg a futó script (../quiz/index2.php?kd=minta) forrását, jól látható a fenti 7 utasítás hatása!

Form megjelenítése

   echo "<p class='h1'> $cim </p>\n"; 1.
   echo "<p class='h2'> $info </p>\n";

   echo "<div id='but'><a href='..'>Vissza a kezdőoldalra!</a></div>\n\n";
   echo "<form id='form' method='post'>\n";

   $at = explode(",",$ansdb); $kt = explode(",",$keydb);   // PHP tömbbe 2.
   $ind = $ind_ekerd;   // ugrás az első kérdésre
   for ( $i=1; $i<(1+$kerdb); $i++ ) { 3.
      $ii = $i; if ($i<10) { $ii = "&nbsp;".$i; } 5.
      echo "<p class='kerdes'><span class='ssz'>$ii.</span>$t[$ind]</p>\n"; 6.
      $ind++;
      echo "<table class='t1'>\n"; 7.
      echo "<col class='c1'><col class='c2'><col class='c3'>\n";
      for ( $j=1; $j<(1+$at[$i]); $j++ ) {   // válaszok 4.
         $inp = "<input type='radio' name='V$i' onclick='correct($i,$j);'>"; 8.
         echo "<tr>\n"; 9.
         echo "\t<td>$inp</td>\n\t<td>$t[$ind]</td>\n\t<td>$BD[$j]</td>\n";
         echo "</tr>\n";
         $ind++;
      }
      echo "</table>\n\n"; 10.
      $ind++;
   }
 echo "
 <div id='resub'> 11.
    <button type='reset'>Törlöm az előző válaszaimat!</button>   
    <button type='submit' onclick='showGrade();'>Rendben, jöhet az értékelés!</button>
 </div>

 </form> 12.
 <p class='h3'>$szerzo ($datum)</p>
 <p class='h4'>$forras</p>
 <div id='but'><a href='..'>Vissza a kezdőoldalra!</a></div><br>
 ";
  1. cím, alcím, visszaugró link kiírása; "form" kezdete
  2. sztringek tömbbe írása (vessző határolja az elemeket); index növelése
  3. külső ciklus, amely egy-egy kérdést kezel
  4. belső ciklus, a válaszok elemzésére/kiírására szolgál
  5. kérdés előtti sorszám előállítása, ha egyjegyű, tesz elé egy nem "lenyelhető" space-t (&nbsp;)
  6. aktuális kérdés kiírása (sorszámozva); index növelése (rááll az első válaszra)
  7. válaszok táblázatba írásának előkészítése; három oszlop lesz, itt állítjuk be ezek jellemzőit
  8. a válasz előtti rádiógomb elkészítése úgy, hogy majd rákattintva meghívja a "correct()" JavaScript függvényt (részletek az index2.js-ben)
  9. a táblázat egy sorának kiírása (előbbi rádiógomb, válasz szövege, megfelelő betűjel)
  10. táblázat zárása; index növelése
  11. "reset" és "submit" gombok létrehozása, utóbbira kattintva meghívódik a "showGrade()" JavaScript függvény (részletek az index2.js-ben)
  12. "form" vége; információk, visszalink kiírása

Másoljuk le az "indexD.php" fájlt "indexE.php", a "mainD.css" fájlt "mainE.css", valamint a "menuD.inc" fájlt "menuE.inc" néven és javítsuk át a rá való hivatkozásokat!