5. Návrh a vytvoření webové databázové aplikace

Cílem této části mé diplomové práce je navrhnout a vytvořit databázovou aplikaci pro správu výsledků úloh studentů. Aplikace musí umožňovat studentům prostřednictvím webového prohlížeče procházet výsledky úloh a zároveň správci stejnou cestou výsledky spravovat. Její pracovní název je SUP (Správce Úloh a Předmětů).
Aplikace bude využívat funkce pro přístup k databázi pomocí standardizovaného rozhraní ODBC (viz. kapitola 4.4) a v kombinaci se skriptovacím jazykem PHP (dále kapitola 5.1.1) tak bude možný přenos na jinou databázovou platformu i jiný operační systém (např. Linux).

5.1 Volba software

K tomu, aby webová stránka zobrazila konkrétní informaci, musí požadavek od uživatele vyvolat spuštění programu (skriptu), který si informace „obstará“ (nejčastěji z databáze) a vygeneruje výsledný HTML dokument.
Při volbě skriptovacího jazyka máme na výběr ze dvou typů [36]:

  1. Serverem vkládané vsuvky – příkazy skriptu se kombinují přímo s HTML kódem. Předtím než je stránka odeslána uživateli, jsou všechny příkazy skriptu vyhodnoceny WWW serverem a jejich výsledek doplněn na odpovídající místo stránky. Typickými zástupci jsou SSI (Server Side Includes), LiveWire (Netscape), ASP (Active Server Pages) od Microsoftu a PHP (Personal Home Pages) – tento systém jsem použil při tvorbě aplikace (viz. dále).
  2. CGI skripty – samostatné programy napsané v libovolném programovacím jazyce. Pokud server obdrží požadavek URL, které ukazuje na program, spustí ho a výsledek (ve formátu HTML) předá prohlížeči jako odpověď.

[34, 36] Při výběru databáze jsem (samozřejmě) vybíral z volně šiřitelných systémů. Nejznámějšími zástupci jsou MySQL a PostgreSQL. Oba mají své přednosti i nedostatky. PostgreSQL je výhodné podporou transakčního zpracování dat (viz. závěr kapitoly 3.2), uložených procedur[1] a triggerů[2] nebo možností vyššího zatížení. Protože jsem (jako většina uživatelů) volil MySQL hovoří jeho vyšší výkon[3], podpora dlouhých textových polí a velmi dobrá spolupráce s PHP.

5.1.1 PHP

PHP (Personal Home Pages) je skriptovací jazyk, který se přímo začleňuje do HTML kódu. Jeho hlavní předností je možnost bezplatného šíření a podpora více platforem – aplikaci tak můžeme vytvořit ve Windows a poté ji umístit na unixový server.
Důležitou vlastností PHP jsou kromě podpory pro práci s databázemi pomocí standardizovaného rozhraní ODBC i nativní funkce pro práci s většinou databázových systémů (např.: Informix, MS SQL Server, MySQL, Oracle, PostgreSQL, Sybase, …)[4]. Kromě toho obsahuje i funkce pro práci se staršími databázemi jako dBase.
Příkazy PHP se od ostatního HTML kódu oddělují znaky <? a ?>.
Popis instalace a konfigurace PHP na platformě Windows je uveden v Dodatku C.

5.1.2 MySQL

[33, 2] MySQL je výkonný a stabilní databázový systém typu klient/server. Podporuje širokou škálu platforem a pro nekomerční účely je šířen zadarmo. Disponuje širokou škálou datových typů, přičemž dokáže uchovat až 4 GB dat v jedné tabulce. Další podstatnou vlastností je i plná podpora české národní abecedy.
MySQL zatím nepodporuje transakční zpracování dat, uložené procedury, triggery a vnořené dotazy, avšak tyto nedostatky je možno v případě potřeby odstranit vhodně napsanými skripty.
Některé testy sice hovoří o limitu 15 stažených stránek za 1 sekundu, ale většina webových aplikací na Internetu (včetně té naší) nedosahuje ani zdaleka zmíněného limitu [33]. Pokud předpokládáme vyšší zatížení, musíme volit některý z komerčních produktů – například Oracle.
Popis instalace a konfigurace MySQL na platformě Windows je uveden v Dodatku C.

5.1.3 Další nástroje

Aby bylo možno skripty používat, musíme je umístit na web server, který je podporuje. V současné době je nejrozšířenějším WWW serverem Apache. Je to výkonný a stabilní server původně určený pro platformu Unix. Podporuje mnoho moderních technologií a navíc je k dispozici zdarma. Server Apache jsem použil při testování PHP skriptů na vlastním počítači. Popis instalace a konfigurace serveru Apache na platformě Windows je uveden v Dodatku C.
Pro kontrolu funkčnosti skriptů a návrh datové základny je výhodné použít grafického správce databáze MySQL. Takových programů je na internetu[5] k dispozici celá řada. Pro tyto účely jsem použil program DBTools[6]. Poskytuje mimo jiné grafické rozhraní pro vzdálenou i „místní“ správu jednotlivých databází, tabulek a uživatelů. Další možností je import a export dat nebo SQL Query Editor, který jsem využil pro testování SQL dotazů následně použitých v PHP skriptech.
Samotné PHP skripty je možno psát v libovolném textovém editoru jako Notepad, uzpůsobených HTML editorech jako je HomeSite[7] či volně šiřitelný 1st Page[8] nebo speciálních editorech pro programování. Použil jsem editor PHPEd[9]. Jde o volně šířitelný nástroj, který kromě klasických editačních funkcí, knihoven příkazů nebo číslovaných řádků, zobrazuje zdrojový kód přehledně barevně odlišený.

5.2 Návrh datové základny

Datová základna je navržena tak, aby při libovolném počtu vložených předmětů, studentů, testů nebo výsledků zůstal počet tabulek i sloupců konstantní. Celkem je rozdělena do pěti tabulek (se sloupci):

  1. Predmety – pro uložení údajů o předmětech
    - id_pred : identifikační číslo předmětu (int, primární klíč)
    - nazev : název předmětu (varchar(40))
  2. Studenti – pro uložení údajů o studentech
    - id_stud : identifikační číslo studenta (int, primární klíč)
    - jmeno : jméno studenta (varchar(15))
    - prijmeni : příjmení studenta (varchar(20))
    - kruh : příslušnost ke studijnímu kruhu (int)
    - email : kontaktní email studenta (varchar(40))
  3. Pred_stud – pro určení příslušnosti studentů k předmětu – každý student má tolik záznamů v kolika je zapsán předmětech (id_pred a id_stud tvoří dohromady složený primární klíč)
    - id_pred : identifikační číslo předmětu (int, primární klíč)
    - id_stud : identifikační číslo studenta (int, primární klíč)
  4. Testy – pro uložení údajů o testech
    - id_test : identifikační číslo testu (int, primární klíč)
    - nazev : název testu (varchar(40))
    - predmet : příslušnost testu k předmětu (int)
  5. Vysledky – pro uložení jednotlivých výsledků úloh (id_test a id_stud tvoří dohromady složený primární klíč)
    - id_test : identifikační číslo testu (int, primární klíč)
    - id_stud : identifikační číslo studenta (int, primární klíč)
    - vysledek : výsledek úlohy (int)

SQL příkazy pro vytvoření všech tabulek jsou uvedeny v příloze 9.2.

5.3 Úvodní informace

5.3.1 Příprava v databázi

Nejprve bylo nutno vytvořit novou databázi (s názvem CVICENI). To lze provést jednoduše pomocí grafického nástroje DBTools nebo příkazem SQL například ze standardního řádkového klienta MySQL (bin\mysql.exe):

CREATE DATABASE cviceni;

Nad touto databází byl poté vytvořen nový datový ODBC zdroj – DSN (pro přehlednost) pod stejným názvem (viz. Dodatek D).

Dále byly v databázi vytvořeny dva uživatelské účty. První s uživatelským jménem STUDENT a heslem STUDENT, kterému bylo přiděleno pouze právo číst data (SELECT) a druhý ADMIN / HELMUT s právy pro čtení, vkládání, změnu a mazání (SELECT, INSERT, UPDATE, DELETE). Ve veřejně přístupných skriptech se tak pro připojení k databázi používá účet s právy pouze pro čtení, což zvyšuje bezpečnost aplikace. Více informací viz. [22].
Uživatele lze opět velice snadno vytvořit pomocí DBTools nebo vložit příkazem SQL (databáze mysql, tabulka user) – například pro uživatele STUDENT:

USE mysql;
INSERT INTO user VALUES(‘%‘,‘student‘,PASSWORD(‘student‘),‘Y‘,‘N‘,‘N‘,‘N‘,‘N‘, ‘N‘,‘N‘,‘N‘,‘N‘,‘N‘,‘N‘,‘N‘,‘N‘,‘N‘,);

5.3.2 Hlavní funkce PHP pro komunikaci s databází přes ODBC

ODBC_Connect(“DSN“,“uživatel“,“heslo“)

ODBC_Exec($spojení,“SQL_příkaz“)

ODBC_Fetch_Row($výsledek,[číslo_záznamu])

ODBC_Result($výsledek,“položka“)

ODBC_Close($spojení)

5.3.3 Poznámky ke stavbě skriptů

HTTP hlavička:

Všechny skripty začínají řádkem, který pomocí HTTP hlavičky Expires odešle čas vypršení platnosti stránky, který je nastaven na aktuální čas. Tím docílíme, že stránka bude pokaždé načítána ze serveru (ne z vyrovnávací paměti) a tudíž v aktuálním stavu.

Header("Expires: ".GMDate("D, d M Y H:i:s")." GMT");

Ošetření chyb:

Před příkazy, které nemusí být vždy provedeny úspěšně, je výhodné použít “zavináč“ (@). Tím se potlačí vypsání chybového hlášení PHP, které by mohlo uživatele vylekat. Případnou chybu ošetříme srozumitelnějším způsobem – například:

do
{
 @$spojeni = ODBC_Connect("cviceni", "student", "student");
  if (!$spojeni):

echo "Spojení s databází se nepodařilo navázat.\n";

break;

  endif;
  . . . . . . .
} while (false);
ODBC_Close($spojeni);

Pokud proměnná $spojeni (popř. jiná z funkcí těla skriptu) vrátí hodnotu typu false vypíše se chybové hlášení a příkaz break ukončí běh cyklu do – while. Za tento cyklus umístíme části kódu, které jsou třeba vykonat vždy – např. uzavření spojení s databází nebo ukončení HTML stránky.

Formátování HTML stránek:

Pro zjednodušení formátování textu, nadpisů a vlastností stránek bylo použito kaskádových stylů CSS – viz. příloha 9.2 .

<link rel=stylesheet type="text/css" href="style.css">

Generování identifikačních čísel:

V tabulkách predmety, studenti a testy tvoří primární klíč identifikační číslo, které musí být v rámci jedné tabulky unikátní. Z tohoto důvodu necháme při vkládání nového záznamu generovat ID jako nejvyšší hodnotu z již existujících hodnot. Například pro vložení záznamu do tabulky studenti (část kódu z insert_stud.php):

$dotaz_na_id = "SELECT Max(id_stud)+1 FROM studenti";
@$vysledek = ODBC_Exec($spojeni, $dotaz_na_id);
 if (!$vysledek):
  echo "Chyba, nové ID nezjištěno.\n";
  break;
 endif;
if (ODBC_Fetch_Row($vysledek))          //přečtení nového ID
 $id_stud = ODBC_Result($vysledek, 1);
else {
 echo "Chyba, nové ID nezjištěno.";
 break;
  }
if ($id_stud=="")                     // je-li záznam první,
 $id_stud = 1;                            // id_stud=1

Zachování integrity dat

Integritou se rozumí soulad dat se skutečným stavem. Například pokud vymažeme záznam z tabulky studenti, musí být odstraněny i odpovídající záznamy z tabulek přiřazení studentů do předmětů (pred_stud) a výsledků (vysledky), aby v databázi nezůstala nepotřebná data. O zachování integrity dat se obecně starají uložené procedury a triggery přímo v databázi. Jinou možností (v případě MySQL jedinou – viz. kapitola 5.1.2) je samotný skript. Ten musí být napsán tak, aby postupně (v tomto případě smazal) všechny související záznamy. Příkladem jsou skripty delete_*.php v příloze 9.2.

5.4 Struktura a funkce aplikace

Nyní zde bude popsána struktura a rozložení funkcí vytvořené aplikace (viz. obrázek 5.4 -1), včetně jmen jednotlivých skriptů a hlavních předávaných parametrů, které odpovídají názvům sloupců v příslušných tabulkách (viz. kapitola 5.2). Všechny zdrojové kódy – viz. příloha 9.3 .

Úvodní strana

Úvodní strana (index.php) větví aplikaci na tři základní části:

  1. Prohlížení výsledků – poskytuje veřejný přístup k prohlížení všech výsledků vybraného předmětu (parametr id_pred).
  2. Správa předmětu – po zadání hesla umožňuje spravovat testy a jejich výsledky v daném předmětu (parametr id_pred), včetně přiřazování studentů.
  3. Správa předmětů a studentů – po zadání příslušného hesla dovoluje spravovat všechny předměty a studenty.

Prohlížení výsledků

Nabízí volný přístup k prohlížení výsledků (browse.php) konkrétního testu (patřícího ke zvolenému předmětu) nebo všech výsledků daného studenta (zapsaného ve zvoleném předmětu). Jako doplněk umožňuje zobrazit seznam s kontakty studentů aktuálně zapsaných v předmětu.

    

Správa předmětu

Na této stránce (admin.php) jsou k dispozici tři základní funkce:

1.      Přidání/odebrání studenta z/do předmětu – umožňuje přidávat (resp. odebírat) studenty do předmětu, přičemž u přidávání výběr nabízí jen ty, kteří ještě v předmětu nejsou a u odebírání naopak. Obslužnému skriptu (addrem_stud.php) je předáván parametr id_stud.

  1. Testy – dovoluje vytvářet (insert_test.php), mazat (delete_test.php) a editovat (update_test.php) testy v rámci aktuálního předmětu. Skriptům je předáván parametr id_test.
  2. Editace výsledků – slouží k souhrnné editaci výsledků vybraného testu. Skriptu je předán parametr id_test.

Správa předmětů a studentů

Tato sekce (admin_pred.php) obsahuje nástroje pro správu:

  1. Předmětů – pomocí předávaného parametru id_pred umožňuje předměty vytvářet (insert_pred.php), mazat (delete_pred.php) a editovat (update_pred.php).

2.      Studentů – pomocí předávaného parametru id_stud umožňuje studenty vytvářet (insert_stud.php), mazat (delete_stud.php) a editovat (update_stud.php)

5.5 Budoucí vývoj aplikace

V případě uvedení do praktického provozu bude účelné upravit, případně přidat, některé funkce ke zvýšení bezpečnosti a praktičnosti aplikace.

Prohlížení výsledků

Pro přehlednost bude výhodnější zobrazovat výsledky všech testů daného předmětu najednou, na rozdíl od stávajícího prohlížení výsledků testu nebo studenta.

Hesla

V této první verzi aplikace pracuje s jedním konstantním heslem „napevno“ uvedeným ve skriptech. Bude účelné oddělit heslo pro správu předmětů a studentů od správy konkrétního předmětu. Každý předmět bude mít své vlastní heslo uložené přímo v databázi (nový sloupec v tabulce predmety). K zabezpečení hesel uložených v databázi nabízí MySQL funkci PASSWORD(), která heslo před uložením zakóduje a dále již pracuje jen s jeho zakódovanou formou.

S tím souvisí i přidání skriptu, který umožní hesla vkládat a měnit.

Email

Další praktickou funkcí může být odesílání emailu z webového formuláře pro všechny zapsané (popřípadě vybrané) studenty. Pro tento účel disponuje PHP funkcí Mail() – viz. příklad:

if (@Mail(“email_adresáta/adresátů“,“subject“, “text_zprávy“[,”hlavičky_emailu”]))
 
echo “Email úspěšně odeslán.\n“;
else
 echo “Email se nepodařilo odeslat.\n“;



[1] Procedura je databázový program. Spustí se voláním z jiného programu či procedury, funkce, triggerem nebo ručně.

[2] Trigger je typ uložené procedury, která se spouští při určité akci s konkrétní tabulkou (např. při vládání nebo mazání záznamu) [1].

[3] Na vygenerování jedné stránky potřebuje 2 – 3 krát kratší čas než PostgreSQL [33].

[4] Přehled a popis všech funkcí PHP pro práci s různými databázovými systémy je možno nalézt na http://download.php.net/manual/en/

[5] Celá řada nástrojů a ovladačů pro databázi MySQL a platformu Windows je k dispozici např. na http://www.mysql.org/downloads/os-win32.html

[6] http://www.dbtools.com.br

[7] http://www.allaire.com

[8] http://www.evrsoft.com/1stpage

[9] http://www.soysal.com/PHPEd