Stručný obsah
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.
K2358_sazba.indd 3
Autoři Přispěvatelé
25 27
Úvod
29
Rychlokurz jazyka PHP Ukládání a načítání dat Pole Textové řetězce a regulární výrazy Opětovné používání kódu a psaní funkcí Objektově orientovaný jazyk PHP Zpracování chyb a výjimek Navrhujeme webovou databázi Vytváříme webovou databázi Práce s databází MySQL Přistupujeme do databáze z webu s jazykem PHP Pokročilá správa systému MySQL Pokročilé programování se systémem MySQL Bezpečnostní rizika webové aplikace Budování bezpečné webové aplikace Implementace autentizačních metod v jazyce PHP Práce se systémem souborů a serverem Síťové a protokolové funkce Správa data a času Internacionalizace a lokalizace Generování obrázků Řízení relací v jazyce PHP Spojení jazyků JavaScript a PHP Další užitečné funkce Používáme jazyk PHP a systém MySQL ve velkých projektech Ladění a logování Autentizace a personalizace uživatelů Vývoj webového e-mailového klienta s frameworkem Laravel, první část Vývoj webového e-mailového klienta s frameworkem Laravel, druhá část Sdílení a přihlašování pomocí sociálních sítí Vývoj nákupního košíku Instalace Apache, PHP a MySQL
39 81 103 129 159 187 225 235 247 273 295 315 339 355 365 389 403 427 447 463 475 501 517 543 553 569 587 625 647 699 715 759
Rejstřík
775
12.9.2017 8:33:46
K2358_sazba.indd 4
12.9.2017 8:33:46
Obsah Autoři Přispěvatelé
25 27
Úvod
29
Proč byste si měli přečíst tuto knihu? Co se naučíte v této knize? Co je PHP? Co je MySQL? Proč používat PHP a MySQL? Několik předností jazyka PHP Výkon Škálovatelnost Integrace s databází Vestavěné knihovny Cena Snadnost učení jazyka PHP Podpora objektově orientovaného programování Přenositelnost Flexibilita vývojového přístupu Zdrojový kód Dostupnost podpory a dokumentace
Klíčové funkce jazyka PHP 7 Několik předností systému MySQL Výkon Nízká cena Snadnost použití Přenositelnost Zdrojový kód Dostupnost podpory
Co je nového v MySQL 5.x? Jak je uspořádaná tato kniha? Závěrem Zpětná vazba od čtenářů Zdrojové kódy ke knize Errata
K2358_sazba.indd 5
29 29 30 31 31 32 32 32 33 33 33 33 33 33 34 34 34
34 35 35 35 35 35 36 36
36 37 38 38 38 38
12.9.2017 8:33:46
OBSAH
6
Kapitola 1
Rychlokurz jazyka PHP Než začnete – nainstalovaný jazyk PHP Tvorba ukázkové aplikace – Bobovy autodíly Tvorba objednávkového formuláře Zpracování formuláře
Vkládání kódu PHP do dokumentu HTML Značky jazyka PHP Příkazy jazyka PHP Bílé znaky Komentáře Přidání dynamického obsahu Volání funkce Funkce date()
Přístup k proměnným formuláře Proměnné formuláře Řetězení textových řetězců Proměnné a literály
Identifikátory Typy proměnných Datové typy jazyka PHP Síla typování Přetypování
Definujeme a používáme konstanty Oblast platnosti proměnných Operátory
K2358_sazba.indd 6
39 40 40 40 42
42 43 44 44 45 46 47 47
47 48 50 50
51 52 52 52 53
54 54 55
Aritmetické operátory Operátory řetězení Operátor přiřazení
56 57 57
Hodnoty vrácené přiřazením Kombinované operátory přiřazení Operátory inkrementace a dekrementace Operátor reference
57 58 58 59
Porovnávací operátory
59
Operátor rovnosti Další porovnávací operátory
59 60
Logické operátory Bitové operátory Další operátory
60 61 62
Ternární operátor Operátor potlačení chyby Operátor spuštění Operátory pro práci s poli Typový operátor
62 62 62 63 63
12.9.2017 8:33:46
OBSAH
7
Výpočet součtů formuláře Pochopení priorit a asociací Funkce pro zpracování proměnných
64 65 66
Testování a nastavení typů proměnných Testování stavu proměnné Reinterpretace proměnných
67 68 69
Rozhodování podle podmínek Příkaz if Bloky kódu Příkaz else Příkaz elseif Příkaz switch Srovnání různých podmíněných příkazů
Opakujeme akce v iteracích Cyklus while Cykly for a foreach Cyklus do…while
Jak ukončit řídicí strukturu nebo skript Alternativní syntaxe řídicích struktur Řídicí struktura declare Co bude dál?
69 69 70 70 71 72 73
74 75 77 78
78 79 79 79
Kapitola 2
Ukládání a načítání dat Ukládání dat Ukládání a načítání Bobových objednávek Zpracování souborů Otevírání souboru Výběr režimu souboru Otevírání souboru funkcí fopen() Otevírání souborů přes FTP nebo HTTP Řešení problémů s otevíráním souborů
81 82 82 83 83 83 86 86
Zapisování do souboru
88
Parametry funkce fwrite() Formáty souborů
89 89
Zavírání souboru Čtení ze souboru Otevření souboru pro čtení – fopen() Příznak zastavení – feof() Čtení po řádcích – fgets(), fgetss() a fgetcsv() Čtení celého souboru – readfile(), fpassthru(), file() a file_get_contents() Čtení znaku – fgetc() Čtení libovolně dlouhých dat – fread()
K2358_sazba.indd 7
81
90 92 93 94 94 95 96 96
12.9.2017 8:33:46
OBSAH
8
Další souborové funkce Ověření existence souboru – file_exists() Určení velikosti souboru – filesize() Smazání souboru – unlink() Navigování v souboru – rewind(), fseek() a ftell()
Zamykání souborů Lepší řešení – databáze Problémy textových souborů Jak databázové systémy řeší tyto problémy
Další zdroje Co bude dál
97 97 97 97 97
98 100 100 101
101 101
Kapitola 3
Pole
103 Co je pole? Číselně indexovaná pole Inicializace číselně indexovaného pole Přístup k obsahu pole Přístup k prvkům pole v cyklu
Pole s jinými klíči Inicializace pole Přístup k prvkům pole Používáme cykly
Operátory pro práci s poli Vícerozměrná pole Řazení polí Funkce sort() Funkce asort() a ksort() Řadíme obráceně
104 105 106
107 107 107 107
109 110 113 113 114 114
Řazení vícerozměrných polí
115
Funkce array_multisort() Uživatelsky definované řazení Obrácené uživatelské řazení
115 116 117
Přeuspořádání polí
118
Funkce shuffle() Převracíme pole
118 119
Načítání polí ze souborů Další manipulace s poli Navigace v poli – each(), current(), reset(), end(), next(), pos() a prev() Aplikování funkce na jednotlivé prvky pole – array_walk() Počítání prvků v poli – count(), sizeof() a array_count_values() Převod polí na skalární proměnné – extract()
Další zdroje Co bude dál
K2358_sazba.indd 8
103 104
120 124 124 125 126 126
128 128
12.9.2017 8:33:46
OBSAH
9
Kapitola 4
Textové řetězce a regulární výrazy Vytváříme ukázkovou aplikaci – chytrý formulář zpětné vazby Formátování textových řetězců
129 129 132
Ořezávání textových řetězců – chop(), ltrim() a rtrim() Formátování textových řetězců pro výstup
132 132
Filtrování textových řetězců pro výstup Filtrování textových řetězců pro výstup do webového prohlížeče funkcí htmlspecialchars() Filtrování textových řetězců pro jiné formy výstupu Formátování jazyka HTML – funkce nl2br() Formátování textového řetězce pro tisk Změna velikosti písmen
132 133 134 135 136 139
Spojování a rozdělování textových řetězců Funkce explode(), implode() a join() Funkce strtok() Funkce substr()
Porovnávání textových řetězců Uspořádání textových řetězců – strcmp(), strcasecmp() a strnatcmp() Zjišťujeme délku textového řetězce funkcí strlen()
Vyhledávání a nahrazování podřetězců
140 140 141 141
142 142 143
143
Vyhledávání textových řetězců v textových řetězcích – strstr(), strchr(), strrchr() a stristr() 144 Vyhledávání pozice podřetězce – funkce strpos() a strrpos() 145 Nahrazování podřetězců – funkce str_replace() a substr_replace() 146
Představení regulárních výrazů Základy Oddělovače Třídy a typy znaků Opakování Podvýrazy Počítané podvýrazy Odkazy na začátek a konec textového řetězce Větvení Hledání speciálních znaků doslovně Shrnutí meta znaků Escapovací sekvence Zpětné reference Tvrzení Vše smícháme dohromady ve formuláři zpětné vazby
Vyhledávání podřetězců regulárními výrazy Nahrazování podřetězců regulárními výrazy Rozdělování textových řetězců regulárními výrazy Další zdroje Co bude dál
K2358_sazba.indd 9
147 147 148 148 150 150 150 150 151 151 152 152 153 154 154
156 157 157 158 158
12.9.2017 8:33:46
OBSAH
10
Kapitola 5
Opětovné používání kódu a psaní funkcí
159
Výhody opětovného používání kódu
159
Cena Spolehlivost Konzistence
Funkce require() a include() Vkládání kódu funkcí require() Funkce require() pro šablony webových stránek Konfigurační možnosti auto_prepend_file a auto_append_file
Funkce v jazyce PHP Volání funkcí Volání nedefinované funkce Velikost písmen v názvech funkcí
Definujeme vlastní funkce Základní struktura funkce Pojmenování funkcí
Parametry funkce Oblast platnosti Předávání parametrů odkazem versus hodnotou Klíčové slovo return Vracení hodnot z funkcí
Implementujeme rekurzi Anonymní funkce (uzávěry) Další zdroje Co bude dál
159 160 160
160 161 163 167
168 168 170 171
171 172 173
174 176 179 180 181
182 183 185 185
Kapitola 6
Objektově orientovaný jazyk PHP Koncepce objektově orientovaného programování Třídy a objekty Polymorfismus Dědičnost
Tvorba tříd, vlastností a metod v jazyce PHP Struktura třídy Konstruktory Destruktory
Vytváření instancí tříd Vlastnosti třídy Volání metod Řízení přístupu modifikátory private a public Magické metody __get() a __set()
K2358_sazba.indd 10
187 187 187 189 189
190 190 190 191
191 192 192 193 194
12.9.2017 8:33:46
OBSAH
Implementace dědičnosti v jazyce PHP Řízení viditelnosti modifikátory private a protected Přepisování Zabraňujeme dědění a přepisování klíčovým slovem final Vícenásobná dědičnost Rozhraní
Traits Navrhujeme třídy Píšeme kód pro naši třídu Pokročilé objektově orientované koncepce Konstanty tříd Statické metody Ověřování typu objektu a typování Pozdní statické vazby Klonujeme objekty Abstraktní třídy Přetěžování metod metodou __call() Funkce __autoload() Implementace iterátorů a iterací Generátory Převod tříd na textové řetězce Rozhraní Reflection API Jmenné prostory Dceřiné jmenné prostory Globální jmenný prostor Import a tvorba aliasů jmenných prostorů
Co bude dál
11
195 196 197 199 200 200
201 203 204 211 211 211 212 212 213 214 214 215 215 217 219 219 220 222 222 223
223
Kapitola 7
Zpracování chyb a výjimek Koncepce zpracování výjimek Třída Exception Uživatelsky definované výjimky Výjimky na Bobových stránkách Výjimky a další mechanismy zpracování chyb v jazyce PHP Další zdroje Co bude dál
225 225 227 228 230 233 233 233
Kapitola 8
Navrhujeme webovou databázi Koncepce relačních databází Tabulky Sloupce Řádky
K2358_sazba.indd 11
235 236 236 236 237
12.9.2017 8:33:46
OBSAH
12
Hodnoty Klíče Schémata Vztahy
Navrhování webové databáze Představujte si skutečné objekty, které se snažíte modelovat Neukládejte redundantní data Používejte atomické hodnoty sloupců Vybírejte smysluplné klíče Přemýšlejte, na co se chcete dotazovat databáze Vyhýbejte se návrhům s mnoha prázdnými sloupci Přehled typů tabulek
Architektura webové databáze Další zdroje Co bude dál
237 237 238 239
239 239 241 242 243 243 243 244
244 246 246
Kapitola 9
Vytváříme webovou databázi MySQL monitor Přihlášení k serveru MySQL Vytváříme databázi Nastavujeme uživatelské účty a oprávnění Systém oprávnění MySQL Princip minimálních oprávnění Založení uživatelského účtu – příkazy CREATE USER a GRANT Typy a úrovně oprávnění Příkaz REVOKE Příklady s příkazy GRANT a REVOKE
Vytvoření uživatelského účtu pro web Vybíráme správnou databázi Tvorba databázových tabulek Co znamenají další klíčová slova Typy sloupců Průzkum databáze s příkazy SHOW a DESCRIBE Tvorba indexů
Identifikátory systému MySQL Vybíráme datové typy sloupců Číselné typy Typy pro datum a čas Textové typy
Další zdroje Co bude dál
K2358_sazba.indd 12
247 248 249 250 251 251 251 252 254 257 257
258 259 259 261 262 264 265
265 267 268 269 270
272 272
12.9.2017 8:33:46
OBSAH
13
Kapitola 10
Práce s databází MySQL Co je jazyk SQL Vkládání dat do databáze Načítání dat z databáze
273 273 274 276
Načítání dat splňujících určitá kritéria Načítání dat z více tabulek Jednoduchá spojení dvou tabulek
277 279 280
Spojování více než dvou tabulek Hledání řádků, které neodpovídají kritériím Používání jiných názvů pro tabulky – aliasy Shrnutí spojení
281 282 283 284
Načítání dat v určitém pořadí Seskupování a agregování dat Vybíráme řádky, které chceme vrátit Poddotazy
284 285 287 288
Základní poddotazy Poddotazy a operátory Související poddotazy Řádkové poddotazy Poddotaz jako dočasná tabulka
288 289 289 290 290
Aktualizujeme záznamy v databázi Změna tabulek po vytvoření Mažeme záznamy z databáze Mazání tabulek Odstranění celé databáze Další zdroje Co bude dál
290 291 293 294 294 294 294
Kapitola 11
Přistupujeme do databáze z webu s jazykem PHP Jak funguje architektura webové databáze Dotazování databáze z webu Ověřování a filtrování vstupních dat Připojování Výběr databáze Dotazování databáze
295 299 299 300 301 302
Nedělejte to
302
Připravené příkazy Načítání výsledků dotazu Odpojení od databáze
303 304 305
Vkládání nových dat do databáze
K2358_sazba.indd 13
295
306
12.9.2017 8:33:46
OBSAH
14
Další databázová rozhraní jazyka PHP Obecné databázové rozhraní PDO
Další zdroje Co bude dál
310 310
313 313
Kapitola 12
Pokročilá správa systému MySQL Pochopení systému oprávnění detailněji Tabulka user Tabulka db Tabulky tables_priv, columns_priv, procs_priv a proxies_priv Řízení přístupu – jak systém MySQL používá grant tabulky Aktualizace oprávnění – kdy se změny projeví?
Zabezpečení databáze MySQL
315 315 317 319 320 321 322
322
Systém MySQL v operačním systému Hesla Oprávnění uživatelů Webové problémy
322 323 323 324
Získávání informací o databázích
324
Získávání informací příkazem SHOW Získávání informací o sloupcích příkazem DESCRIBE Jak prozkoumat dotazy příkazem EXPLAIN
325 327 327
Optimalizace databáze
332
Optimalizace návrhu Oprávnění Optimalizace tabulek Indexy Výchozí hodnoty Další tipy
332 332 332 333 333 333
Zálohování databáze MySQL Obnova databáze MySQL Implementace replikace Nastavení master serveru Provedení úvodního přenosu dat Nastavení slave serverů
Další zdroje Co bude dál
333 334 334 335 336 336
337 337
Kapitola 13
Pokročilé programování se systémem MySQL Příkaz LOAD DATA INFILE Databázová úložiště Transakce Transakce v databázovém úložišti InnoDB
K2358_sazba.indd 14
339 339 339 341 342
12.9.2017 8:33:46
OBSAH
Cizí klíče Uložené procedury Základní příklad Lokální proměnné Kurzory a řídicí struktury
Triggery Další zdroje Co bude dál
15
343 344 344 347 348
352 354 354
Kapitola 14
Bezpečnostní rizika webové aplikace Identifikace hrozeb, kterým čelíme Přístup k citlivým datům
355 355 355
Snížení rizika
356
Úprava dat Únik nebo ztráta dat
358 358
Snížení rizika
359
Denial of Service
359
Snížení rizika
360
Injekce zákeřného kódu
361
Snížení rizika
362
Kompromitovaný server
362
Snížení rizika
362
Odmítnutí
362
Snížení rizika
362
Kdo stojí proti nám Útočníci a hackeři Uživatelé, kteří nemají ponětí, že je jejich počítač infikovaný Nespokojení zaměstnanci Zloději hardwaru My sami
Další zdroje Co bude dál
363 363 363 364 364 364
364 364
Kapitola 15
Budování bezpečné webové aplikace Strategie pro zacházení s bezpečností
365
Začněte správným myšlením Vyvažování bezpečnosti a použitelnosti Sledování bezpečnosti Základní přístup
365 366 366 367
Zabezpečení zdrojového kódu
K2358_sazba.indd 15
365
367
Filtrování vstupu uživatele
367
Dvakrát kontrolujte očekávané hodnoty Filtrujte i základní hodnoty
368 370
12.9.2017 8:33:46
OBSAH
16
Zabezpečení textových řetězců pro dotazy SQL
371
Escapování výstupu Uspořádání zdrojového kódu Co patří do zdrojového kódu Úvahy nad systémem souborů Stabilita a chyby kódu Spouštíme příkazy
372 374 375 376 376 377
Zabezpečení webového serveru s jazykem PHP
378
Aktualizujte software
378
Instalace nových verzí Nasazení nové verze
378 379
Prohlížení souboru php.ini Konfigurace webového serveru
379 380
Apache http Server
380
Sdílený hosting pro webové aplikace
381
Bezpečnost databázového serveru Uživatelé a systém oprávnění Odesílání dat na server Připojování k serveru Spouštění serveru
Ochrana sítě Brány firewall DMZ Připravujeme se na útoky DoS a DDoS
Zabezpečení počítače a operačního systému Pravidelné aktualizace operačního systému Spouštějte jen nezbytné programy Fyzické zabezpečení serveru
Krizové plánování Co bude dál
382 382 383 383 383
384 384 384 385
386 386 386 387
387 388
Kapitola 16
Implementace autentizačních metod v jazyce PHP Identifikace návštěvníků Implementace řízení přístupu Ukládáme hesla Zabezpečení hesel Zabezpečení více stránek
Základní autentizace Základní autentizace v jazyce PHP Základní autentizace serveru Apache pomocí souborů .htaccess Tvorba vaší vlastní autentizace Další zdroje Co bude dál
K2358_sazba.indd 16
389 389 390 393 393 395
396 396 398 401 402 402
12.9.2017 8:33:46
OBSAH
17
Kapitola 17
Práce se systémem souborů a serverem Uploadování souborů Kód HTML pro upload souborů Kód PHP pro zpracování souboru Průběh uploadu Vyhněte se běžným problémům s uploadem
Adresářové funkce Čtení z adresářů Načítáme informace o aktuálním adresáři Vytváření a mazání adresářů
Interakce se systémem souborů Získávání informací o souboru Změna vlastností souboru Vytváření, mazání a přesouvání souborů
Funkce pro spouštění programů Interakce s prostředím – getenv() a putenv() Další zdroje Co bude dál
403 403 405 406 410 411
412 413 416 417
417 418 420 421
422 424 425 425
Kapitola 18
Síťové a protokolové funkce Průzkum dostupných protokolů Odesílání a přijímání e-mailů Používáme data z jiných webových stránek Funkce pro vyhledávání na síti Zálohování nebo zrcadlení souboru
427 427 428 428 432 436
Zálohování nebo zrcadlení souboru přes protokol FTP
436
Připojování ke vzdálenému serveru FTP Přihlašování k serveru FTP Kontrola časů poslední úpravy souboru Stahování souboru Zavíráme spojení
439 440 441 442 443
Uploadování souborů Zabraňujeme překročení časového limitu Další FTP funkce
443 443 444
Další zdroje Co bude dál
445 445
Kapitola 19
Správa data a času Načítání data a času v jazyce PHP Časové zóny Funkce date()
K2358_sazba.indd 17
447 447 447 448
12.9.2017 8:33:46
OBSAH
18
Pracujeme s časovými známkami systému Unix Funkce getdate() Validujeme datum funkcí checkdate() Formátování časových známek
Převádění formátů data mezi jazykem PHP a systémem MySQL Výpočty s daty v jazyce PHP Výpočty s daty v systému MySQL Mikrosekundy Kalendářové funkce Další zdroje Co bude dál
450 451 453 453
455 457 458 459 460 461 461
Kapitola 20
Internacionalizace a lokalizace Lokalizace není jen překlad Porozumění znakovým sadám Dopady znakových sad na bezpečnost Vícebajtové funkce pro práci s textovými řetězci
Tvorba základní struktury lokalizovatelných stránek Jak používat funkci gettext() v mezinárodní aplikaci
463 463 464 465 466
466 470
Nastavení systému pro použití funkce gettext() 470 Tvorba souborů s překlady 472 Implementace lokalizovaného obsahu v jazyce PHP s pomocí funkce gettext() 473
Další zdroje Co bude dál
474 474
Kapitola 21
Generování obrázků Nastavení podpory zpracování obrázků v jazyce PHP Obrazové formáty
475 476
Formát JPEG Formát PNG Formát GIF
476 477 477
Tvorba obrázků
477
Vytváříme plátno Kreslení a tisk textu do obrázku Výstup finální grafiky Úklid
Jak používat automaticky generované obrázky na dalších stránkách Jak vytvářet obrázky s texty a písmy Vytváříme základní plátno Umístění textu na tlačítko
K2358_sazba.indd 18
475
479 479 481 482
482 483 486 487
12.9.2017 8:33:46
OBSAH Umístění textu Píšeme text na tlačítko Dokončujeme
Vykreslování čísel a grafových dat Další obrazové funkce Co bude dál
19 490 491 491
491 500 500
Kapitola 22
Řízení relací v jazyce PHP
501
Co je řízení relací? Pochopení základů relací
501 501
Co je cookie? Nastavujeme cookies z jazyka PHP Cookies a relace Ukládání identifikátoru relace
502 502 503 503
Implementace jednoduchých relací
504
Spuštění relace Registrace relačních proměnných Používání relačních proměnných Mažeme proměnné a ukončujeme relaci
504 504 505 505
Příklad s jednoduchou relací Konfigurace řízení relací Implementujeme autentizaci s použitím relací Co bude dál
505 508 509 516
Kapitola 23
Spojení jazyků JavaScript a PHP Technologie AJAX Stručný úvod do jQuery Aplikace frameworku jQuery ve webových aplikacích Základní techniky a koncepce frameworku jQuery Selektory knihovny jQuery
517 517 518 519 519
Zpracování vybraných skupin
522
Úvod do událostí frameworku jQuery
523
Spojení frameworku jQuery s technologií AJAX a jazykem PHP
528
Skript na straně serveru umožňující chatovat pomocí technologie AJAX Ajaxové metody frameworku jQuery
528 532
Metoda $.ajax() Pomocné ajaxové metody
532 533
Klientská část chatu jako aplikace v jQuery
535
Další zdroje Co bude dál
K2358_sazba.indd 19
517
541 541
12.9.2017 8:33:46
OBSAH
20
Kapitola 24
Další užitečné funkce Vyhodnocování textových řetězců – eval() Ukončujeme běh skriptu – die() a exit() Serializování proměnných a objektů Načítání informací o prostředí PHP Pátráme po načtených rozšířeních Identifikujeme vlastníka skriptu Zjištění času poslední úpravy skriptu
Dočasná změna běhového prostředí Zvýrazňování zdrojového kódu Ovládání interpretu PHP z příkazového řádku Co bude dál
543 543 544 545 546 546 547 548
548 549 550 551
Kapitola 25
Používáme jazyk PHP a systém MySQL ve velkých projektech Aplikujeme principy softwarového inženýrství na webový vývoj Plánování a zpracování projektu webové aplikace Znovupoužitelnost zdrojového kódu Píšeme udržovatelný kód
554 554 555 556
Standardy programování
556
Definice konvencí pojmenování Komentování kódu Odsazování kódu
557 558 559
Rozdělení kódu Standardní adresářová struktura Dokumentace a sdílení funkcí interně
559 560 560
Implementace správy verzí Výběr vývojového prostředí Dokumentování projektů Prototypování Oddělení logiky od obsahu Optimalizace zdrojového kódu Jednoduché optimalizace
Testování Další zdroje Co bude dál
K2358_sazba.indd 20
553
561 562 562 563 564 565 565
566 567 567
12.9.2017 8:33:47
OBSAH
21
Kapitola 26
Ladění a logování
569
Programovací chyby
569
Syntaktické chyby Běhové chyby
569 570
Volání neexistující funkce Čtení a zapisování do souborů Interakce s databází MySQL a jinými databázemi Připojení k síťovým službám Absence validace vstupních dat
571 572 573 575 576
Logické chyby
Pomoc s laděním proměnných Úrovně hlášení chyb Změna konfigurace hlášení chyb Vyvolávání vlastních chyb Elegantní logování chyb Logování chyb do souboru Co bude dál
576
577 579 580 582 583 585 586
Kapitola 27
Autentizace a personalizace uživatelů Komponenty řešení Identifikace a personalizace uživatelů Ukládáme záložky Doporučování záložek
Přehled řešení Implementace databáze Implementace základních stránek Implementujeme autentizaci uživatelů Registrace uživatelů Přihlašování Odhlášení Změna hesla Obnova zapomenutého hesla
Implementujeme ukládání a načítání záložek Přidávání záložek Zobrazování záložek Mazání záložek
Implementace doporučování Možná rozšíření ke zvážení
K2358_sazba.indd 21
587 587 588 589 589
589 591 592 595 595 601 605 606 609
613 613 616 617
620 623
12.9.2017 8:33:47
OBSAH
22
Kapitola 28
Vývoj webového e-mailového klienta s frameworkem Laravel, první část Úvod do frameworku Laravel 5
625 625
Tvorba nového projektu s frameworkem Laravel Struktura aplikace Laravel Cyklus požadavků frameworku Laravel a architektura MVC
625 626 628
Jádra aplikace Poskytovatelé služeb
628 629
Modely, pohledy a kontrolery frameworku Laravel
629
Směrovač Laravel Parametry cesty Skupiny cest Kontrolery Přistupujeme k datům požadavku Pohledy Šablony Blade Modely frameworku Laravel Operace CRUD v modelech Eloquent Poslední nápady týkající se frameworku Laravel
629 630 632 632 634 636 637 639 644 645
Kapitola 29
Vývoj webového e-mailového klienta s frameworkem Laravel, druhá část Vývoj jednoduchého klienta IMAP pomocí frameworku Laravel
647 647
Funkce pro práci s protokolem IMAP
647
Otevření spojení se serverem IMAP Protokol IMAP a e-mailové schránky Načítání zpráv protokolem IMAP Načítání a parsování konkrétních zpráv ze serveru IMAP
648 649 651 654
Začlenění funkčnosti IMAP do naší aplikace Laravel
656
Třída klienta IMAP Třída zprávy a rozhraní zprávy Třída Attachment
659 664
674
Skládáme vše dohromady, abychom vytvořili webového e-mailového klienta 675 Implementace poskytovatele ImapServiceProvider Přihlašovací stránka webového klienta Implementujeme hlavní pohled Implementujeme prohlížení zprávy Mazání a odesílání zprávy
Závěr
K2358_sazba.indd 22
675 676 682 688 692
697
12.9.2017 8:33:47
OBSAH
23
Kapitola 30
Sdílení a přihlašování pomocí sociálních sítí
699
Přihlašování k webové službě standardem OAuth
699
Povolení typu autorizační kód Implicitní povolení Stavíme webového klienta propojeného se sítí Instagram
701 702 703
Přihlašovací stránka OAuth Dokončení autorizačního povolení OAuth Zobrazujeme feed sítě Instagram
705 707 708
Lajkování fotografií na síti Instagram
Závěr
712
713
Kapitola 31
Vývoj nákupního košíku Komponenty řešení Stavba online katalogu Sledování vybraných produktů uživatelů při nakupování Implementace platebního systému Vývoj administračního rozhraní
Návrh řešení Implementujeme databázi Implementace online katalogu Výpis kategorií Výpis knih v kategorii Zobrazujeme detail knihy
Implementace nákupního košíku Skript show_cart.php Zobrazení košíku Přidávání položek do košíku Ukládáme aktualizovaný košík Výpis shrnutí v záhlaví Objednávání
Implementujeme platby Implementujeme administrační rozhraní Rozšiřování projektu
K2358_sazba.indd 23
715 715 716 716 716 717
717 721 723 725 728 729
731 731 734 736 738 739 739
746 748 757
12.9.2017 8:33:47
OBSAH
24
Dodatek A
Instalace Apache, PHP a MySQL Instalace programů Apache, PHP a MySQL v systému UNIX
760
Binární instalace Instalace ze zdrojového kódu
760 761
Instalace systému MySQL Instalace PHP a Apache
762 765
Základní úpravy konfigurace serveru Apache Funguje podpora jazyka PHP? Funguje vrstva SSL?
769 770 770
Instalace programů Apache, PHP a MySQL v systémech Windows a Mac OS pomocí souhrnných instalačních balíků Otestujte výsledek své práce Instalace repozitáře PEAR
Instalace interpretu PHP s jinými webovými servery
Rejstřík
K2358_sazba.indd 24
759
772 773 773
774
775
12.9.2017 8:33:47
Navrhujeme webovou databázi Když už znáte základy jazyka PHP, můžete se začít zabývat tím, jak začlenit databáze do svých skriptů. Možná si pamatujete, že kapitola 2 uváděla výhody databází oproti prostým textovým souborům. Patří k nim:
Databáze poskytují rychlejší přístup k datům než prosté textové soubory.
Databází se lze dotazovat na skupinu dat, která splňují určitá kritéria.
Databáze mají vestavěné mechanizmy pro zacházení se současným přístupem více uživatelů a s konflikty z toho plynoucími, kterými se proto jako programátoři nemusíte zabývat.
Databáze poskytují náhodný přístup k datům.
Databáze mají vestavěný systém oprávnění.
K A P I T O L A
8 V této části knihy budete pracovat s databázovým systémem MySQL. Než se jím začnete zabývat podrobněji (v příští kapitole), měli byste se dozvědět o: Koncepce a terminologie relačních databází. Navrhování webové databáze. Architektura webové databáze.
Pomocí databází můžete například rychle odpovědět na otázky, odkud pocházejí vaši zákazníci, které produkty se prodávají nejlépe a jaký typ zákazníků nejvíce utrácí. Tyto informace vám můžou pomoct vylepšovat vaše webové stránky, abyste zaujali více návštěvníků. Z prostého textového souboru byste je dolovali jen stěží. V této části knihy se naučíte následující:
K2358_sazba.indd 235
V kapitole 9, „Vytváříme webovou databázi“, se dozvíte o základní konfiguraci pro připojení databáze MySQL k webu. Naučíte se vytvářet uživatele, databáze, tabulky a indexy a dozvíte se o nejrůznějších typech úložišť systému MySQL.
12.9.2017 8:33:57
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
236
Kapitola 10, „Práce s databází MySQL“, vysvětluje, jak se dotazovat do databáze, jak přidávat, odstraňovat a upravovat záznamy – a to vše z příkazového řádku.
V kapitole 11, „Přistupujeme do databáze z webu s jazykem PHP“, se dozvíte, jak propojit jazyk PHP se systémem MySQL, abyste mohli používat a spravovat svou databázi z webového rozhraní. Můžete používat dvě metody – nativní ovladač MySQL a databázově nezávislé rozšíření PDO.
Kapitola 12, „Pokročilá správa systému MySQL“, se věnuje správě systému MySQL podrobněji. Obsahuje informace o systému oprávnění, zabezpečení a optimalizaci.
Kapitola 13, „Pokročilé programování se systémem MySQL“, se zabývá typy databázových úložišť podrobněji, a to včetně transakcí, fulltextového vyhledávání a uložených procedur.
Koncepce relačních databází Relační databáze jsou nejrozšířenějším typem databází. Svůj základ mají v relační algebře. Nemusíte rozumět relační teorii, abyste mohli používat relační databáze, ale musíte znát základní koncepce relačních databází.
Tabulky Relační databáze se skládají z tabulek. Tabulky jsou přesně to, co naznačuje jejich název – tabulky dat. Pokud jste někdy pracovali s Excelem, už jste používali podobné tabulky. Prohlédněte si ukázkovou tabulku na obrázku 8.1. Obsahuje jména a adresy zákazníků obchodu Book-O-Rama. Customers CustomerID
Name
Address
City
1
Jana Nováková
Dubová 25
Pelhřimov
2
Aleš Světlý
Kopřivová 47
Horní Bečva
3
Michal Starý
Severní 357
Pustiměř
Obrázek 8.1. Informace o zákaznících obchodu Book-O-Rama uložené v tabulce
Tabulka se jmenuje Customers (zákazníci), přičemž obsahuje několik sloupců s různými kusy data a řádky odpovídající jednotlivým zákazníkům.
Sloupce Každý sloupec má jedinečný název a obsahuje různá data. Ke každému sloupci se váže určitý datový typ. V tabulce Customers na obrázku 8.1 můžete vidět, že sloupec CustomerID obsahuje celá čísla a v dalších třech sloupcích jsou textové řetězce. Sloupce se také občas nazývají pole nebo atributy.
K2358_sazba.indd 236
12.9.2017 8:33:57
KONCEPCE RELAČNÍCH DATABÁZÍ
237
Řádky Každý řádek v tabulce reprezentuje jiného zákazníka. Díky tabulkovému formátu mají všechny řádky stejné atributy. Řádkům se někdy rovněž říká záznamky.
Klíče Musíte mít možnost identifikovat jednotlivé zákazníky. Jména nejsou vhodným údajem k identifikaci. Pokud máte rozšířené jméno, pravděpodobně chápete proč. Uvažte kupříkladu jméno Jana Nováková z tabulky Customers. Když si otevřete telefonní seznam, najdete v něm příliš mnoho výskytů tohoto jména.
Navrhujeme webovou databázi
Jednotlivé řádky se skládají z různých hodnot pro jednotlivé sloupce. Každá hodnota musí mít datový typ, který odpovídá příslušnému sloupci.
8
Hodnoty
Mohli byste rozlišovat Janu několika způsoby. O něco pravděpodobnější je, že Jana Nováková je jedinou nositelkou tohoto jména na své adrese. Identifikace „Jana Nováková, žijící na adrese Dubová 25, v Pelhřimově“ je však poměrně krkolomná. Pravděpodobně by vyžadovala zapojení více sloupců tabulky. V tomto příkladu jste udělali něco, co bude i skvělým řešením ve vašich aplikacích – přiřadili jste jednotlivým zákazníkům jedinečné číselné identifikátory CustomerID. Jedná se o stejný princip, proč například máte jedinečné číslo účtu v bance nebo jedinečné klubové číslo. Díky tomu bude ukládání osobních údajů do databáze jednodušší. U uměle vygenerovaného čísla lze snadno zaručit, aby bylo jedinečné. Jen málo typů skutečných informací má tuto vlastnost, a to i když jich spojíte více. Identifikující sloupec tabulky se nazývá klíč nebo primární klíč. Klíče se můžou skládat z více sloupců. Kdybyste se opět vrátili k „Janě Novákové, Dubová 25, Pelhřimov“, mohli byste složit klíč ze sloupců Name (jméno), Address (adresa) a City (město) a přitom byste stále nemohli zaručit jedinečnost. Databáze se obvykle skládají z více tabulek, přičemž klíče slouží jako odkazy z jedné tabulky do druhé. Obrázek 8.2 ukazuje druhou tabulku přidanou do dané databáze. Každý řádek tabulky Orders (objednávky) představuje objednávku od nějakého zákazníka. Abyste neztratili přehled, ke kterému zákazníkovi objednávka patří, budete si ukládat k objednávce identifikátor zákazníka. Když si prohlédnete tuto tabulku, zjistíte například, že objednávku OrderID 2 vytvořil zákazník CustomerID 1. Pokud se potom podíváte do tabulky Customers, uvidíte, že zákazníkem 1 je Jana Nováková.
K2358_sazba.indd 237
12.9.2017 8:33:58
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
238
Customers CustomerID
Name
Address
City
1
Jana Nováková
Dubová 25
Pelhřimov
2
Aleš Světlý
Kopřivová 47
Horní Bečva
3
Michal Starý
Severní 357
Pustiměř
CustomerID
Amount
Date
Orders OrderID 1
3
687.50
02-Apr-2007
2
1
325.00
15-Apr-2007
3
2
1850.00
19-Apr-2007
4
3
175.00
01-May-2007
Obrázek 8.2. Každá objednávka v tabulce Orders se odkazuje na zákazníka z tabulky Customers
Relační databáze označuje tento typ vztahu jako cizí klíč. Sloupec CustomerID je primárním klíčem tabulky Customers, ale pokud se objeví v jiné tabulce, například v tabulce Orders, říká se mu cizí klíč. Možná se divíte, proč byste měli mít dvě samostatné tabulky. Proč neuložit adresu Jany do tabulky Orders? O tomto problému pojednává následující část této kapitoly.
Schémata Kompletní sada návrhů tabulek se nazývá schéma databáze. Jedná se o plán databáze. Schéma by mělo ukazovat tabulky s jejich sloupci, primární klíče a cizí klíče tabulek. Schéma neobsahuje data, ale můžete spolu s ním uvádět ukázková data, která pomáhají objasnit jednotlivé jeho komponenty. Schéma lze znázornit diagramem, kterému se říká ERD diagram (entity relationship diagram, jehož popis ale není součástí této knihy), nebo textově; například takto: Customers(CustomerID, Name, Address, City) Orders(OrderID, CustomeID, Amount, Date)
Podtržené sloupce jsou primární klíče tabulek, ve kterých jsou uvedené. Kurzíva označuje cizí klíče tabulek, v nichž jsou uvedené.
K2358_sazba.indd 238
12.9.2017 8:33:58
NAVRHOVÁNÍ WEBOVÉ DATABÁZE
239
Vztahy
Vztah jeden-na-jednoho znamená, že na každé straně se může nacházet jeden záznam. Když například oddělíte adresy a zákazníky do samostatných tabulek, můžete mezi nimi mít vztah jeden-na-jednoho. Cizí klíč byste mohli umístit buď do tabulky Addresses nebo do tabulky Customers (v obou být nemusí).
Navrhujeme webovou databázi
V relačních databázích jsou k dispozici tři základní druhy vztahů. Rozdělují se podle počtu prvků na každé straně vztahu. Vztahy můžou být jeden-na-jednoho, jeden-na-mnoho a mnoho-na-mnoho.
8
Cizí klíče reprezentují vztahy mezi daty dvou tabulek. Například cizí klíč z tabulky Orders odkazující do tabulky Customers představuje vztah mezi řádkem v tabulce Orders a řádkem v tabulce Customers.
Ve vztahu jeden-na-mnoho může patřit k řádku z první tabulky libovolný počet řádků z druhé tabulky. Například jeden zákazník může odeslat více objednávek. V takovém případě tabulka, která má více řádků (Orders), bude obsahovat cizí klíč, který bude odkazovat na řádek druhé tabulky (Customers). Proto jste umístili cizí klíč CustomerID do tabulky Customers. Ve vztahu mnoha-na-mnoho se více řádků z první tabulky hlásí k více řádkům z druhé tabulky. Předpokládejte kupříkladu, že máte dvě tabulky, Books (knihy) a Authors (autoři). Běžně se stává, že jednu knihu napíše více spoluautorů, případně že jeden autor napíše více knih, ať už sám, nebo jako spoluautor. Tento typ vztahu vyžaduje samostatnou tabulku, takže byste měli tabulky Books, Authors a Books_Authors. Tato třetí tabulka bude obsahovat jen klíče ze zbývajících dvou tabulek – tj. dvojice cizích klíčů, které říkají, jací autoři napsali jaké knihy.
Navrhování webové databáze Poznat, že potřebujete novou třídu a jakou by měla mít klíč, je tak trochu umění. Můžete si přečíst hromadu materiálů o ERD diagramech a normalizaci databází. Tato témata jsou však nad rámec této knihy. Většinou si vystačíte s několika základními principy návrhu, o nichž se naučíte na příkladu obchodu Book-O-Rama.
Představujte si skutečné objekty, které se snažíte modelovat Když vytváříte databázi, obvykle modelujete skutečné objekty a vztahy, abyste o nich mohli ukládat informace. Každá třída objektů, kterou modelujete, potřebuje svou vlastní tabulku. Můžete si to představit takto: chcete ukládat stejné informace o všech zákaznících. Pokud skupiny dat mají stejný „tvar“, můžete pro ně vytvořit odpovídající tabulku.
K2358_sazba.indd 239
12.9.2017 8:33:59
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
240
V obchodu Book-O-Rama budete chtít ukládat informace o zákaznících, o knihách, které prodáváte a o objednávkách. Všichni zákazníci se nějak jmenují a někde bydlí. Každá objednávka má datum, celkovou cenu a skupinu objednaných knih. Každá kniha má číslo ISBN, autora, název a cenu. Potřebujete tudíž alespoň tři tabulky v této databázi – Customers, Orders a Books. Tento základ schématu si můžete prohlédnout na obrázku 8.3. Customers CustomerID
Name
Address
City
1
Jana Nováková
Dubová 25
Pelhřimov
2
Aleš Světlý
Kopřivová 47
Horní Bečva
3
Michal Starý
Severní 357
Pustiměř
CustomerID
Amount
Date
Orders OrderID 1
3
27.50
02-Apr--2007
2
1
12.99
15-Apr-2007
3
2
74.00
19-Apr-2007
4
3
6.99
01-May-2007
Books ISBN
Author
Title
Price
9788025137505
Ondřej Baše
jQuery pro neprogramátory
424
9788025147375
Timothy Boronczyk
MySQL Okamžitě
212
9788025141960
Callum Hopkins
PHP Okamžitě
212
Obrázek 8.3. Základ schématu se skládá z tabulek Customers, Orders a Books
Ze současného modelu nemůžete určit, které knihy patří do dané objednávky. Tuto situaci vyřešíte za chvíli.
K2358_sazba.indd 240
12.9.2017 8:33:59
NAVRHOVÁNÍ WEBOVÉ DATABÁZE
241
Neukládejte redundantní data Dříve jsme si položili otázku: „Co nám brání, abychom uložili adresu Jany Novákové do tabulky Orders?“ Kdyby si Jana Nováková objednávala z obchodu Book-O-Rama častěji, ukládali bychom její adresu opakovaně. Tabulka Orders by nakonec mohla vypadat jako na obrázku 8.4. Date
CustomerID
Name
Address
City
12
4987.50
25-Apr-2007
1
Jana Nováková
Dubová 25
Pelhřimov
13
1075.00
29-Apr-2007
1
Jana Nováková
Dubová 25
Pelhřimov
14
399.99
30-Apr-2007
1
Jana Nováková
Dubová 25
Pelhřimov
15
594.00
01-May-2007
1
Jana Nováková
Dubová 25
Pelhřimov
8
Amount
Navrhujeme webovou databázi
OrderID
Obrázek 8.4. Návrh databáze vede k ukládání redundantních dat, která zbytečně zabírají diskový prostor a můžou způsobovat různé problémy
Takový návrh s sebou nese dva problémy:
Plýtvá diskovým prostorem. Proč ukládat údaje o Janě čtyřikrát, když je stačí uložit jednou?
Může vést k aktualizačním anomáliím – to jsou situace, kdy změna v databázi skončí nekonzistentními daty. Jakmile dojde k narušení integrity dat, už nemůžete určit, která data jsou správná, a která nikoliv. To obvykle vede ke ztrátě dat.
Měli byste se vyhýbat třem aktualizačním anomáliím: anomáliím úprav, vkládání a mazání. Kdyby se Jana přestěhovala v době, kdy bude mít nevyřízené objednávky, museli byste měnit její adresu na čtyřech místech současně – to je čtyřnásobné množství práce. Kdybyste ignorovali tuto skutečnost a změnili její adresu jen na jediném místě, měli byste nekonzistentní data v databázi (to je velmi špatná věc). Tyto problémy se označují anomálie úprav, protože nastávají při úpravách záznamů. S tímto návrhem musíte vkládat Janiny osobní údaje, kdykoliv si něco objedná. Vždy musíte zajišťovat, aby její údaje zůstaly konzistentní s již uloženými daty. Kdybyste to neudělali, skončili byste s konfliktními informacemi o Janě. Například jeden řádek by tvrdil, že Jana žije v Pelhřimově, kdežto druhý řádek by tvrdil, že žije v Humpolci. Tuto situaci nazýváme anomálií vkládání, jelikož vzniká při vkládání záznamů. Třetí typ anomálie se označuje jako anomálie mazání, protože nastává, když mažete záznamy z databáze. Představte si kupříkladu, že po odeslání objednávky zákazníkovi ji budete chtít vymazat. Jakmile byste vyřídili všechny Janiny objednávky, zmizely by z tabulky Orders. To by znamenalo, že už neznáte nadále Janinu adresu. Nemůžete ji posílat speciální nabídky, a až si bude chtít příště objednat, bude muset vyplňovat všechny osobní údaje znovu.
K2358_sazba.indd 241
12.9.2017 8:34:00
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
242
Databáze byste měli navrhovat tak, aby k těmto anomáliím nedocházelo.
Používejte atomické hodnoty sloupců Používat atomické hodnoty sloupců znamená ukládat do každého sloupce každého řádku jen jedinou informaci. Kdybyste kupříkladu chtěli vědět, z jakých knih se objednávka skládá, mohli byste to udělat mnoha způsoby. Jedním řešením by bylo přidat do tabulky Objednavky sloupec se všemi objednanými knihami, jak lze vidět na obrázku 8.5. Orders OrderID
CustomerID
Amount
Date
Books Ordered
1
3
687.50
02-Apr-2007
9788025137505
2
1
325.00
15-Apr-2007
9788025147375, 9788025141960
3
2
1850.00
19-Apr-2007
9788025137505
4
3
175.00
01-May-2007
9788025147375, 9788025141960, 9788025137505
Obrázek 8.5. S tímto návrhem by sloupec Books Ordered obsahoval více hodnot
Toto řešení není dobrým nápadem z mnoha důvodů. Ve skutečnost vkládáte celou tabulku do jednoho sloupce – tabulku, která by měla spojovat objednávky s knihami. Když vytváříte podobné sloupce, je složitější odpovídat na otázky typu: „Kolik kopií knihy jQuery pro neprogramátory si zákazníci objednali?“ Systém nemůže jednoduše spočítat odpovídající záznamy. Místo toho je nutné parsovat hodnoty ve sloupcích, abyste mohli porovnávat jejich obsah. Protože ve skutečnosti vytváříte tabulku v tabulce, měli byste raději vytvořit samostatnou tabulku. Tuto novou tabulku můžete pojmenovat například Order_Items (viz obrázek 8.6). Order_Items OrderID
ISBN
Quantity
1
9788025137505
1
2
9788025147375
2
2
9788025141960
1
3
9788025137505
1
4
9788025147375
1
4
9788025141960
2
4
9788025137505
1
Obrázek 8.6. Tento návrh usnadňuje hledání objednaných knih
Tato tabulka vytváří vazby mezi tabulkami Orders a Books. Takový typ tabulky reprezentuje vztah mnoho-na-mnoho mezi dvěma objekty – jedna objednávka se může skládat z více knih a jedna kniha může být součástí více objednávek.
K2358_sazba.indd 242
12.9.2017 8:34:00
NAVRHOVÁNÍ WEBOVÉ DATABÁZE
243
Jestliže máte řešit problém, který skutečně vyžaduje neatomické hodnoty sloupců, měli byste zvážit výběr databáze pro tento typ dat namísto relační databáze. Jedná se o tzv. nerelační databáze, databáze NoSQL nebo datová úložiště. (Databázemi NoSQL se však tato kniha nezabývá.)
Navrhujeme webovou databázi
Ujistěte se, že vybíráte klíče, které jsou jedinečné. V tomto případě jste vytvořili speciální klíče pro zákazníky (CustomerID) a objednávky (OrderID), protože tyto objekty skutečného světa nemusí mít identifikátory, které jsou zaručeně jedinečné. Nemusíte ale vytvářet jedinečný identifikátor pro knihy, protože ten už existuje – jedná se o kód ISBN. Do tabulky Order_Items byste mohli doplnit další klíč, kdybyste chtěli, ale kombinace sloupců OrderID a ISBN je jedinečná, dokud pracujete s více kopiemi stejné knihy v objednávce jako s jedním záznamem. Tabulka Order_Items obsahuje sloupec Quantity právě z tohoto důvodu.
8
Vybírejte smysluplné klíče
Přemýšlejte, na co se chcete dotazovat databáze Popřemýšlejte, na jaké otázky by měla vaše databáze odpovídat. Například, které knihy se v obchodě Book-O-Rama prodávají nejlépe? Nezapomeňte, že vaše databáze by měla obsahovat všechna nezbytná data a že k získání odpovědí můžete používat i vztahy mezi tabulkami.
Vyhýbejte se návrhům s mnoha prázdnými sloupci Kdybyste chtěli přidat recenze knihy do vaší databáze, mohli byste to udělat přinejmenším dvěma způsoby. Oba můžete vidět na obrázku 8.7. Books ISBN
Author
Title
Price
9788025137505
Ondřej Baše
jQuery pro neprogramátory
424
9788025147375
Timothy Boronczyk
MySQL Okamžitě
212
9788025141960
Callum Hopkins
PHP Okamžitě
212
Review
Books_Reviews ISBN
Review
Obrázek 8.7. Recenze knih je možné doplnit přidáním sloupce Review do tabulky Books nebo přidáním samostatné tabulky pro recenze
K2358_sazba.indd 243
12.9.2017 8:34:01
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
244
První řešení spočívá v přidání sloupce Review do tabulky Books. Tímto způsobem získají všechny knihy sloupec Review. Pokud máte v databázi spoustu knih a recenzent je neplánuje recenzovat všechny, spousta řádků nebude mít hodnotu v tomto poli. Ve skutečnosti ale bude mít hodnotu NULL. Mít spoustu hodnot NULL v databázi není rozumné. Plýtváte tak diskovým prostorem a způsobuje to problémy se součty a jinými funkcemi pro číselné sloupce. Když uživatel uvidí hodnotu NULL v tabulce, neví, jestli je tento sloupec irelevantní, databáze obsahuje chybu nebo zatím nikdo tato data nezadal. Problémům s mnoha hodnotami NULL se můžete vyhnout, když navrhnete svou databázi jinak. V tomto případě byste mohli zvolit druhý návrh z obrázku 8.7. V tabulce Book_ Reviews jsou uvedené pouze knihy s recenzemi. Zapamatujte si, že první návrh předpokládal, že máte recenzenta, který nebude psát více recenzí pro jedinou knihu – tj. mezi knihami a recenzemi existuje vztah jeden-na-jednoho. Druhý návrh umožňuje psát více recenzí ke stejné knize – tj. mezi knihami a recenzemi je vztah jeden-na-mnoho. Pokud si vystačíte s jednou recenzí na knihu, můžete u druhého návrhu udělat primární klíč ze sloupce ISBN v tabulce Book_Reviews. Kdybyste chtěli mít více recenzí jedné knihy, měli byste zavést ještě nový jedinečný identifikátor do této tabulky. Přehled typů tabulek
Často zjistíte, že váš návrh tabulek dopadne tak, že bude obsahovat dva typy tabulek:
Jednoduché tabulky popisující reálné objekty. Mohou také obsahovat cizí klíče odkazující na další jednoduché objekty, s nimiž jsou ve vztahu jeden-na-jednoho nebo jeden-na-mnoho. Například – zákazník může mít více objednávek, ale objednávku může vytvořit jediný zákazník. Proto vkládáte odkaz na zákazníka do objednávky.
Spojovací tabulky, které popisují vztahy mnoho-na-mnoho mezi dvěma reálnými objekty, jako jsou kupříkladu vztahy mezi objednávkami a knihami. Tyto tabulky většinou odpovídají nějakému typu transakcí skutečného světa.
Architektura webové databáze Když už známe interní architekturu databáze, můžeme se zaměřit na externí architekturu webového databázového systému a ukázat si, jak vyvíjet takový systém. Obrázek 8.8 popisuje základní operace webového serveru. Celý systém se skládá ze dvou objektů – webového prohlížeče a webového serveru. Mezi nimi je nezbytná komunikační linka. Webový prohlížeč odesílá požadavek serveru. Server posílá zpět odpověď. Tato architektura vyhovuje skvěle serveru, který prezentuje statické stránky. Architektura s webovými stránkami postavenými na databázi je o něco složitější.
K2358_sazba.indd 244
12.9.2017 8:34:02
ARCHITEKTURA WEBOVÉ DATABÁZE
245
Požadavek Prohlížeč
Webový server Odpověď
1 Prohlížeč
2 Webový server
6
3 Jádro PHP
5
Server MySQL 4
Obrázek 8.9. Vztah klient-server mezi webovým prohlížečem a webovým serverem vyžaduje komunikační spojení
Navrhujeme webovou databázi
Webové aplikace s databází, s nimiž se setkáte v této knize, se řídí běžnou strukturou webové databáze, kterou můžete vidět na obrázku 8.9. Převážnou část této struktury byste měli už znát.
8
Obrázek 8.8. Vztah klient-server mezi webovým prohlížečem a webovým serverem vyžaduje komunikační spojení
Typická transakce webové databáze má níže uvedené fáze, které jsou očíslované na obrázku 8.9. Tyto fáze si popíšeme na příkladu obchodu Book-O-Rama:
Webový prohlížeč uživatele odesílá požadavek HTTP pro určitou webovou stránku. Například uživatel si může skrze webový formulář vyžádat vyhledání všech knih, které napsala Laura Thomson. Stránka s výsledky hledání se jmenuje results.php.
Webový server přijímá požadavek na stránku results.php, načítá tento soubor a předává ho jádru PHP ke zpracování.
Jádro PHP začíná parsovat tento skript. Uvnitř tohoto skriptu se nachází příkazy pro připojení k databázi a pro provedení dotazu (vyhledávajícího knihy). Interpret PHP otevírá spojení se serverem MySQL a posílá mu tento dotaz.
Server MySQL přijímá tento dotaz do databáze, zpracovává ho a odesílá výsledky (seznam knih) zpět jádru PHP.
Jádro PHP dokončí provádění skriptu, který většinou formátuje výsledky dotazu do kódu HTML. Potom vrací výsledný kód jazyka HTML webovému serveru.
Webový server posílá tento kód HTML zpět webovému prohlížeči, v němž si uživatel může prohlédnout seznam vyhledaných knih.
Tento proces zůstává stejný, ať používáte jakékoliv skriptovací jádro nebo databázový server. Někdy běží webový server, jádro PHP a databázový server na jediném stroji. Není ale ani neobvyklé, aby databázový server běžel na jiném stroji. Může tomu tak být kvůli vyšší bezpečnosti, vyšší kapacitě nebo rozdělování zátěže. Z pohledu vývoje se ale tento proces nemění, mění se jen jeho efektivita. Jak bude vaše aplikace narůstat, začnete ji rozdělovat do vrstev – obvykle se jedná o databázovou vrstvu pro komunikaci s databází, vrstvu řídicí logiky, která představuje jádro aplikace,
K2358_sazba.indd 245
12.9.2017 8:34:02
KAPITOLA 8 NAVRHUJEME WEBOVOU DATABÁZI
246
a prezentační vrstvu, která se stará o generování výstupu. Základní architektura z obrázku 8.9 zůstává i v tomto případě zachována – pouze lépe strukturujete kód jazyka PHP.
Další zdroje V této kapitole jste se seznámili s návrhem relačních databází. Pokud chcete více proniknout do teorie relačních databází, zkuste si přečíst knihy od nějakého relačního guru, například od C.J. Data. Měli byste však vědět, že jeho knihy můžou být značně teoretické a jejich praktický přínos pro webového vývojáře nemusí být přímočarý. Běžná webová databáze není příliš složitá.
Co bude dál V příští kapitole vytvoříte databázi MySQL. Nejprve se naučíte, jak ji nakonfigurovat pro web a jak se do ní dotazovat, a potom také to, jak se dotazovat z jazyka PHP.
K2358_sazba.indd 246
12.9.2017 8:34:02