Lekce 6 - Založení databáze a přístupy k ní v PHP
V minulé lekci, Kontaktní formulář, jsme vytvořili kontaktní formulář.
Myšlenku MVC jsme si již osvojili a měli bychom se pohnout směrem kupředu. V dnešním dílu založíme databázi pro uživatele a jejich články.
Databáze
V následujících několika odstavcích si vytvoříme databázi v nástroji phpMyAdmin. Pokud preferujete SQL nebo používáte jiný nástroj, bude na konci uveden i kompletní zakládací kód, který stačí jen spustit.
Přejděte do phpMyAdmin a vytvořte si nějakou novou databázi,
já si ji pojmenoval mvc_db
. Nezapomeňte nastavit
porovnávání na utf8_czech_ci
.
Databázi si otevřete. Nyní si vytvoříme tabulky, budou jen dvě.
Uživatelé
Vytvořte si novou tabulku uzivatele
. Bude mít celkem 4 sloupce
(pole):
uzivatele_id
- typINT
- primární klíč, autoincrementjmeno
- typVARCHAR
- délka 255heslo
- typVARCHAR
- délka 255admin
- typINT
, výchozí: 0 (vyberte možnost "Dle zadání" a poté zadejte 0, viz obrázek níže)
Sloupec admin
určuje zda je uživatel administrátor (0/1).
Naklikaná tabulka by měla vypadat takto:
(Nezapomeňte na primární klíč a AI u pole uzivatele_id. Na screenshotu to není vidět.)
Potvrdíme tlačítkem Uložit.
Hotové tabulce naklikněte klíč UNIQUE na sloupec jmeno
. To
aby v ní nemohli být 2 uživatelé se stejným jménem:
MySQL podporuje i datový typ BOOLEAN
, který je
však vnitřně reprezentován jako typ TINYINT
o velikosti 1 bajt.
BOOLEAN
tedy také můžeme zvolit pro ukládání informací ve
sloupci admin
, avšak až na drobnou úsporu místa nepocítímě
žádný praktický rozdíl.
Články
Přidáme ještě tabulku clanky
. Ta bude obsahovat 6 sloupců
(polí).
clanky_id
- typINT
- primární klíč, autoincrementtitulek
- typVARCHAR
- délka 255obsah
- typTEXT
url
-VARCHAR
- délka 255popisek
-VARCHAR
- délka 255klicova_slova
-VARCHAR
- délka 255
Naklikaná tabulka:
(Opět nezapomeňte na primární klíč a autoinkrementaci u pole
clanky_id
)
Sloupec url
je URL adresa, přes kterou budeme k článku
přistupovat. Např. pro článek s titulkem Úvodní článek
by
URL mohlo vypsat jako uvodni-clanek
. Některé systémy články
zobrazují jen podle číselného ID, což je však nepříjemné jak pro
uživatele, tak pro vyhledávače. Uložíme.
Mezi články si vložíme ten úvodní, abychom měli systém na čem testovat:
Pokud preferujete raději SQL, databázi spolu s tabulkami založíte následujícím skriptem:
CREATE DATABASE IF NOT EXISTS mvc_db DEFAULT CHARACTER SET utf8 COLLATE utf8_czech_ci; USE mvc_db; CREATE TABLE IF NOT EXISTS clanky ( clanky_id int(11) AUTO_INCREMENT, titulek varchar(255), obsah text, url varchar(255), popisek varchar(255), klicova_slova varchar(255), PRIMARY KEY (clanky_id) ); CREATE TABLE IF NOT EXISTS uzivatele ( uzivatele_id int(11) AUTO_INCREMENT, jmeno varchar(255), heslo varchar(255), admin int(11) NOT NULL DEFAULT '0', PRIMARY KEY (uzivatele_id) ); ALTER TABLE uzivatele ADD UNIQUE (jmeno); INSERT INTO clanky ( clanky_id, titulek, obsah, url, popisek, klicova_slova ) VALUES ( NULL , 'Úvod', '<p>Vítejte na našem webu!</p> <p>Tento web je postaven na <strong>jednoduchém MVC frameworku v PHP</strong>. Toto je úvodní článek, načtený z databáze.</p>', 'uvod', 'Úvodní článek na webu v MVC v PHP', 'úvod, mvc, web' );
Než se pustíme do práce s databází v PHP, zmíníme si k tomu trochu teorie.
Přístupy pro práci s databází v PHP
Objektový svět a svět relačních databází (svět relační) jsou velmi rozdílné. Jedná se o 2 odlišné filozofie, o kterých si zde troufnu prohlásit, že jsou neslučitelné.
Relační databáze jsou ověřený způsob jak pracovat s daty. I když existují i databáze plně objektové, firmám se do nich nyní nevyplatí investovat peníze a proto se zatím neprosadily. Po revoluci v programování a příchodu objektů samozřejmě nastal problém s ukládáním dat, jelikož relační databáze objektově nefungují a objekty ukládat neumí. Existuje několik možností, jak se s tímto vypořádat.
1. Neobjektové programování
První možností je samozřejmě programovat úplně bez objektů. Tím bychom však šli proti proudu, nemohli bychom používat žádné komponenty 3. stran a náš kód by byl velmi nekvalitní. Byl by problém vůbec vytvořit aplikaci nějakou architekturu. Určitě zde teď nemá smysl vysvětlovat přínosy OOP, zájemce odkáži na článek Objektově orientované programování a evoluce vývoje softwaru.
2. CRUD Wrapper
Přístup tzv. wrapperu nám umožňuje s databází pracovat jako s objektem, nicméně komunikujeme s ní stále v jejím jazyce SQL. Mícháme tedy objektový a relační kód. Přístup je jakýmsi kompromisem a vyžaduje filozofii OOP trochu ohnout. Výhodou je zachování výkonu a schopností databáze za cenu mírné degradace myšlenek OOP.
Data z databáze vidíme nejčastěji jako hodnoty v poli a přicházíme o možnost přidělit entitám nějakou funkcionalitu. Tu místo toho sdružujeme do tzv. manažerů. Lze i částečně mapovat data na existující třídy, nicméně plnohodnotného konceptu objektového modelu nedosáhneme.
Databázové wrappery se často píší jako tzv. CRUD, jsou tedy předpřipraveny pro provádění 4 základních databázových operací (Create, Read, Update, Delete).
3. Objektově relační mapování
Objektově relační mapování (ORM) jde ortodoxně za myšlenkou OOP. Z databáze tedy místo pole hodnot dostáváme rovnou objekty a ty na sobě mají metody. V jazyce SQL vůbec nekomunikujeme, tabulky v databázi vidíme jako kolekce objektů, se kterými můžeme pracovat běžnými prostředky jazyka. Jsme vlastně úplně odstíněni od toho, že pracujeme s relační databází. Zní to skvěle, že?
Háček je samozřejmě v tom, že na pozadí dochází k určité degradaci výkonu databáze, dotazy se generují automaticky a jsou často neefektivní. Dalším problémem ORM je, že je velmi složité. Musíme sáhnout po hotovém řešení, které PHP jako takové neobsahuje a je třeba použít nějaké řešení 3. strany, které často není jednoduché vůbec zprovoznit, natož používat.
Názory na ORM jsou velmi kontroverzní, někdo říká, že je to moderní způsob práce s daty a že psát dotazy v SQL je zastaralé. Někdo zas, že už samotná myšlenka ORM je nesprávná, jelikož generovaný SQL kód zkrátka nemůže být efektivní a je nutné pomýšlet na jeho konečnou podobu, odstínění tedy není úplné. Osobně mám k ORM neutrální postoj a pokud mi někdo spolu s jazykem poskytne standardizované a odladěné ORM, rád ho použiji. Jelikož PHP nic takového neposkytuje, vyhýbám se mu. Nepřijde mi totiž, že je jeho přidaná hodnota tak vysoká, aby se s ním zde vyplatilo zatěžovat.
4. Objektové databáze
Kromě databází relačních existují i již zmíněné databáze objektové. Ty řeší problém neslučitelnosti objektového a relačního přístupu. Poskytují stejný komfort, jako ORM, ale vnitřně není třeba data převádět do tabulek, ukládají se rovnou jako objekty. Teoreticky neexistuje výkonnostní ani jiný důvod, proč by neměly nahradit databáze relační. V praxi se ale bohužel téměř nepoužívají a můžeme jen doufat, že se to časem změní. Zájemci se mohou podívat např. na projekt MongoDB. My budeme využívat 2. přístupu - wrapperu, který se hodí do seriálu, kde tvoříme minimalistický a zároveň přehledný kód.
Příště, v lekci Databázový wrapper, si vytvoříme databázový wrapper.