Velká kniha PHP a MySQL 5

Page 1

E N C Y K L O P E D I E ENCYKLOPEDIE WEBDESIGNERA

W. Jason Gilmore

KOMPENDIUM ZNALOSTÍ PRO ZAČÁTEČNÍKY I PROFESIONÁLY

První vydání této knihy z roku 2005 bylo v poměrně k rátké době rozebráno a kniha se zařadila mezi bestseller y vydavatelství Zoner Press. Nové vydání knihy je výrazně rozšířeno a doplněno, přibylo více než 150 stran a 7 nových kapitol: tři z nich jsou věnované specifickým tématům PHP – probírají se v nich PEAR (PHP Extension and Application Repository), funkcionalita související s dat em a s časem a rozšíření PDO (PHP Data Objec ts). Ve čtyřech dalších k apitolách najdete výklad rozšíření mysqli PHP 5 a novou funkcionalitu MySQL 5 – uložené rutiny, triggery a pohledy na data (views). Upraveny a doplněny byly i původní kapitoly knihy, které jsou věnovány klíčovým schopnostem PHP i MySQL počínaje instalací a konfigurací jak na platformě Linux, tak i Windows, práci s proměnnými, datovými typy, poli i funkcemi, ale také např. využití šablon Smarty a webových služeb, až po pokročilé rysy objektově orientovaného programování, zpracování výjimek nebo detekci chyb. Práci s databáz emi se v ěnuje téměř polovina knihy, pozornost je zaměřena především na M ySQL a SQLit e, nechybí však ani inf ormace o spolupráci s jinými databázovými systémy. Vedle již zmíněných novinek v knize najdete kapitoly věnované např. možnostem indexování, tvorbě databázových dotazů a řadě dalších praktických témat. Všechny ukázkové příklady najdete buďto na webu původního vydavatele www.apress.com, nebo na str ánkách našeho v ydavatelství www.zonerpress.cz v sekci Download.

www.zoner.cz © Foto: Jiří Heller, www.heller.cz

Věrným čtenářům je určen výhodný PRÉMIOVÝ PLUS PROGRAM.

Fotografie z nabídky fotobanky HELLER.CZ

E N C Y K LO P E D I E W E B D E S I G N E R A

DOPORUČENÁ CENA: 650 KČ KATALOGOVÉ ČÍSLO: ZR617

Zoner Press tel.: 532 190 883 fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz

VELKÁ

KNIHA

PHP MySQL SQL 5

KOMPENDIUM ZNALOSTÍ PRO ZAČÁTEČNÍKY I PROFESIONÁLY /přepracované, doplněné a rozšířené vydání publikace z roku 2005/

© Foto: Jiří Heller

W. Jason Gilmore

ISBN 80-86815-53-6

ZONER software, s.r.o., Nové sady 18, 602 00 Brno 9 7 8 8 0 8 6

PHP_sec.indd 1

kompendium znalostí pro začátečníky a profesionály

ZONER software, s.r.o. významný producent software v oblasti digitální fotografie, počítačové grafiky a multimédií, poskytovatel internetových služeb, souvisejících s prezentací na internetu a e-komercí, a nakladatelství odborné literatury.

VELKÁ KNIHA

PHP & MySQL 5

PHP MySQL 5

W. Jason Gilmore

VELKÁ KNIHA

Pod tímto logem vycházejí publikace určené pro každého, kdo se zajímá o t vorbu webových stránek. Od r yze praktických příruček a průvodců až po komplexní publikace o všem, co potřebuje webdesignér při každodenní práci. Na vydavatelský plán a výhody, které můžete získat, se informujte na adrese vydavatelství.

W E B D E S I G N E R A

8 1 5 5 3 4

www.zonerpress.cz

15.12.2006 15:53:57


VELKÁ KNIHA

PHP a MySQL 5 KOMPENDIUM ZNALOSTÍ PRO ZAČÁTEČNÍKY I PROFESIONÁLY /přepracované, doplněné a r ozšířené vydání publikace z r oku 2005/

W. Jason Gilmore


Beginning PHP and MySQL 5: From Novice to Professional, Second Edition Copyright © 2006 by W. Jason Gilmore Original English language published Apress L.P., 2560 Ninth Street, Suite 219, Berkeley, CA 9 47 10 USA. Copyright © 2006 by Apress L.P. CZECH language edition copyright © 2006 by ZONER software, s.r.o. All rights reserved. No part of this book ma y be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Apress L.P. Originál v anglickém jaz yce vydal Apress L.P., 2560 Ninth Street, Suite 219, Berkeley, CA 9 47 10 USA. C opyright © 2006 Apress L.P. České vydání Copyright © 2006 ZONER software s.r.o.. Všechna práva vyhrazena. Žádná část t éto publikace nesmí být reprodukována nebo předávána žádnou formou nebo způsobem, elektronicky ani mechanicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení Apress L.P.

Velká kniha PHP a MySQL 5 kompendium znalostí pro začátečníky i profesionály přepracované, doplněné a rozšířené vydání publikace z roku 2005 Autor: W. Jason Gilmore Copyright © ZONER software, s.r.o. Vydání první v roce 2007. Všechna práva vyhrazena. Zdrojový kód příkladů uvedených v knize je k dispozici na adrese http://www.apress.com v sekci Source Code nebo na adrese http://www.zonerpress.cz v sekci Download. Zoner Press KATALOGOVÉ ČÍSLO: ZR617 ZONER software, s.r.o. Nové sady 18, 602 00 Brno Překlad: RNDr. Jan Pokorný Odpovědný redaktor: Miroslav Kučera, Pavel Kristián Šéfredaktor: Ing. Pavel Kristián DTP: Filip Božoň © Cover foto: Jiří Heller, HELLER.CZ s.r.o., www.heller.cz © Cover a layout: Ing. Pavel Kristián Informace, které jsou v t éto knize zveřejněny, mohou byt chráněny jako patent. Jména produktů byla uvedena bez záruky jejich volného použití. Při tvorbě textů a vyobrazení bylo sice postupováno s maximální péčí, ale přesto nelze zcela vyloučit možnost výskytu chyb. Vydavatelé a autoři nepřebírají právní odpovědnost ani žádnou jinou záruku za použití chybných údajů a z toho vyplývajících důsledků. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována ani distribuována žádným způsobem ani prostředkem, ani reprodukována v databázi či na jiném záznamo vém prostředku či v jiném systému bez výslovného svolení vydavatele s výjimkou zveřejnění krátkých částí textu pro potřeby recenzí. Veškeré dotazy týkající se distribuce směřujte na: Zoner Press ZONER software, s.r.o. Nové sady 18, 602 00 Brno tel.: 532 190 883, fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz

ISBN 80-86815-53-6


Kniha je věnována památce Dr. Giovanni „Nino“ Sanzi (1929-2004). Addio, caro amico.


Stručný obsah Kapitola 1 Kapitola 2 Kapitola 3 Kapitola 4 Kapitola 5 Kapitola 6 Kapitola 7 Kapitola 8 Kapitola 9 Kapitola 10 Kapitola 11 Kapitola 12 Kapitola 13 Kapitola 14 Kapitola 15 Kapitola 16 Kapitola 17 Kapitola 18 Kapitola 19 Kapitola 20 Kapitola 21 Kapitola 22 Kapitola 23 Kapitola 24 Kapitola 25 Kapitola 26 Kapitola 27 Kapitola 28 Kapitola 29 Kapitola 30 Kapitola 31 Kapitola 32 Kapitola 33 Kapitola 34 Kapitola 35 Kapitola 36 Kapitola 37

Úvod do PHP Instalace a konfigurace Apache a PHP Základy PHP Funkce Pole Objektově orientované programování v PHP Vyspělé schopnosti OOP Zpracování chyb a výjimek Řetězce a regulární výrazy Práce se systémem souborů a s operačním systémem PEAR Datum a čas Formuláře a navigační pomůcky Autentizace Upload souborů Networking PHP a LDAP Zpracovatelé sezení Šablony se Smarty Webové služby Bezpečné programování v PHP SQLite Úvod do PDO Úvod do MySQL Instalace a konfigurace MySQL Klienti MySQL Ukládací enginy MySQL a datové typy Zabezpečení MySQL Rozšíření mysql v PHP Rozšíření mysqli v PHP Uložené rutiny Triggery MySQL Pohledy Databázové dotazy v praxi Indexy a vyhledávání Transakce Import a export dat Rejstřík

31 39 69 115 127 153 177 197 211 247 277 289 319 341 359 373 409 431 451 475 515 533 551 569 579 603 625 655 681 709 733 755 767 779 801 817 831 845


Obsah O autorovi O odborném recenzentovi Poděkování

25 25 26

Pošlete nám váš názor Zdrojové soubory Úvod

27 27 29

Kapitola 1

Úvod do PHP

Historie PHP 4 PHP 5

31 31 32 34

Všeobecné rysy jazyka Upotřebitelnost Vyspělost Možnosti

35 35 36 36

Cena Shrnutí

37 37

Kapitola 2

Instalace a konfigurace Apache a PHP

39

Instalace Obstaráme si distribuce Proces instalace Otestování instalace Přizpůsobení vybudované distribuce pro Unix Přizpůsobení vybudované distribuce pro Windows Běžné potíže Prohlížení a stažení dokumentace

39 39 41 46 47 47 48 48

Konfigurace Správa konfiguračních direktiv PHP Konfigurační direktivy PHP Shrnutí

49 49 51 68

Kapitola 3

Základy PHP

Únik k PHP Výchozí syntax Krátké značky Styl <script>

69 69 70 70 71


8

Obsah Styl ASP Vkládání několika bloků kódu

71 71

Komentáře Syntax jediného řádku z C++ Syntax shellu Komentář na několika řádcích ve stylu C

72 72 72 72

Výstup print() echo() printf() sprintf()

73 73 74 74 75

Typy dat Skalární datové typy Složené datové typy Resource Přetypování Žonglování s typy Funkce vztahující se k typům

76 76 77 79 80 81 82

Identifikátory Proměnné Deklarace proměnné Obor proměnné Superglobální proměnné PHP Proměnné proměnné

83 84 84 85 88 93

Konstanty Výrazy Operandy Operátory

93 94 94 94

Interpretace řetězců Uvozovky Apostrofy heredoc

100 100 101 102

Řídící struktury Příkazy, které řídí vykonávání Podmínkové příkazy Příkazy cyklu Příkazy pro vkládání souborů

102 103 104 106 111

Shrnutí

113


Velká kniha PHP a MySQL 5

Kapitola 4

9

Funkce

115

Volání funkcí Vytvoření funkce Předávání argumentů hodnotou Předávání argumentů odkazem Výchozí hodnoty argumentů Nepovinné argumenty Návratové hodnoty funkcí Vracení více hodnot najednou Vnořování funkcí Rekurzivní funkce Funkce jako proměnná

115 116 116 117 118 118 119 120 120 121 123

Knihovny funkcí Shrnutí

124 125

Kapitola 5

Pole

127

Co je pole? Výstup polí Jak se vytvoří pole Test, zda se jedná o pole

128 129 130 132

Přidávání a odstraňování prvků pole Vyhledávání prvků v poli

133 134

Procházení polí Zjištění velikosti a jedinečných hodnot pole Setřídění prvků polí Kombinace, sloučení, extrakce a porovnání Další užitečné funkce pro práci s poli Shrnutí

136 140 141 146 150 152

Kapitola 6

Objektově orientované programování v PHP

153

Zisky plynoucí z OOP Zapouzdření Dědění Polymorfizmus

154 154 155 155

Klíčové pojmy OOP Třídy Objekty Členské proměnné

156 156 157 157


10

Obsah Vlastnosti Konstanty Metody

160 163 163

Rada pro typ Konstruktory a destruktory Konstruktory Destruktory

167 168 168 171

Statické členy tříd Klíčové slovo instanceof Pomocné funkce Automatické načítání objektů Shrnutí

172 173 173 175 176

Kapitola 7

Pokročilé schopnosti OOP

177

Schopnosti OOP nepodporované v PHP Klonování objektů Příklad klonování Metoda _ _clone()

178 178 178 180

Dědění Dědění třídy Dědění a konstruktory

181 181 183

Rozhraní Dědění jednoho rozhraní Implementace více rozhraní

185 186 187

Abstraktní třídy Reflexe Shrnutí

188 189 195

Kapitola 8

Zpracování chyb a výjimek

197

Konfigurační direktivy Protokolování chyb Zpracování výjimek Proč je zpracování výjimek prospěšné Implementace zpracování výjimek v PHP

198 201 203 203 205

Shrnutí

209

Kapitola 9

Řetězce a regulární výrazy

Syntaxe se složenými závorkami {}

211 211


Velká kniha PHP a MySQL 5

11

Regulární výrazy Syntax regulárních výrazů ve stylu POSIX Syntax regulárních výrazů ve stylu Perlu

212 213 218

Další funkce pro práci s řetězci Určování délky řetězce Porovnávání dvou řetězců Úpravy velikosti písmen Převádění řetězců do HTML a z HTML Alternativy pro funkce regulárních výrazů Doplňování a zkracování řetězce Počítání znaků a slov

225 226 226 228 229 234 241 242

Využití předností balíku Validate_US PEAR Instalace balíku Validate_US Jak se používá balík Validate_US

244 245 245

Shrnutí

246

Kapitola 10 Práce se systémem souborů a s operačním systémem

247

Soubory a adresáře Analýza cest k adresářům Typy souborů a odkazy Zjišťování velikosti souboru, adresáře a disku Časy posledního přístupu a modifikace

248 248 250 253 256

Vlastnictví souborů a povolení Vstupní a výstupní (I/O) operace se soubory Pojem prostředek Znak pro nový řádek Konec souboru Otevření a uzavření souboru Čtení ze souboru Přesouvání ukazatele souboru Zapisování do souboru Čtení obsahu adresářů

257 259 259 260 260 260 262 267 268 268

Vykonávání příkazů shellu Vykonávání programů na systémové úrovni Shrnutí

270 271 275

Kapitola 11 PEAR Populární balíky PEAR Konverze číselných formátů

277 277 279


12

Obsah Instalace a aktualizace PEAR Instalace PEAR PEAR a hostitelské firmy Aktualizace PEAR

280 280 282 282

Jak se pracuje s manažerem balíků PEAR Jaké balíky jsou nainstalované Jak získáte další informace o nainstalovaném balíku Instalace balíku Jak se pracuje s balíkem Modernizace balíku Odinstalování balíku Přechod na starší verzi balíku

282 283 283 284 286 287 287 288

Shrnutí

288

Kapitola 12 Datum a čas

289

Časová známka Unixu Knihovna PHP pro datum a čas Bojové umění „Date Fu“ Zobrazení lokalizovaného data a času Zobrazení data poslední modifikace webové stránky Zjištění počtu dní aktuálního měsíce Určení data vzdáleného x dní od aktuálního data Vytvoření kalendáře

289 290 297 297 301 301 302 303

PHP 5.1 Základní informace o Date Konstruktor Date Accessory a mutátory Validátory Manipulační metody

306 307 307 308 311 311

Shrnutí

317

Kapitola 13 Formuláře a navigační pomůcky PHP a webové formuláře Jednoduchý příklad Předávání dat formuláře do funkce Práce s vícehodnotovými komponentami formuláře Generování formulářů s PHP Automatický výběr na formuláři PHP, webové formuláře a JavaScript

319 320 320 321 322 324 326 327


Velká kniha PHP a MySQL 5

13

Navigační pomůcky Uživatelsky přívětivé URL Navigační stopy Vytváření vlastních zpracovatelů chyb

329 329 333 337

Shrnutí

339

Kapitola 14 Autentizace

341

Pojmy autentizace HTTP Autentizace PHP Proměnné autentizace Různé metodologie autentizace Autentizace založená na IP adrese Využití PEAR: Auth_HTTP

341 342 343 344 348 349

Administrace přihlašování uživatelů Ustanovení hesel Testování jak snadno lze uhádnout heslo s knihovnou CrackLib Jednorázové URL a obnova hesla

352 352 354 356

Shrnutí

358

Kapitola 15 Upload souborů

359

Nahrávání souborů přes protokol HTTP Nahrávání na server s PHP Direktivy PHP pro nahrávání souborů a pro prostředky Pole $_FILES Funkce PHP pro nahrávání na server Chybové zprávy týkající se nahrávání Ukázky nahrávání souborů

359 360 360 362 363 364 365

Dejte přednost PEAR: HTTP_Upload Instalace HTTP_Upload Získáme informace o nahraném souboru Přesun nahraného souboru na cílové umístění Nahrávání více souborů najednou

368 368 369 370 370

Shrnutí

371

Kapitola 16 Networking DNS, služby a servery DNS Služby

373 374 374 377


14

Obsah Zřizování soketových připojení

378

Pošta Konfigurační direktivy Odeslání e-mailu, který obsahuje jen čistý text Odeslání e-mailu s dodatečnými záhlavími Odeslání e-mailu více příjemcům Odeslání e-mailu formátovaného jako HTML Jak se odešle příloha

380 380 381 382 382 383 384

IMAP, POP3 a NNTP Požadavky Zřízení a uzavření připojení Další informace o poštovních přihrádkách a poště Získávání zpráv Sestavení zprávy Odeslání zprávy Administrace poštovní přihrádky Administrace zpráv

385 385 386 388 390 397 398 398 400

Proudy Obaly proudů a kontexty Filtry proudů

400 401 402

Běžné síťové úkoly Zvonění na server Skener portu Konvertor podsítě Testování šířky pásma uživatele

404 404 405 405 407

Shrnutí

408

Kapitola 17 PHP a LDAP

409

Úvod do LDAP Další informace o LDAP

410 411

PHP a LDAP Připojení k serveru LDAP Vázání k serveru LDAP Uzavření připojení k serveru LDAP Získávání dat LDAP Práce s hodnotami položek Počet získaných položek Získávání atributů Řazení a porovnávání položek LDAP

411 411 412 413 414 415 416 417 420


Velká kniha PHP a MySQL 5 Práce s položkami Dealokace paměti Vkládání dat LDAP Aktualizace dat LDAP Odstraňování dat LDAP Konfigurační funkce Znakové sady Práce s distingovaným názvem Zpracování chyb Shrnutí

Kapitola 18 Zpracovatelé sezení

15 421 423 424 425 426 426 428 428 429 430

431

Co je to zpracování sezení? Cookies Přepisování URL Proces zpracování sezení

431 432 432 432

Konfigurační direktivy Klíčové pojmy Startování sezení Likvidace sezení Získávání a nastavování ID sezení Vytváření a odstraňování proměnných sezení Zakódování a dekódování dat sezení

433 438 438 439 439 440 440

Praktické ukázky zpracování sezení Automatizované přihlašování Seznam naposled prohlížených dokumentů

442 442 444

Vytváření vlastních zpracovatelů sezení Včlenění vlastních funkcí sezení do logiky PHP Vlastní zpracovatelé sezení založení na MySQL

445 446 447

Shrnutí

450

Kapitola 19 Šablony se Smarty Co je stroj na šablony? Úvod do Smarty Instalace Smarty Práce se Smarty Prezentační logika Smarty Komentáře

451 452 453 454 456 458 458


16

Obsah Modifikátory proměnné Řídící struktury Speciální příkazy

458 461 465

Vytváření konfiguračních souborů Odkazy na konfigurační proměnné

468 469

CSS v součinnosti se Smarty Ukládání stránek do cache Doba života stránek uložených v cache Eliminace režijních nákladů na zpracování s is_cached() Vytvoření několika cache pro jednu šablonu Několik slov závěrem k ukládání do cache

470 471 472 472 473 474

Shrnutí

474

Kapitola 20 Webové služby

475

Proč webové služby? Real Simple Syndication Syntax RSS MagpieRSS

476 478 480 481

SimpleXML Funkce SimpleXML Metody SimpleXML

488 489 490

SOAP NuSOAP Rozšíření SOAP PHP 5

493 494 503

Použití klienta C# s webovou službou PHP Shrnutí

512 514

Kapitola 21 Bezpečné programování v PHP

515

Bezpečná konfigurace PHP Bezpečný mód Další konfigurační direktivy vztahující se bezpečnému módu

516 516 518

Skrývání podrobností konfigurace Skrytí Apache a PHP

520 520

Skrývání citlivých dat Dbejte řádně o kořen dokumentů Zamítněte přístup k souborům s určitými příponami

522 522 523

Desinfekce dat uživatele Vymazání souborů

523 524


Velká kniha PHP a MySQL 5 Skriptování přes weby Desinfekce vstupu od uživatele: řešení

17 524 526

Šifrování dat Šifrovací funkce PHP mhash MCrypt

528 528 529 530

Shrnutí

532

Kapitola 22 SQLite

533

SQLite Instalace SQLite Práce v rozhraní příkazového řádku SQLite

533 534 534

Knihovna SQLite PHP Direktivy SQLite Jak se otevře připojení Vytvoření tabulky v paměti Uzavření připojení Dotazy na databázi Analýza sad výsledků Získávání podrobností o sadě výsledků Manipulace s ukazatelem sady výsledků Informace o struktuře tabulky Práce s binárními daty Vytváření a překrývání funkcí SQLite Vytváření agregačních funkcí

536 536 536 537 538 538 539 542 544 545 546 547 548

Shrnutí

549

Kapitola 23 Úvod do PDO Zase další databázová abstraktní vrstva? Jak se pracuje s PDO Instalace PDO Podpora databází v PDO Připojení k databázovému serveru a výběr databáze Získávání a nastavování atributů Zpracování chyb Vykonání dotazu Připravené příkazy Získávání dat Nastavování vázaných sloupců

551 552 553 554 554 555 557 557 558 560 564 567


18

Obsah Transakce Shrnutí

Kapitola 24 Úvod do MySQL

568 568

569

Proč je MySQL tak populární? Flexibilita Výkon Flexibilní licenční možnosti (Hyper) aktivní komunita uživatelů

569 570 570 572 573

MySQL 4 MySQL 5 Prominentní uživatelé MySQL craigslist Yahoo! Finance Wikipedia

574 575 575 575 576 576

Shrnutí

577

Kapitola 25 Instalace a konfigurace MySQL

579

Licence PHP a MySQL Linux Windows

579 580 580

Stažení MySQL Instalace MySQL Linux Windows

580 582 582 586

Nastavte heslo administrátora MySQL Start a zastavení MySQL Ruční ovládání démona Automatické startování a zastavování MySQL

589 589 589 591

Konfigurace a optimalizace MySQL mysqld_safe Konfigurační a optimalizační parametry Soubor my.cnf

594 594 595 599

Shrnutí

602

Kapitola 26 Klienti MySQL

603

Standardní volby klientů Volby týkající se připojení

603 604


Velká kniha PHP a MySQL 5

19

Všeobecné volby mysql Klíčové volby mysql Práce s mysql v interaktivním režimu Prohlížení konfiguračních proměnných a stavu systému Práce s mysql v dávkovém režimu Užitečné tipy k mysql

605 605 606 608 610 611 612

mysqladmin Příkazy mysqladmin

614 614

Další utility mysqldump mysqlshow mysqlhotcopy mysqlimport myisamchk mysqlcheck

615 615 616 616 617 618 619

Klientské programy jiných výrobců Administrátor MySQL phpMyAdmin Prohlížeč dotazů MySQL Navicat

619 619 621 622 624

Shrnutí

624

Kapitola 27 Ukládací enginy MySQL a datové typy

625

Ukládací enginy InnoDB MyISAM MEMORY MERGE BDB FEDERATED ARCHIVE CSV EXAMPLE BLACKHOLE Časté otázky týkající se ukládacích enginů

625 626 627 629 631 631 631 633 633 634 634 634

Datové typy a atributy Datové typy Datové typy pro datum a čas

636 636 636


20

Obsah Datové typy pro řetězce Atributy datových typů

640 642

Práce s databázemi a s tabulkami Práce s databázemi Práce s tabulkami Změny ve struktuře tabulky Databáze INFORMATION_SCHEMA

645 645 647 650 650

Shrnutí

653

Kapitola 28 Zabezpečení MySQL

655

Co byste měli udělat nejdřív Zabezpečení démona mysqld Systém přístupových oprávnění MySQL Jak systém přístupových oprávnění funguje Kde jsou informace o přístupových oprávněních uložené?

656 657 657 657 659

Správa uživatelů a přístupových oprávnění Prohlížení oprávnění

668 675

Limity na konzumaci prostředků uživateli Bezpečná připojení MySQL Volby příkazu GRANT, které se týkají bezpečných připojení Volby SSL

675 676 677 678

Shrnutí

680

Kapitola 29 Rozšíření mysql v PHP

681

Předběžné informace Jak se zpřístupní rozšíření mysql na Linuxu Jak se zpřístupní rozšíření mysql na Windows Přístupová oprávnění uživatelů Ukázková data

681 681 682 682 682

Příkazy MySQL v PHP Zřízení a uzavření připojení Uložení informací o připojení do separátního souboru Zabezpečení informací o připojení

683 683 685 685

Volba databáze Dotazy na MySQL Získávání a zobrazování dat Vkládání dat Modifikace dat

686 686 688 691 693


Velká kniha PHP a MySQL 5

21

Odstraňování dat Vybrané řádky a ovlivněné řádky Získávání informací o databázi a tabulce Získávání informací o sloupcích Prohlížení vlastností tabulky Získávání informací o chybách

695 696 697 698 702 703

Pomocné funkce Shrnutí

704 707

Kapitola 30 Rozšíření mysqli v PHP

709

Předběžné informace Jak se zpřístupní rozšíření mysqli na Unixu Jak se zpřístupní rozšíření mysqli na Windows Ukázková data

710 710 710 711

Jak se pracuje s rozšířením mysqli Připojení k serveru MySQL Zprávy o chybách připojení Výběr databáze MySQL Uzavření připojení

711 711 712 715 716

Dotazy Vykonání dotazu Zotavení paměti dotazu Příprava sady výsledků pro zpracování Analýza výsledků Vykonávání několika dotazů za sebou Připravené příkazy

716 716 718 718 720 723 724

Databázové transakce Shrnutí

731 732

Kapitola 31 Uložené rutiny

733

Měli bychom používat uložené rutiny? Přednosti uložených rutin Nevýhody uložených rutin

734 734 734

Jak MySQL implementuje uložené rutiny Tabulky přístupových oprávnění uložených rutin Jak se vytvoří uložená rutina Deklarace a nastavování proměnných Jak se vykoná uložená rutina

735 735 737 739 741


22

Obsah Uložené rutiny složené z několika příkazů Volání rutiny z jiné rutiny Modifikace uložené rutiny Odstranění uložené rutiny Prohlížení stavu rutiny Prohlížení syntaxe rutiny Podmínky a zpracovatelé

741 748 749 749 750 751 751

Integrace rutin do webových aplikací Vytvoření rozhraní pro bonus zaměstnanců Získávání více řádků

752 752 753

Shrnutí

753

Kapitola 32 Triggery MySQL

755

Úvod do triggerů Proč používat triggery? Vykonání akce před událostí Vykonání akce po události Triggery spouštěné „před“ versus triggery spouštěné „po“

755 756 756 757 758

Podpora triggerů v MySQL Jak se vytvoří trigger Prohlížení existujících triggerů Modifikace triggeru Odstranění triggeru Kaskádové triggery

758 759 761 762 762 763

Integrace triggerů do webových aplikací Shrnutí

764 766

Kapitola 33 Pohledy

767

Úvod do pohledů Podpora pohledů v MySQL Vytváření a vykonávání pohledů Prohlížení informací o pohledu Modifikace pohledu Odstranění pohledu Aktualizace pohledů

768 768 769 774 776 776 776

Začlenění pohledů do webových aplikací Shrnutí

777 778


Velká kniha PHP a MySQL 5

Kapitola 34 Databázové dotazy v praxi

23

779

Ukázková data Vytváření tabulárních výstup s PEAR Instalace HTML_Table Jak se vytvoří jednoduchá tabulka Vytváření lépe čitelného výstupu řádků Vytvoření tabulky z dat databáze Zobecnění výstupního procesu

780 780 781 781 782 784 785

Seřazení výstupu Vytvoření výstupu se stránkováním Číslování stránek výpisu Poddotazy Porovnávací operace s poddotazy Určování existence s poddotazy Údržba databáze pomocí poddotazů Používání poddotazů v PHP

787 788 791 793 794 794 796 796

Kurzory Základy práce s kurzory Vytvoření kurzoru Otevření kurzoru Práce s kurzorem Uzavření kurzoru Jak se kurzor používá s PHP

797 797 798 798 798 799 799

Shrnutí

800

Kapitola 35 Indexy a vyhledávání

801

Indexování databází Primární klíče Jedinečné indexy Normální indexy Fulltextové indexy Doporučené praktiky pro práci s indexy

801 802 803 804 806 810

Vyhledávání pomocí formuláře Jednoduché hledání Rozšíření vyhledávacích možností Fulltextové vyhledávání

811 811 812 814

Shrnutí

815


24

Obsah

Kapitola 36 Transakce

817

Co je transakce? Možnosti MySQL pro transakční zpracování Systémové požadavky Vytvoření tabulky Konfigurační parametry InnoDB

817 818 818 819 819

Ukázkový projekt Ukázková data Vykonáme konkrétní transakci Zálohování a obnova tabulek InnoDB Tipy pro práci s transakcemi

822 822 823 825 825

Budování transakčních aplikací s PHP Směna zboží za hotové ještě jednou

826 826

Shrnutí

830

Kapitola 37 Import a export dat

831

Ukázková tabulka Touha po inteligentním médiu Export dat Příkaz SELECT INTO OUTFILE

831 832 832 833

Import dat Import dat příkazem LOAD DATA INFILE Import dat s mysqlimport Načítání dat do tabulky s PHP

836 836 839 842

Shrnutí

843

Rejstřík

845


Kapitola 2

Instalace a konfigurace Apache a PHP V této kapitole se dozvíte, jak se nainstaluje a nakonfiguruje PHP, a v průběhu tohoto procesu se dozvíte, jak nainstalovat webový server Apache. Jestliže doposud nemáte k dispozici fungující server Apache/ PHP, je látka probíraná zde pro vás neocenitelná, abyste totiž mohli pracovat s příklady v pozdějších kapitolách, o vašich vlastních experimentech nemluvě. Konkrétně se v této kapitole dozvíte

• Jak se nainstaluje Apache a PHP jako modul serveru Apache, a to na dvou platformách, Unix i Windows.

• • • •

Jak otestujete svou instalaci, abyste se přesvědčili, že všechny komponenty pracují řádně. O běžných instalačních potížích a jak se řeší. Jaký mají účel, obor a výchozí hodnoty běžně používané konfigurační direktivy PHP. Různé způsoby, jimiž lze modifikovat konfigurační direktivy PHP.

Instalace V tomto oddílu projdeme všechny potřebné kroky k instalaci funkčního serveru Apache/PHP. Důsledkem bude, že budete moci na serveru spouštět skripty PHP a prohlížet jejich výsledky v prohlížeči.

Obstaráme si distribuce Než začnete s instalací, musíte stáhnout zdrojový kód. V tomto oddílu dostanete pokyny, jak to udělat.

Stažení Apache Popularita Apache a licence otevřeného zdrojového kódu podnítily prakticky všechny vývojáře Unixu, aby zabalili tento software do svých distribucí. Vzhledem ke svižnému rozvrhu nových vydání Apache se však musíte obrátit na webové stránky Apache a stáhnout nejnovější verzi. V době, kdy jsem psal tyto řádky, se na následující stránce nabízelo 260 zrcadel umístěných v 53 zemích světa: http://www.apache.org/mirrors


40

Kapitola 2 – Instalace a konfigurace PHP

Přejděte na tuto stránku a zvolte vhodné zrcadlo tím, že kliknete na patřičný odkaz. Výsledná stránka bude obsahovat všechny projekty kryté deštníkem Apache Software Foundation. Zvolte odkaz httpd. Tím přejdete na stránku obsahující odkazy na nejnovější vydání Apache a r ůzné k nim s e vztahující projekty a utility. Distribuce je dostupná ve dvou formátech:

• Zdrojový (source). Je-li vaší cílovou platformou Unix, doporučuji, abyste si stáhli zdrojový kód. Přestože jistě není nic špatného na tom, když využijete některou ze skvostně vybudovaných binárních verzí, čas navíc, který budete investovat, abyste se naučili kompilovat ze zdrojového kódu, vám v dlouhodobé perspektivě poskytne větší flexibilitu. Je-li vaší cílovou platformou systém Windows, a rádi byste kompilovali ze zdrojového kódu, lze stáhnout separátní zdrojové balení pro platformu Win32. Připomínám však, že se v kapitole neprobírá proces instalace pro platformu Win32 ze zdrojového kódu. Soustředíme se na mnohem běžnější (a doporučovaný) binární instalátor.

• Binární (binary). V době, kdy jsem psal tyto řádky, byly binární distribuce k dispozici pro 15

operačních systémů. Je-li vaší cílovou platformou systém Windows, doporučuje se, abyste si stáhli relevantní binární verzi. Na ostatních platformách zvažte kompilaci ze zdrojového kódu, protože v dlouhodobé perspektivě poskytne větší flexibilitu.

Poznámka V době, kdy jsem psal tyto řádky, nebyla ještě k dispozici binární verze Apache 2 s podporou SSL, přestože je možné, že v době, kdy tyto řádky čtete vy, je už situace jiná. Jestliže ale ne a vy požadujete na Windows podporu SSL, budete muset budovat ze zdrojového kódu.

Takže, kterou verzi Apache byste si měli stáhnout? Přestože byl Apache 2 vydán už před více než třemi lety, stále se všeobecně používá verze 1.X. Skutečně, zdá se, že většinu ISP sdílených serverů teprve čeká migrace k verzi 2.X. Neochota modernizovat nemá nic společného s problémy týkajícími se verze 2.X, spíše je to důkaz báječné stability a vyspělosti verze 1.X. Při standardním používání jsou vnější rozdíly mezi oběma verzemi prakticky nezjistitelné; proto uvažujte o práci s Apache 2 tehdy, potřebujete-li využívat jeho zdokonalenou stabilitu. Skutečně, hodláte-li provozovat Apache pod Windows, buď pro vývojové, nebo pro rozmisťovací účely, doporučuje se, abyste zvolili verzi 2, protože byla oproti předchozí distribuci Windows kompletně přepsána a je signifikantně stabilnější než její předchůdkyně.

Stažení PHP Přestože je v dnešní dob ě už PHP do v ětšiny distribucí Linuxu zabudovaný, doporučuje se, abyste si z webových stránek PHP stáhli nejnovější stabilní (stable) verzi. Abyste zkrátili dobu stahování, zvolte příhodné zrcadlo z více než sta zrcadel sídlících ve více než padesáti zemích. Seznam zrcadel najdete na adrese http://www.php.net/mirrors.php. Jakmile zvolíte nejbližší zrcadlo, přejděte na stránku, ze které se stahuje (downloads) a zvolte vhodný formát. Celkem jsou tři:

• Zdrojový (source). Je-li vaší cílovou platformou Unix, nebo hodláte kompilovat ze zdroje na

platformě Windows, zvolte zdrojový formát. Budování ze zdrojového kódu na Windows se nedoporučuje a v knize se tím nezabývám. Pokud se nenacházíte v situaci s opravdu velmi speci-


Velká kniha PHP a MySQL 5

41

álními okolnostmi, měla by vašim potřebám uspokojivě vyhovovat předem vybudovaná binární distribuce pro Windows. Tato distribuce je komprimovaná ve formátech bz2 a gz. Uvědomte si ale, že jejich obsah je identický; různé komprimační formáty jsou tu jen pro vaše pohodlí.

• Windows zip package. Distribuce obsahuje binární CGI a různé verze modulu serveru. Plánuje-

te-li využívat PHP v součinnosti s Apache, měli byste stáhnout tuto verzi, protože k ní se vztahují pozdější instalační pokyny uvedené v knize.

• Windows Installer. Distribuce obsahuje pouze CGI a nabízí pohodlné rozhraní instalačního

programu pro Windows, v němž nainstalujete a nakonfigurujete PHP. Obsahuje také podporu pro automatickou konfiguraci serverů IIS, PWS a Xitami. Přestože můžete tuto verzi používat v součinnosti s Apache, nedoporučuje se to. Použijte místo ní verzi Windows zip package.

Chcete-li si pohrát s nejnovějšími vývojovými fázemi PHP, můžete si na adrese http://snaps.php.net stáhnout zdrojovou i binární verzi. Mějte na paměti, že některé z verzí, které jsou dostupné přes tento web, nejsou určené pro rutinní provoz.

Proces instalace Protože se kapitola soustřeďuje především na PHP, ne na s erver Apache, vyčerpávající (ale i ú vodní) výklad všech možných schopností, které jsou během procesu budování Apache k dispozici, přesahuje rámec této kapitoly. Potřebujete-li dodatečné informace týkající se těchto schopností, doporučuji vám, abyste nějaký čas věnovali studiu dokumentace Apache, nebo si obstarejte publikaci Pro Apache, Third Edition, napsal Peter Wainwright, vydalo Apress 2004.

Poznámka Licenční konflikty mezi PHP a MySQL měly za následek, že byly knihovny MySQL z PHP 5 odstraněny. Proto, chcete-li používat PHP 5 a MySQL pospolu (což je dost pravděpodobné, když čtete tuto knihu), musíte podniknout patřičné kroky, abyste pro PHP 5 zpřístupnili knihovny MySQL. Tato látka se podrobněji probírá v kapitole 25. V ní si také určitě pročtěte informace, které se vztahují k různým licenčním scénářům, chcete-li používat PHP a MySQL dohromady

Instalace Apache a PHP na Linuxu/Unixu Na Unixu vybudujeme Apache a PHP ze zdrojového kódu. Potřebujete slušný kompilátor ANSI-C a systém, dva prvky, jejichž dostupnost je dnes p ro drtivou většinu distribucí samozřejmostí. PHP kromě toho vyžaduje balíky Flex (http://www.gnu.org/software/flex/flex.html) a Bison (http://www. gnu.org/software/bison/bison.html), Apache vyžaduje Perl alespoň verze 5.003. Opět všechny tři prvky jsou běžně rozšířené, když ne na vš ech, tak na většině moderních platformách Unix. Konečně potřebujete oprávnění úrovně root k cílovému serveru, abyste byli sto proces budování dokončit. Než zahájíte proces instalace, zvažte, zda byste neměli kvůli většímu pohodlí umístit oba balíky na společné místo, například /usr/src/. Pak začněte s instalací podle následujících pokynů. 1. Rozbalte Apache a PHP (operace gunzip a tar):


42

Kapitola 2 – Instalace a konfigurace PHP %>gunzip httpd-2_X_XX.tar.gz %>tar xvf httpd-2_X_XX.tar %>gunzip php-XX.tar.gz %>tar xvf php-XX.tar.

2. Zkonfigurujte a vybudujte Apache. Předat je třeba minimálně dvě volby. První z nich, --enable-so, sdděluje Apache, aby zapnul schopnost načítat sdílené moduly. Druhá, --with-mpm=worker, sděluje Apache, aby použil vícevláknový modul paralelního zpracování (threaded multiprocessing module), známý jako zpracovatelský proces (worker). Na základě svých konkrétních potřeb zvažte, zda byste neměli také používat modul prefork paralelního zpracování. Další informace týkající se této důležité záležitosti si vyhledejte v dokumentaci Apache. %>cd httpd-2_X_XX %>./configure --enable-so [další volby] %>make

3. Nainstalujte Apache: %>make install

4. Zkonfigurujte, vybudujte a nainstalujte PHP (informace ohledně modifikací výchozích instalačních hodnot a začlenění rozšíření cizích výrobců do PHP viz oddíly „Přizpůsobení vybudované instalace pro Unix“, resp. „Přizpůsobení vybudované instalace pro Windows, podle toho, pod jakým operačním systémem pracujete). %>cd ../php-X_XX %>./configure --with-apxs2=/usr/local/apache2/bin/apxs [další volby] %>make %>make install

Upozornění Verze PHP pro Unix se spoléhá na několik utilit, bez nichž se řádně nezkompiluje. Proces konfigurace se proto nezdaří, jestliže nejsou přítomné na serveru. Zmínit je třeba především to, že tato balení obsahují Bison parser generator, Flex lexical analysis generator, GCC compiler collection a m4 macro processor. Bohužel, četné distribuce je automaticky nenainstalují, takže je nezbytné ručně tyto balíky přidat v době, kdy se instaluje operační systém, nebo před instalací PHP. Proto, objeví-li se nějaké chyby týkající se zmíněných balíků, mějte na paměti, že je to zcela typické, a podnikněte nezbytné kroky, abyste je nainstalovali na váš systém.

5. Zkopírujte soubor php.ini-dist na jeho výchozí umístění a přejmenujte na php.ini. je hlavní konfigurační kanál. Účel a obsah php.ini podrobně prozkoumáme v příštím oddílu, „Konfigurace“. Soubor php.ini obsahuje stovky direktiv, jimiž se přizpůsobuje chování PHP. V pozdějším oddílu „Konfigurace“ prozkoumáme podrobně účel a obsah php.ini. Připomínám, že tento konfigurační soubor můžete umístit, kamkoli chcete, zvolíte-li však nějaké nestandardní umístění, budete muset také nakonfigurovat PHP pomocí volby --with-config-filepath. Dál připomínám, že máte k dispozici ještě jeden konfigurační soubor, který se jmenuje


Kapitola 3

Základy PHP Máme za sebou pouhé dvě kapitoly, a už jsme p robrali poměrně dost základních informací o jazyku PHP. Seznámili jste se s pozadím a historií vzniku jazyka a hluboko jste se zavrtali do pojmů a postupů souvisejících s instalací a konfigurací. Tím jste si vytvořili dobrou výchozí pozici k tomu, co je jádrem zbývající části knihy: vytváření vyspělých aplikací PHP. Jejich výklad teď začíná, uvádí se v něm mnoho základních schopností jazyka. Konkrétně se budou probírat následující témata:

• Jak se odděluje kód PHP, což umožňuje enginu pro analýzu určit, které oblasti skriptu má analyzovat, a které má ignorovat.

• Jak se do kódu vkládají komentáře pomocí různých metodologií, které jsou vypůjčené ze skriptování shellu Unixu a jazyků C a C++.

• Jak dostanete data na výstup pomocí příkazů echo(), print(), printf() a sprintf(). • Výklad typů dat PHP, proměnných, operátorů a příkazů. • Podrobné pojednání o klíčových řídících strukturách a příkazech PHP: if-else-elseif, while, foreach, include/require, break, continue a declare.

V kapitole si osvojíte nejen vědomosti nezbytné k tomu,k abyste mohli vytvářet sice jen zák ladní, ale přesto prospěšné aplikace PHP. Pochopíte také to, co vám umožní vytěžit co nejvíce z lá tky probírané v následujících kapitolách.

Únik k PHP Jednou z předností PHP je, že jeho k ód můžete vkládat přímo do statických stránek HTML. Aby ale kód mohl něco dělat, musí se stránka předat enginu PHP, který ji bude interpretovat. Při interpretaci kódu by ale bylo hodně neefektivní, kdyby se měl každý řádek brát jako potenciální příkaz PHP. Proto parser potřebuje nějaké prostředky, aby mohl okamžitě určit, které oblasti na stránce představují kód PHP. To se logicky docílí tím, že s e kód PHP oddělí. Existují čtyři varianty, jak lze k ód oddělit. Jejich popis následuje.


70

Kapitola 3 – Základy PHP

Výchozí syntax Výchozí syntax oddělení kódu začíná znaky <?php a končí znaky ?>, jako zde: <h3>Vítejte!</h3> <?php print "<p>Tohle je ukázka PHP.</p>"; ?> <p>Zde se nacházejí nějaké statické informace...</p>

Uložíte-li kód uvedený výše jako test.php a zavoláte ho z nějakého webového serveru, který má zapnutou podporu PHP, uvidíte výstup jako na obrázku 3-1:

Obrázek 3-1 Ukázka výstupu PHP

Krátké značky Pro lenochy je k dispozici ještě kratší syntax oddělovačů. Říká se jí krátký styl značek (short-tags). Obejde se bez odkazu php, který vyžaduje výchozí syntax. Chcete-li ale p oužívat krátké značky, musíte zapnout direktivu short_open_tag PHP. Příklad: <? print "Tohle je další ukázka PHP."; ?>

Upozornění Přestože jsou krátké značky pohodlné, mějte na paměti, že kolidují s XML, a tedy i se syntaxí XHTML. Proto se kvůli souladu doporučuje, abyste používali výchozí syntax..


Velká kniha PHP a MySQL 5

71

Informace se obvykle zobrazují příkazy print nebo echo. Když jsou zapnuté krátké značky, můžete se bez těchto příkazů obejít, a využít variantu výstupu známou jako zkrácená výstupní syntax: <?="Tohle je další ukázka PHP.";?>

Což je funkčně ekvivalentní oběma následujícím variantám: <? print "Tohle je další ukázka PHP."; ?> <? php print "Tohle je další ukázka PHP";?>

Styl <script> Z historických příčin měly některé editory, konkrétně editor FrontPage společnosti Microsoft, potíže s únikovou syntaxí, kterou se obracíme na PHP. Proto byla do PHP začleněna ještě jedna varianta oddělovací syntaxe, <script>: <script language="php"> print "Tohle je další ukázka PHP."; </script>

Tip Editor FrontPage společnosti Microsoft rozpoznává oddělovací syntax ve stylu ASP, která následuje.

Styl ASP Stránky ASP společnosti Microsoft používají obdobnou strategii. Také oddělují statickou syntax od dynamické pomocí předem definovaného vzorku znaků. Dynamická syntax se uvozuje znaky <% a ukončuje znaky %>. Přicházíte-li z krajiny ASP a rádi byste i nadále používali tuto syntax, PHP ji podporuje. Podívejte se na ukázku: <% print "Tohle je další ukázka PHP."; %>

Vkládání několika bloků kódu Na PHP se můžete obracet na dané stránce kolikrát, kolikrát jenom chcete. Například, následující ukázka je formálně zcela v pořádku: <html> <head> <title><?php echo "Vítejte na mém webu!";?></title> </head> <body> <?php $date = "18. září 2004"; ?>


72

Kapitola 3 – Základy PHP

<h3>Dnes je </body> </html>

<?=$date;?></h3>

Připomínám, že jakékoli proměnné, které se deklarují před blokem kódu, se „zapamatují“ pro potřeby následných bloků, což je v našem příkladu případ proměnné $date.

Komentáře Zdůraznit, jak je důležité prokládat kód pečlivými komentáři, není nikdy zbytečné. PHP pro komentáře nabízí několik syntaktických variant, jejichž popis následuje.

Syntax jediného řádku z C++ Pro komentář často stačí jediný řádek. Protože je komentář krátký, není třeba ho ukončovat speciálním ukončovacím oddělovačem, protože tuto roli uspokojivě zvládne znak pro nový řádek (\n). PHP podporuje jednořádkové komentáře ve stylu C++, které jsou uvozené dvěma lomítky (//), jako zde: <?php // Titulek: Můj program PHP // Autor: Jason print "Tohle je program PHP"; ?>

Syntax shellu PHP také podporuje alternativu k syntaxi ve stylu C++, které se říká syntax shellu. Komentář je uvozen znakem hash (#). Předchozí ukázka pak vypadá takto: <?php # Titulek: Můj program PHP # Autor: Jason print "Tohle je program PHP"; ?>

Komentář na několika řádcích ve stylu C Často je žádoucí vložit obšírnější popis, jak daná část kódu funguje, nebo jiné poznámky ke kódu. Takové vysvětlení se obvykle na jediný řádek nevejde. Přestože byste mohli postupovat tak, že byste každý řádek zahájili oddělovači ve stylu C++ nebo shellu, nabízí PHP pohodlnější variantu s uvozovacím a ukončovacím oddělovačem komentáře. Podívejte se na několikařádkový komentář: <?php /* Titulek: Můj program PHP Autor: Jason


Velká kniha PHP a MySQL 5

73

Datum: 10. října 2005 */ ?>

Syntax komentáře na několika řádcích se hodí zejména tehdy, když z kódu generujete dokumentaci, protože nabízí možnost, jak odlišit skutečné komentáře od okomentovaného kódu, což není tak snadné, jako když se používá jednořádková syntax komentářů.

Výstup Většina webových aplikací je značně interaktivních. Dobře napsané skripty trvale komunikují s uživateli, a to přes nástroje rozhraní, i prostřednictvím odpovědí na požadavky. PHP nabízí pro zobrazování informací řadu prostředků, jejichž popis následuje.

print() boolean print(argument print(argument) )

Účelem příkazu print je poskytnout uživateli zpětnou vazbu. Umí zobrazit prosté řetězce i obsah proměnných. Všechny následující příkazy jsou akceptovatelné příkazy print: <?php print("<p>Zbožňuji léto.</p>"); ?> <?php $obdobi = "léto"; print "<p> Zbožňuji $obdobi.</p>"; ?> <?php print "<p> Zbožňuji léto.</p>"; ?> <?php $obdobi = "léto"; print "<p> Zbožňuji ".$obdobi.".</p>"; ?>

Všechny příkazy vypíší: Zbožňuji léto.

Zatímco tři první varianty jsou patrně velmi snadno pochopitelné, poslední z nich tak zřejmá být nemusí. V poslední variantě jsem totiž zřetězil tři řetězce do jediného pomocí tečky, která slouží v tomto kontextu jako operátor řetězení. Je to technika, která se běžně používá při řetězení proměnných, konstant a statických řetězců. S uvedenou strategií se budete průběžně setkávat na různých místech knihy.


74

Kapitola 3 – Základy PHP

Poznámka Přestože nás oficiální syntax vybízí, abychom argument dávali do závorek, máte možnost je vynechat. Mnozí programátoři je neuvádějí prostě proto, že je cílový argument zřejmý i bez nich. .

echo() void echo(string argument1 [, ...string argumentN])

Příkaz echo funguje obdobně jako print, ale se dvěma odlišnostmi. Zaprvé nemůže být částí složitějšího výrazu, protože vrací void, zatímco print vrací hodnotu typu boolean. Zadruhé echo umí vypsat několik řetězců. Prospěšnost té druhé vymoženosti je problematická, vypadá to, že je to více než cokoli jiného, jen otázka osobních preferencí. Nicméně je k dispozici, pokud pocítíte neodolatelnou potřebu ji použít. Tady máte ukázku: <?php $heavyweight = "Lennox Lewis"; $lightweight = "Floyd Mayweather"; echo $heavyweight, " a ", $lightweight, " jsou skvělí bojovníci."; ?>

Kód vyprodukuje následující výstup: Lennox Lewis a Floyd Mayweather jsou skvělí bojovníci.

Tip Co je rychlejší, echo() nebo print()? To, že jsou funkčně zaměnitelné, způsobuje, že si mnozí kladou tuto otázku. Odpověď zní, že funkce echo() je nepatrně rychlejší, protože nic nevrací, kdežto print() vrací booleovskou hodnotu, kterou informuje volajícího, zda příkaz zvládl výstup úspěšně, nebo ne. Je zcela nepravděpodobné, že byste si všimli nějakého rozdílu v rychlosti, takže se můžete rozhodnout podle toho, co vám více vyhovuje stylisticky.

printf() boolean printf (string format [, mixed args args]) ])

Funkce printf() je funkčně identická s print(). Jde o výstup argumentů specifikovaných v args, ale výstup se naformátuje podle format. To umožňuje získat značnou kontrolu nad výstupem dat, pokud jde o takové věci, jako jsou zarovnání, přesnost, typ či pozice. Argument se může skládat až z pěti komponent, které se musejí ve format objevit ve stanoveném pořadí:

• Specifikátor doplnění: volitelná komponenta, která určuje, jakým znakem se výstup doplní na

správnou délku řetězce. Výchozí znak je mezera. Alternativní znak se specifikuje tak, že se před něj napíše apostrof.

• Specifikátor zarovnání: volitelná komponenta, která určuje, zda má být výstup zarovnaný

doleva nebo doprava. Výchozí je doprava. Zarovnání vlevo vynutíte tím, že uvedete znaménko minus.


Velká kniha PHP a MySQL 5

75

• Specifikátor délky: volitelná komponenta, která určuje minimální počet znaků, který má výstup z funkce obsahovat.

• Specifikátor přesnosti: volitelná komponenta, která určuje, kolik se má zobrazit desetinných míst. Má vliv pouze na data typu float.

• Specifikátor typu: určuje, jak se argument přetypuje. Podporované specifikátory typu jsou uvedené v tabulce 3-1.

Tabulka 3-1. Podporované specifikátory typu. Typ

Popis

%b

Argument se považuje za celé číslo, zobrazí se jako binární číslo.

%c

Argument se považuje za celé číslo, zobrazí se znak odpovídající dané hodnotě ASCII.

%d

Argument se považuje za celé číslo, zobrazí se jako dekadické číslo se znaménkem.

%f

Argument se považuje za číslo v pohyblivé řádové čárce a tak se také zobrazí.

%o

Argument se považuje za celé číslo, zobrazí se jako oktalové číslo.

%s

Argument se považuje za řetězec, zobrazí se jako řetězec.

%u

Argument se považuje za celé číslo, zobrazí se jako dekadické číslo bez znaménka.

%x

Argument se považuje za celé číslo, zobrazí se jako hexadecimální číslo s malými písmeny.

%X

Argument se považuje za celé číslo, zobrazí se jako hexadecimální číslo s velkými písmeny

Podívejte se na několik ukázek: printf("$%01.2f", 43.2); // $43.20 printf("%s je %d lahví piva", "Ve sklepě", 100); // Ve sklepě je 100 lahví piva printf("%15s", "Nějaký text"); // Nějaký text

Někdy se hodí změnit výstupní pořadí argumentů, nebo zopakovat výstup některého konkrétního argumentu, aniž byste ho museli opakovaně uvádět v seznamu argumentů. To se dělá tak, že se odkážete na argument, a zároveň na jeho pozici. Například, %2$ vyjadřuje argument umístěný v seznamu argumentů na druhé pozici, zatímco %3$ vyjadřuje třetí. Když to však umístíte do řetězce format, musíte před znak dolar uvést obrácené lomítko, například %2\$. Dvě ukázky: printf("Náš %2\$s rád %1\$s", "štěká", "pes"); // Náš pes rád štěká printf("Náš %1\$s říká: %2\$s, %2\$s.", "pes", "haf"); // Náš pes říká: haf, haf.

sprintf() string sprintf (string format [, mixed arguments arguments]) ])

Funkce sprintf() se funkčně shoduje s printf() až na to, že se výstup přiřadí do řetězce, nejde přímo na standardní výstup. Ukázka: $cena = sprintf("$%01.2f", 43.2); // $cena = $43.20


76

Kapitola 3 – Základy PHP

Typy dat Datový typ je obecný název přiřazený nějaké množině dat, která sdílí nějakou společnou množinu charakteristik. Mezi běžné datové typy patří řetězce, celá čísla, čísla v pohyblivé řádové čárce a booleovské hodnoty. PHP už dlo uho nabízí bohatou sadu datových typů. K nim p řibyly ve verzi 5 další. V tomto oddílu projdu jednotlivé datové typy, které lze všechny rozdělit do tří kategorií: skalární, složené a speciální.

Skalární datové typy Skalární datové typy mohou obsahovat jen jediný prvek informace. Sem spadá několik datových typů: boolean, integer, float a string.

Boolean Datový typ boolean se jmenuje po matematikovi George Booleovi (1815–1864), který je pokládám za jednoho ze zakladatelů teorie informace. Booleovská proměnná reprezentuje pravdivost, a podporuje tedy pouze dvě hodnoty: TRUE (pravda) nebo FALSE (nepravda); na velikosti písmen nezáleží. Alternativou je reprezentovat FALSE hodnotu nula, a TRUE reprezentovat jakoukoli nenulovou hodnotou. $jenazivu $jenazivu $jenazivu $jenazivu $jenazivu

= = = = =

false; 1; -1; 5; 0;

# # # # #

$jenazivu $jenazivu $jenazivu $jenazivu $jenazivu

je je je je je

false. true. true. true. false.

Integer Typ integer vyjadřuje prostě celé číslo, neboli takové číslo, které nemá desetinnou část. Sem spadají čísla dekadická (o základu 10), oktalová (o základu 8) a hexadecimální (o základu 16). Několik ukázek: 42 -678900 0755 0xC4E

# # # #

dekadické dekadické oktalové hexadecimální

Jaké je největší podporované celé číslo, závisí na platformě, i když obvykle je to plus nebo minus 231. Pokusíte-li se tento limit v nějakém skriptu PHP překročit, převede se takové číslo automaticky do pohyblivé řádové čárky (na float). Ukázka: <?php $val = 45678945939390393678976; echo $val + 5; ?>

Výsledek bude: 4.567894593939E+022


Kapitola 7

Pokročilé schopnosti OOP V kapitole 6 jste absolvovali základy objektově orientovaného programování v PHP. V této kapitole budeme na těchto základech stavět. Seznámíte se s několika vyspělejšími schopnostmi OOP, které byste si měli zařadit do svého repertoáru hned poté, co budete mít v malíku základy. Konkrétně se v kapitole hovoří o pěti schopnostech:

• Klonování objektů. Jedním z hlavních zdokonalení modelu OOP v PHP verze 5 je to, že se

všechny objekty považují za odkazy, ne za hodnoty. Jak se pak ovšem vypořádáme s úlohou vytvořit kopii objektu, když se všechny objekty považují za odkazy? Klonováním objektu, což je nová schopnost v PHP 5.

• Dědění. Jak už bylo zmíněno v kapitole 6, je schopnost budovat hierarchie tříd prostřednictvím dědění klíčovým pojmem OOP. Dozvíte se, co je to dědění, jakou má v PHP 5 syntax, a uvidíte několik příkladů, které předvádějí tuto klíčovou schopnost OOP.

• Rozhraní. Rozhraní je nějaká kolekce neimplementovaných definic metod a konstant. Slouží

jako jistý náčrt třídy. Rozhraní přesně definují, co se může ve třídě dělat, ale nezatěžují se konkrétními podrobnostmi implementace. V této kapitole se dozvíte, jakou podporu poskytuje PHP 5 pro rozhraní, a uvidíte také několik příkladů, které předvádějí tuto klíčovou schopnost OOP.

• Abstraktní třídy. Abstraktní třída je v podstatě taková třída, ze které se nedají vytvářet instance.

Účelem abstraktních tříd je to, aby se z nich odvozovaly třídy, jejichž instance se už dají vytvářet (říká se jim někdy konkrétní třídy). Abstraktní třídy lze implementovat plně, nebo implementovat jen částečně, nebo neimplementovat vůbec. V této kapitole se uvádějí všeobecné pojmy, které se točí okolo abstraktních tříd spolu s úvodem, jak se abstraktní třídy implementují v PHP 5.

• Reflexe. Jak jste se dozvěděli v kapitole 6, skrývání „odpudivých“ podrobností aplikace přívěti-

vými rozhraními (zapouzdření) je jedním z hlavních pilířů OOP. Nicméně programátoři ovšem potřebují nějaké pohodlné prostředky, jimiž se dá prozkoumávat chování třídy. Tuto schopnost poskytuje pojem reflexe, který se zde vysvětluje.


178

Kapitola 7 – Pokročilé vlastnosti OOP

Schopnosti OOP nepodporované v PHP Máte-li zkušenosti s jinými objektově orientovanými jazyky, možná p o přečtení výše uvedeného seznamu nespokojeně potřásáte hlavou, a p táte se, proč v něm c hybí jedna neb o několik konkrétních schopností OOP, které důvěrně znáte z jiných jazyků. Je docela dobře možné, že je to kvůli tomu, že PHP tuto schopnost nepodporuje. Takže abyste si hlavu úplně nevyviklali z pantů, jsou v následujícím výčtu uvedena ta vyspělá témata OOP, která PHP nepodporuje, a proto jejich výklad v kapitole nenajdete.

• Jmenné prostory (namespace). Přestože byly původně do PHP 5 naplánované, od začlenění

jmenných prostorů bylo brzo upuštěno. Není jasné, zda bude podpora jmenných prostorů integrována do nějaké budoucí verze.

• Přetěžování metod (overloading). Možnost docílit polymorfického účinku prostřednictvím přetěžování funkcí PHP nepodporuje a podle diskuse na webových stránkách Zend Technologies, patrně ani nikdy podporovat nebude. Více se o tom můžete dozvědět na adrese http://www. zend.com/php/ask_experts.php.

• Přetěžování operátorů. Možnost přiřadit dodatečné významy stávajícím operátorům na základě typu dat, která se pokoušíte modifikovat, zatím není na pořadu dne. Podle výše zmíněné diskuse na webu Zend Technologies, není pravděpodobné, že by se tato schopnost někdy v budoucnu implementovala.

• Vícenásobné dědění. PHP nepodporuje vícenásobné dědění. Implementace více rozhraní se však podporuje.

Jen čas ukáže, budou-li se v budoucnu některé z těchto schopností v PHP podporovat.

Klonování objektů Jednou z nejv ětších stinných stránek objektově orientovaných schopností PHP 4 b yla skutečnost, že zacházel s objekty jako s jinými datovými typy. Tato praxe byla překážkou využití mnohých běžných metodologií OOP, jako jsou návrhové vzory. Takové metodologie závisejí na možnosti předávat objekty do jiných metod třídy odkazem, ne hodnotou, což byla výchozí praktika v PHP. Naštěstí byla tato záležitost v PHP 5 vyřešena, a nyní se standardně se všemi objekty zachází jako s odkazy. Protože se ale nyní se všemi objekty zachází jako s odkazy, ne jako s hodnotami, je zase obtížnější udělat kopii objektu. Pokusíte-li se zkopírovat odkazovaný objekt, bude prostě ukazovat zpět na adresované umístění původního objektu. PHP se s tím vypořádal tak, že nabízí explicitní prostředek pro klonování objektu.

Příklad klonování Klon objektu vytvoříte tak, že před ním uvedete klíčové slovo clone, jako zde: cílový_objekt = clone zdrojový_objekt zdrojový_objekt; ;

Vyčerpávající příklad klonování objektu nabízí výpis 7-1. V p říkladu jsem vytvořil ukázkovou třídu s názvem parazitFirmy, která obsahuje dva členy (idZamestnance a barvaKravaty), a jejich odpovídající gettery a settery. V příkladu se vytvoří instance parazitFirmy a použije se jako základna pro předvedení, jaké účinky má operace klonování.


Velká kniha PHP a MySQL 5 Výpis 7-1. Klonování objektu pomocí klíčového slova clone <?php class parazitFirmy { private $idZamestnance ; private $barvaKravaty; // Definuje setter a getter pro $idZamestnance function nastavitIdZamestnance ($idZamestnance ) { $this->idZamestnance = $idZamestnance ; } function ziskatIdZamestnance() { return $this->idZamestnance ; } // Definuje setter a getter pro $barvaKravaty function nastavitBarvuKravaty ($barvaKravaty) { $this->barvaKravaty = $barvaKravaty; } function ziskatBarvuKravaty() { return $this->barvaKravaty; } } // Vytvoří nový objekt parazita firmy $parazit1 = new parazitFirmy(); // Nastaví člen idZamestnance parazita 1 $parazit1->nastavitIdZamestnance ("12345"); // Nastaví člen barvaKravaty parazita 1 $parazit1->nastavitBarvuKravaty ("červená"); // Vytvoří klon parazita 1 $parazit2 = clone $parazit1; // Nastaví člen idZamestnance parazita 2 $parazit2->nastavitIdZamestnance ("67890"); // Výstup členů prvního a druhého parazita echo "parazit1 id zaměstnance: ".$parazit1->ziskatIdZamestnance ()."<br />"; echo "parazit1 barva kravaty: ".$parazit1->ziskatBarvuKravaty()."<br />"; echo "parazit2 id zaměstnance: ".$parazit2->ziskatIdZamestnance ()."<br />"; echo "parazit2 barva kravaty: ".$parazit2->ziskatBarvuKravaty()."<br />"; ?>

179


180

Kapitola 7 – Pokročilé vlastnosti OOP

Když kód spustíte, vrátí: parazit1 id zaměstnance: 12345 parazit1 barva kravaty: červená parazit2 id zaměstnance: 67890 parazit2 barva kravaty: červená

Jak vidíte, $parazit2 se stal objektem typu parazitFirmy a zdědil hodnoty členů z $parazit1. Aby se zdůraznilo, že je $parazit2 opravdu typu parazitFirmy, nastavil se znovu i jeho člen idZamestnance.

Metoda _ _clone() Při klonování objektu si dokonce můžete přizpůsobit chování tohoto procesu, když si ve třídě objektu definujete metodu _ _clone(). Kromě toho, že se do cílového objektu zkopírují všechny existující členy objektu, vykoná se také vše, co je umíst ěné v této metodě. Upravte třídu parazitFirmy tak, že do ní přidáte metodu: function _ _clone() { $this->barvaKravaty = "modrá"; }

Až s tím budete hotovi, vytvořte nový objekt parazitFirmy, přidejte hodnotu členu idZamestnance, udělejte klon objektu, a nakonec vypište potřebná data, abyste si ověřili, že se barvaKravaty klonovaného objektu skutečně nastavila prostřednictvím metody _ _clone(). Příklad vidíte ve výpisu 7-2. Výpis 7-2. Rozšíření možností klíčového slova clone metodou _ _clone() // Vytvoří objekt nového parazita firmy $parazit1 = new parazitFirmy(); // Nastaví člen idZamestnance parazita 1 $parazit1->nastavitIdZamestnance ("12345"); // Vytvoří klon objektu $parazit1 $parazit2 = clone $parazit1; // Nastaví člen idZamestnance parazita 2 $parazit2->nastavitIdZamestnance ("67890"); // Výstup členů obou parazitů echo "parazit1 id zaměstnance: ".$parazit1->ziskatIdZamestnance ()."<br />"; echo "parazit2 id zaměstnance: ".$parazit2->ziskatIdZamestnance ()."<br />"; echo "parazit2 barva kravaty: ".$parazit2->ziskatBarvuKravaty()."<br />";

Když kód vykonáte, vypíše: parazit1 id zaměstnance: 12345 parazit2 id zaměstnance: 67890 parazit2 barva kravaty: modrá


Velká kniha PHP a MySQL 5

181

Dědění Lidé mají docela dobrou výbavu pro uvažování v takových termínech, jakým je třeba uspořádaná hierarchie, proto není nijak překvapující, že je takové nahlížení na správu mnoha aspektů našeho každodenního života široce rozšířené. Struktury managementu firmy, daňový systém Spojených Států, i náš pohled na říše rostlin a živočichů, to je jen několik příkladů systémů, které se převážně spoléhají na hierarchie. Protože je objektově orientované programování založeno na premise, že my lidé dokážeme velmi dobře modelovat vlastnosti a c hování prostředí skutečného světa, které se snažíme implementovat pomocí kódu, dá se z toho rozumně usoudit, že jsme také schopni znázorňovat tyto hierarchické vztahy. Předpokládejme například, že vaše aplikace potřebuje třídu nazvanou Zamestnanec, jejíž účelem má být reprezentace charakteristik a chování, jaká člověk může očekávat od nějakého zaměstnance. Mezi členy takové třídy by mohly patřit

• • • •

jmeno: jméno zaměstnance vek: věk zaměstnance plat: plat zaměstnance zamestnan_let: počet let, které daný zaměstnanec u firmy pracuje.

Mezi metody třídy Zamestnanec by mohly patřit:

• • •

vykonatPraci: vykoná nějakou práci související se zadaným úkolem. snistObed: vezme si přestávku na oběd. vzitDovolenou: týká se nejcennějších týdnů v roce.

Tyto charakteristiky a chování budou relevantní pro všechny druhy zaměstnanců, bez ohledu na účel nebo pozici zaměstnance v organizaci. Je zřejmé, že budou mezi zaměstnanci také jisté rozdíly; například, pracovník exekutivy může mít v držení jist é akcie firmy, a bude sto společnost tunelovat, zatímco jiní zaměstnanci takové výdobytky nemají. Sekretářka musí umět napsat dopis a vedoucí prodejny musí umět udělat inventuru. Navzdory těmto rozdílům by ale bylo velmi neefektivní, kdybyste museli vytvářet a udržovat redundantní struktury tříd pro ty atributy, které sdílejí všichni zaměstnanci. Vývoj schematu OOP to bere v úvahu. Umožňuje dědit z existujících tříd a dále na nich budovat.

Dědění třídy V PHP se dědění třídy dociluje klíčovým slovem extends .Předvádí je výpis 7-3, kde se nejprve definuje třída Zamestnanec, pak se vytvoří třída Vedouci, která bude dědit ze třídy Zamestnanec.

Poznámka Třídě, která dědí z jiné třídy, se říká dceřiná (child) třída, podtřída nebo odvozená třída. Dceřiná třída dědí ze své rodičovské (parent), neboli základní (base) třídy.


182

Kapitola 7 – Pokročilé vlastnosti OOP

Výpis 7-3. Dědění ze základní třídy <?php # Definuje třídu Zamestnanec class Zamestnanec { private $jmeno; # Definuje funkci set vlastnosti pro soukromý člen $jmeno. function nastavitJmeno($jmeno) { if ($jmeno == "") echo "Jméno nesmí zůstat prázdné!"; else $this->jmeno = $jmeno; } # Definuje funkci get vlastnosti pro soukromý člen $jmeno function ziskatJmeno() { return "Jmenuji se ".$this->jmeno."<br />"; } } #konec třídy Zamestnanec # Definuje třídu Vedouci, která bude dědit z třídy Zamestnanec class Vedouci extends Zamestnanec { # Definuje metodu jedinečnou pro Zamestnanec function tunelovatFirmu() { echo "Prodám aktiva firmy, abych mohl financovat svou jachtu!"; } } #konec třídy Vedouci # vytvoří nový objekt Vedouci $exec = new Vedouci(); # zavolá metodu nastavitJmeno(), která je definovaná ve třídě Zamestnanec $exec->nastavitJmeno("Richard"); # Zavolá metodu ziskatJmeno() echo $exec->ziskatJmeno(); # zavolá metodu tunelovatFirmu() $exec->tunelovatFirmu(); ?>

Kód vrátí Jmenuji se Richard. Prodám aktiva firmy, abych mohl financovat svou jachtu!


Kapitola 23

Úvod do PDO Počet dostupných softwarových řešení je zároveň požehnáním i prokletím. I když je jejich nadbytečná hojnost skvělá pro konečné uživatele, protože si mohou vyhledat takový produkt, který nejlépe vyhovuje jejich konkrétním potřebám, už dlouho je prokázané, že je to noční můra pro vývojáře a systémové administrátory, protože se od nich požaduje, aby dva nebo více odlišných produktů transparentně vzájemně komunikovaly. I když to, že se ctí různé standardy, jako je třeba XML, značně přispívá v úsilí o interoperabilitu, jsme stále roky vzdáleni od nějakého obecně akceptovatelného řešení. Tento problém se projeví zvlášť velmi zřetelně tehdy, když aplikace požadují jako datovou základnu nějakou databázi. Zatímco všechny hlavní databáze ctí standard SQL, přestože s různými odchylkami, rozhraní, na nichž jsou závislí programátoři, chtějí-li s databází komunikovat, mohou být značně odlišná (dokonce i tehdy, když jsou dotazy z valné části stejné). Proto bývají aplikace téměř vždy svázané s nějakou konkrétní databází, čímž nutí uživatele, aby si také nainstalovali a udržovali tu hlavní databázi, pokud ji ještě nevlastní. Nebo musejí zvolit alternativní, nějaké patrně méně vyspělé řešení, které bude kompatibilní s jejich stávajícím prostředím. Předpokládejme například, že vaše organizace požaduje aplikaci, která se bude provozovat výlučně na Oracle, ale vaše organizace je přitom standardizovaná na nějakou databázi open-source. Odhodláte se investovat značné prostředky, které bude nutno vložit do nákupu nezbytných licencí Oracle, jste ochotni udržovat tuto databázi jen kvůli tomu, aby se mohla provozovat jedna jediná konkrétní aplikace? Aby se programátoři velkých korporací nějak s t ěmito dilematy vypořádali, začali vyvíjet abstraktní databázové vrstvy, které mají sloužit k tomu, aby se mohla oddělit logika aplikace od logiky komunikace s databází. Když se všechny příkazy související s databází mohou prohnat nějakým ze všeobecněným rozhraním, může pak aplikace používat jedno z několika databázových řešení, za předpokladů, že daná databáze podporuje schopnosti, které aplikace požaduje, a že abstraktní vrstva nabízí ovladač kompatibilní s danou databází. Graficky je popisovaný proces znázorněn na obrázku 23-1. Patrně už něco víte o některých rozšířenějších implementacích, z nichž několik je uvedeno v následujícím výčtu:

• DB: DB je databázová abstraktní vrstva napsaná v PHP a k dispozici jako balík PEAR. (Další

informace o PEAR viz kapitola 11.) V současné době podporuje FrontBase, InterBase, Informix, Mini SQL, MySQL, Oracle, ODBC, PostgreSQL, SQLite a Sybase.


552

Kapitola 23 – Úvod do PDO

Obrázek 23-1 Oddělení aplikačních a datových vrstev pomocí abstraktní databázové vrstvy

• JDBC: jak název implikuje, umožňuje standard Java Database Connectivity (JDBC) programá-

torům Javy komunikovat s jakoukoli databází, pro kterou je k dispozici ovladač JDBC. Patří sem mj. MSSQL, MySQL, Oracle a PostgreSQL.

• ODBC: rozhraní Open Database Connectivity (ODBC) je v současnosti jedna z nejrozšířeněj-

ších abstraktních implementací, podporuje ji široká škála aplikací a jazyků, včetně PHP. ovladače ODBC nabízejí všechny hlavní databáze, mezi nimi také ty, které jsou uvedené v odrážce JDBC výše.

• Perl DBI: modul Perl Database Interface je standardizovaný prostředek Perlu pro komunikaci s databází, a sloužil jako inspirace při tvorbě balíku DB PHP.

Jak vidíte, mají uživatelé PHP p o ruce řešení DB i ODBC, proto se může zdát, že js ou vaše potřeby vyřešené, co se týče databázové abstrakce, vyvíjíte-li aplikace poháněné PHP, není-liž pravda? I když jsou tato (a mnohá jiná) řešení hotová a po ruce, už nějakou dobu se vyvíjí ještě lepší řešení, které bylo oficiálně vydané s PHP 5.1. Je známé jako abstraktní vrstva PDO (PHP Data Objects).

Zase další databázová abstraktní vrstva? Jak PDO v posledních dvou letech dozrával, dost okolo toho hudrali vývojáři, kteří buď byli zainteresováni ve vývoji nějakých jiných databázových abstraktních vrstev, nebo patrně byli příliš soustředěni na schopnosti databázové abstraktní vrstvy PDO, než na celou paletu vybavení, které nabízí. Skutečně, PDO poslouží jako ideální náhrada balíku DB a obdobných řešení. PDO je však ve skutečnosti mnohem dál, není to jen pouhá další databázová abstraktní vrstva:

• Konsistentní kódování: protože různá databázová rozšíření, která jsou k dispozici pro PHP, psali různí hostující přispěvovatelé, neexistuje jednotnost v kódování, navzdory faktu, že všechna tato rozšíření nabízejí v zásadě stejné schopnosti. PDO tuto nejednotnost odstraňuje, protože nabízí jediné rozhraní, které se používá vždy, bez ohledu na to, o jakou databázi se jedná. Navíc


Velká kniha PHP a MySQL 5

553

rozšíření je rozděleno do dvou zřetelně vymezených komponent: jádro PDO obsahuje většinu kódu specifického pro PHP, takže se jednotlivé ovladače mohou soustředit výhradně na data. Dále, vývojáři PDO využili svých vědomostí a zkušeností při budování různých databázových rozšíření v posledních letech, takže mohli těžit z toho, co se osvědčilo, to zařadili, a zároveň se pečlivě vystříhali toho, aby zařazovali něco, co se neosvědčilo.

• Flexibilita: protože PDO načítá potřebný databázový ovladač až při běhu, není třeba překonfigurovat a překompilovat PHP pokaždé, když se používá jiná databáze. Například potřebujete-li náhle přejít z Oracle na PostgreSQL, prostě načtěte ovladač PDO_PGSQL a pracujte (jak se to udělá, o tom více později).

• Objektově orientované schopnosti: PDO využívá objektově orientovaných schopností PHP, což vede na vyspělejší a efektivnější databázovou komunikaci.

• Výkon: PDO je napsaný v C a vkompilovaný do PHP, což samo o sobě, budou-li všechny ostatní faktory rovnocenné, poskytuje značný nárůst výkonu oproti řešením napsaným v PHP.

Vzhledem k t ěmto přednostem, proč to nezkusit? V této kapitole se dostatečně obeznámíte s PD O a s myriádami schopností, které nabízí.

Jak se pracuje s PDO PDO se až p ozoruhodně podobá všem databázovým rozšířením, která už dlo uhou dobu podporuje PHP; proto, jestliže jste už používali PHP v součinnosti s nějakou databází, bude vám látka prezentovaná v tomto oddílu připadat důvěrně známá. Jak už bylo zmíněno, PDO byl vybudován tak, že jeho tvůrci měli stále na mysli ty nejlepší schopnosti předchozích databázových rozšíření, takže není divu, že v jeho metodách najdete značné podobnosti s tím, co už zn áte. Oddíl zahájíme stručným přehledem procesu instalace PDO, pak následuje přehled databázových serverů, které se podporují v současné době. V příkladech kapitoly budeme používat následující tabulku MySQL: CREATE TABLE product ( rowid SMALLINT NOT NULL AUTO_INCREMENT, sku CHAR(8) NOT NULL, name VARCHAR(35) NOT NULL, PRIMARY KEY(rowid) );

Poznámka překladatele SKU je zkratka Stock Keeping Unit, v online obchodování jednoznačný identifikátor výrobku na skladě nebo v katalogu

Tabulku naplňte dále uvedenými výrobky: rowID 1

SKU ZP457321

Name Painless Aftershave

2 3 4

TY232278 PO988932 KL334899

AquaSmooth Toothpaste HeadsFree Shampoo WhiskerWrecker Razors


554

Kapitola 23 – Úvod do PDO

Instalace PDO Jak už bylo zmíněno, je PDO standardně zabalený do PHP 5.1 a no vějších verzí, takže provozujete-li tuto verzi, nemusíte podnikat vůbec žádné další kroky. Pracujete-li s nějakou verzí starší než 5.1, i t ak můžete pracovat s PDO, když si ho stáhnete z PECL; protože však PDO využívá plně nových objektově orientovaných schopností PHP 5, není možné ho používat v součinnosti s verzí, která je starší než 5.0. Ale ať je to tak či onak, když konfigurujete PHP, musíte přesto explicitně specifikovat ovladače, které chcete zařadit (výjimkou je ovladač SQLITE, který je zařazený standardně). Například chcete-li zapnout podporu ovladače MySQL PDO,přidejte do příkazu configure následující přepínač: --with-pdo-mysql=/cesta/k/instalaci/mysql

Potřebujete-li se dozvědět víc o jednotlivých ovladačích PDO, vydejte příkaz configure --help. Pracujete-li s PHP 5.1 nebo novější verzí na platformě Windows, tak v době, kdy jsem psal tyto řádky, nebyly ovladače začleněné do distr ibuce. Proto přejděte na http://snaps.php.net/win32/, zadejte patřičný adresář PECL a stáhněte si DLL PDO do adresáře, který máte vyznačený v direktivě extension_dir PHP. Pak musíte přidat odkazy na ovladače rozšíření do souboru php.ini. Například chcete-li zapnout podporu MySQL, přidejte do sekce Windows Extensions řádek: extension=php_pdo_mysql.dll

Podpora databází v PDO Když jsem psal tyto řádky, podporoval PDO devět databází kromě všech těch, které jsou přístupné přes FreeTDS a ODBC:

• Firebird: přístupná přes ovladač FIREBIRD. • FreeTDS: to není databáze, ale sada knihoven Unixu, které umožňují programům založených na Unixu hovořit s databázemi MSSQL a Sybase. Přístupná přes ovladač DBLIB.

• • • •

IBM DB2: přístupná přes ovladač ODBC. Interbase 6: přístupná přes ovladač FIREBIRD. Microsoft SQL Server: přístupná přes ovladač MSSQL. MySQL 3.X/4.0: přístupná přes ovladač MYSQL. Připomínám, že v době, kdy jsem psal tyto řádky, nebylo dostupné rozhraní pro MySQL 5. Protože je jasné, že je to v seznamu priorit vývojářů hodně vysoko, bude to patrně brzy vyřešeno.

• ODBC v3: není databáze sama o sobě, ale umožňuje PDO používat v součinnosti s jakoukoli databázi kompatibilní s ODBC, která není uvedena v tomto seznamu. Přístupná přes ovladač ODBC.

• • • •

Oracle: přístupná přes ovladač OCI. PostgreSQL: přístupná přes ovladač PGSQL. SQLite 3.X: přístupná přes ovladač SQLITE. Sybase: přístupná přes ovladač SYBASE.


Velká kniha PHP a MySQL 5

555

Tip Které ovladače PDO máte dostupné ve svém prostředí můžete zjistit tak, že si v prohlížeči zobrazíte výstup z phpinfo() a podíváte se do sekce PDO. Nebo zavolejte funkci pdo_drivers(), jako zde: <?php print_r(pdo_drivers()); ?>.

Připojení k databázovému serveru a výběr databáze Než můžete začít komunikovat s databází přes PDO, musíte zřídit připojení k serveru a vybrat databázi. Udělá se to konstruktorem PDO. Jeho prototyp vypadá takto: PDO PDO::_ _construct(string DSN [, string username [, string password [, array driver_opts driver_opts]]]) ]]])

Parametr DSN (Data Source Name) se skládá ze dvou prvků: název požadovaného databázového ovladače a vš echny nezbytné proměnné databázového připojení, jako jsou název hostitele, port a náze v databáze. Parametry username a passw ord specifikují uživatelské jméno a heslo , které se použijí při připojení k databázi. Konečně, pole driver_opts specifikuje jakékoli další volby, které by se mohly požadovat nebo jsou žádoucí pro připojení. Seznam dostupných voleb je uveden na konci tohoto oddílu. Konstruktor lze volat několika způsoby, které si teď uvedeme.

Vložíte parametry do konstruktoru Při prvním způsobu volání konstruktoru PDO se parametry vloží přímo. Například byste ho mo hli zavolat třeba takto (jedná se konkrétně o databázi MySQL): $dbh = new PDO("mysql:host=localhost;dbname=corporate", "websiteuser", "secret");

Umístíte parametry do souboru PDO využívá schopnost PHP pracovat s proudy, což otevírá možnost umístit řetězec DSN do s eparátního souboru, který bude na nějakém místním nebo vzdáleném umístění. Na něj se pak odkážete v konstruktoru, jako zde: $dbh = new PDO("uri:file://usr/local/mysql.dsn");

Zajistěte ale, aby soubor vlastnil stejný uživatel, který vykonává skript PHP, a aby tento uživatel měl udělena patřičná přístupová oprávnění.

Odkážete se na soubor php.ini Je také možné udržovat informace o DSN v souboru php.ini, když je přiřadíte do konfiguračního parametru pdo.dsn.aliasname, kde aliasname je zvolené alias pro DSN, které následně dodáte do konstruktoru. Například v následující ukázce je alias DSN mysqlpdo: [PDO] pdo.dsn.mysqlpdo = "mysql:dbname=corporate;host=localhost"

Alias pak následně uvedete ve volání konstruktoru PDO, jako v: $dbh = new PDO("mysqlpdo", "websiteuser", "secret");

Podobně jako v předchozím způsobu, ani tento neumožňuje zařadit do DSN uživatelské jméno a heslo.


556

Kapitola 23 – Úvod do PDO

Volby PDO vztahující se k připojení Existuje několik voleb vztahujících se k připojení, jimiž můžete připojení přizpůsobit svým potřebám. Předávají se v poli driver_opts. Dostupné volby jsou uvedené v následujícím výčtu:

PDO_ATTR_AUTOCOMMIT: určuje, zda bude PDO potvrzovat změny hned po vykonání každého

PDO_ATTR_CASE: PDO můžete donutit, aby převáděl získané názvy sloupců na samé velká nebo na samá malá písmena, nebo aby používat názvy sloupců přesně v tom tvaru, v jakém jsou v databázi. Volba se nastavuje na jednu ze tří hodnot: PDO_CASE_UPPER, PDO_CASE_LOWER a PDO_CASE_NATURAL.

PDO_ATTR_ERRMODE: PDO podporuje tři módy oznamování chyb, PDO_ERRMODE_EXCEPTION,

dotazu, nebo zda bude čekat, až se vykoná metoda commit().

PDO_ERRMODE_SILENT a PDO_ERRMODE_WARNING. Určují, za jakých okolností PDO oznámí chybu. Volba se nastavuje na jednu ze tří výše uvedených hodnot, výchozí chování je PDO_ERRMODE_EXCEPTION. Tato volba se probírá podrobněji v pozdějším oddílu “Zpracování chyb”.

PDO_ATTR_ORACLE_NULLS: je-li nastavena na TRUE, způsobí, že se budou získané prázdné řetězce převádět na NULL. Výchozí hodnota je FALSE.

• •

PDO_ATTR_PERSISTENT: určuje, zda je připojení trvalé. Výchozí hodnota je FALSE.

PDO_ATTR_TIMEOUT: tato volba nastavuje dobu v sekundách, po kterou se bude čekat, než se

PDO_ATTR_PREFETCH: jedná se o databázovou schopnost, při které se získává několik řádků,

i když klient požaduje v daném okamžiku jen jeden řádek, a to na základě filozofie, že pokud klient požádal o jeden řádek, je pravděpodobné, že bude postupně žádat ještě o další. To snižuje počet požadavků obracejících se na databázi a zvyšuje efektivitu. Volba nastavuje velikost získávané sady v kilobajtech, u těch ovladačů, které tuto schopnost podporují. skončí.

Další čtyři atributy umožňují dozvědět se dodatečné informace o klientovi, serveru a o stavu připojení. Hodnoty těchto atributů lze získat metodou getAttribute(), která se probírá v pozdějším oddílu “Získávání a nastavování atributů”.

PDO_ATTR_SERVER_INFO: obsahuje specifické informace o databázovém serveru. V případě MySQL jsou to data vztahující se k době provozu serveru, kolik bylo celkem dotazů, průměrný počet vykonaných dotazů za sekundu a další důležité informace.

• • •

PDO_ATTR_SERVER_VERSION: obsahuje informace o čísle verze databázového serveru. PDO_ATTR_CLIENT_VERSION: obsahuje informace o čísle verze klienta databáze. PDO_ATTR_CONNECTION_STATUS: obsahuje informace o stavu připojení k databázi. Například pra-

cujete-li s MySQL, tak po úspěšném připojení atribut obsahuje „localhost via TCP/IP“, zatímco při práci s PostgreSQL obsahuje „Connection OK; waiting to send“.

Jakmile zřídíte připojení, můžete ho začít používat, a to je téma zbývající části kapitoly.


Kapitola 31

Uložené rutiny V průběhu práce s knihou jste viděli poměrně dost příkladů, v nichž se dotazy MySQL vkládaly přímo do skriptu PHP. U menších aplikací je to jistě v pořádku, jak ale slo žitost a velikost aplikací narůstá, mohlo by pokračování v takové praxi skončit až fiaskem. Například co když máte rozmístit dvě podobné aplikace, jednu desktopovou a druhou webovou, které obě používají databázi MySQL a provádějí mnoho stejných úkolů? Když je tu a tam třeba změnit nějaký dotaz, budete muset provést patřičné modifikace všude, kde se daný dotaz objevuje, a to ne v jedné, ale ve dvou aplikacích! Jinou výzvou, které čelíte, když pracujete se složitými aplikacemi, zvlášť když je vyvíjíte v týmu, je poskytnout každému členu týmu příležitost, aby mohl přispívat ke zdaru projektu na základě svých odborných znalostí a kvalifikace, aniž by přitom šlapal po úsilí ostatních. Typické je, že ti lidé, kteří jsou zodpovědní za vývoj databáze a údržbu (známí jako databázoví architekti), jsou neobyčejně erudovaní v psaní efektivních a bezpečných dotazů. Ale jak může takový databázový architekt psát a udržovat tyto dotazy, aniž by nelezl do zelí vývojáři aplikace, když jsou dotazy vložené přímo do kódu? Navíc, jak se může databázový architekt spolehnout na to, že vývojář následně „nezdokonalí“ tyto dotazy, a potenciálně tím otevře dveře infiltracím v podobě útoků injektáží SQL (které spočívají v tom, že se modifikují data odesílaná do databáze se záměrem, aby se pak dal spustit nějaký škodlivý kód SQL)? Jedním z nejběžnějších řešení těchto výzev je databázová schopnost, které se říká uložená rutina – stored routine. Uložená rutina je nějaká sada příkazů SQL, která je uložená na databázovém serveru a vykonává se tak, že se zavolá prostřednictvím dotazu názvem, který jí byl přiřazen. V mnohém je to obdoba funkce, protože ta také zapouzdřuje nějakou sadu příkazů, které se vykonají poté, co se funkce zavolá svým názvem. Uložená rutina se dá udržovat za bezpečnými zdmi databázového serveru a na kód aplikace nemusíte ani sáhnout. Od verze 5.0 už MySQL konečně podporuje tuto dlouho toužebně očekávanou schopnost. V této kapitole se dozvíte vše potřebné o tom, jak MySQL implementuje uložené rutiny. Probereme syntax a uvidíte, jak se uložené rutiny vytvářejí, spravují a vykonávají. Také se naučíte začleňovat uložené rutiny do svých webových aplikací. Na začátku se však chvilku zastavme u formálnějšího souhrnu jejich výhod a nevýhod.


734

Kapitola 31 – Uložené rutiny

Měli bychom používat uložené rutiny? Není žádoucí, abyste se naslepo nadšeně vrhli do módních vln uložených rutin. Vyplatí se, když v krátkosti posoudíme jejich přednosti a stinné stránky, zejména proto, že jejich užitečnost je v da tabázové komunitě předmětem vášnivých debat. V tomto oddílu najdete souhrn pro a proti, uvažujete-li o začlenění uložených rutin do své vývojářské strategie.

Přednosti uložených rutin Uložené rutiny mají mnoho předností, nejvýznačnější z nich jsou zdůrazněné zde:

• Eliminuje se redundance. Když mnoho aplikací napsaných v různých jazycích vykonává stejné databázové úkoly, tak shromáždění těchto úkolů do uložených rutin podobných funkcím redukuje jinak běžnou redundanci vývojových procesů.

• Vyšší výkon. Kompetentní databázový administrátor je pravděpodobně ten nejkompetentnější

člen týmu, když jde o to, jak psát optimalizované dotazy. Proto je rozumné, když se tvorba velmi komplikovaných operací, které se týkají databáze, přenechá tomuto individuu tím, že se takové operace udržují jako uložené rutiny.

• Větší bezpečnost. Když pracujete ve zvlášť citlivých prostředích, jako jsou bankovnictví, zdra-

votnictví nebo obrana státu, je někdy oficiálně nařízeno, aby byl přístup k datům přísně restriktivní. Uložené rutiny nabízejí skvělý způsob, jak zajistit, aby měli vývojáři přístup jen k těm informacím, které nezbytně potřebují k řešení svých úkolů..

• Snazší údržba rozsáhlých aplikací. Přestože diskuse o výhodách vícevrstevných architektur

přesahuje rámec této knihy, používání uložených procedur v součinnosti s vrstvou dat může dost usnadnit údržbu rozsáhlých aplikací. Chcete-li se o tomto tématu dozvědět víc, zadejte ve svém webovém vyhledávači termín „n-tier architecture“.

Nevýhody uložených rutin Přestože vás předchozí výčet předností přesvědčil, že jsou uložené rutiny ta cesta, kterou se vydáte, zamyslete se chvilku nad jejich nevýhodami:

• Vyšší spotřeba prostředků. Mnozí argumentují tím, že jediný účel databáze je ukládat data

a udržovat relace mezi nimi, ne vykonávat kód, který by jinak vykonala aplikace. Kromě toho, že se tím narušuje jediný hlavní účel databáze, vykonávání takové logiky z databáze spotřebovává také dodatečné prostředky procesoru a paměti.

• Menší zdatnost. Jak se brzy dozvíte, jazykové konstrukce SQL nabízejí bohatou výbavu i znač-

nou flexibilitu; většina vývojářů však přišla na to, že budovat tyto rutiny je snadnější i pohodlnější, když se to dělá v nějakém vyspělém plnohodnotném jazyku, jakým je PHP.

• Horší udržovatelnost rutin. Přestože se dají pro správu uložených rutin používat utility s gra-

fickým uživatelským rozhraním , jako je MySQL Query Browser (viz kapitola 26), psaní kódu i ladění uložených rutin je o hodně obtížnější, než když píšete funkce PHP ve zdatném integrovaném vývojovém prostředí.


Velká kniha PHP a MySQL 5

735

• Obtížnější přenositelnost. Protože uložené rutiny často používají syntax, která je specifická pro danou databázi, určitě se vynoří nějaké potíže s přenositelností, budete-li potřebovat používat aplikaci v součinnosti s jiným databázovým produktem

Nuže, i potom, co jste se seznámili s výhodami i nevýhodami, možná si stále nejste jisti, zda jsou uložené rutiny pro vás to pravé. Asi nejlepší rada, kterou je možno v tomto ohledu poskytnout, je, abyste si přečetli tuto kapitolu a podnikli všelijaké experimenty s četnými příklady, které v ní najdete.

Jak MySQL implementuje uložené rutiny Přestože se všude okolo omílá termín uložené procedury, MySQL ve skutečnosti implementuje dvě varianty procedur, na které se odkazuje společně jako na uložené rutiny:

• Uložené procedury. Uložené procedury podporují vykonávání příkazů SQL jako jsou SELECT,

INSERT, UPDATE a DELETE. Mohou také připravovat parametry, na které se dá odkazovat později, vně procedury.

• Uložené funkce. Uložené funkce podporují vykonávání pouze příkazů SELECT, akceptují jen

vstupní parametry a musejí vracet právě jednu hodnotu. Kromě toho můžete vložit uloženou funkci přímo do příkazu SQL tak, jak to děláte se standardními funkcemi MySQL, jako jsou count() a date_format().

Všeobecně řečeno, uložené procedury byste měli používat tehdy, když potřebujete pracovat s daty nacházejícími se v databázi, třeba získávat řádky, vkládat, odstraňovat nebo aktualizovat hodnoty, zatímco s pomocí uložených funkcí byste měli s t ěmito daty manipulovat nebo provádět speciální výpočty. Syntax prezentovaná v průběhu kapitoly je ovšem pro obě varianty prakticky identická, kromě toho, že se přepíná termín „procedura“ a „funkce“. Například, příkazem DROP PROCEDURE název_procedury se odstraní existující uložená procedura, kdežto příkazem DROP FUNCTION název_funkce se odstraní existující uložená funkce.

Tabulky přístupových oprávnění uložených rutin Ti z vás, kdo už s MySQL nějaký čas pracujete, dobře víte, že v databázi mysql přibyly nové tabulky. Dvě z nich, proc a procs_priv, slouží ke správě uložených rutin a přístupových oprávnění, která se požadují, chcete-li je vytvářet, vykonávat, měnit nebo odstraňovat.

proc V tabulce proc jsou uložené informace o uložené rutině, mezi něž pa tří její syntax, datum, kdy byla vytvořena, seznam jejích parametrů a další věci. Její strukturu prezentuje tabulka 31-1. Tabulka 31-1. Tabulka proc databáze mysql Sloupec

Datový typ

Null

Výchozí hodnota

db

char(64)

Ano

Není

name

char(64)

Ne

Není

type

enum('FUNCTION','PROCEDURE')

Ne

Není


736

Kapitola 31 – Uložené rutiny

Sloupec

Datový typ

Null

Výchozí hodnota

specific_name language

char(64)

Ne

Není

enum('SQL')

Ne

SQL

sql_data_access

enum přístupu k datům

Ne

CONTAINS_SQL

is_deterministic

enum('YES', 'NO')

Ne

NO

security_type

enum('INVOKER','DEFINER')

Ne

DEFINER

param_list

blob

Ne

Není

returns

char(64)

Ne

Není

body

longblob

Ne

Není

definer

char(77)

Ne

Není

created

timestamp

Ano

CURRENT_TIMESTAMP

modified

timestamp

Ano

0000-00-00 00:00:00

sql_mode

mmožina módů sql

Ne

Není

comment

char(64)

Ne

Není

Aby nebyl sloupec tabulky pro datový typ zoufale široký, je termín enum přístupu k datům datům zástupce skutečného výčtu enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA')

a termín množina módů sql zastupuje množinu set('REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE').

Všechny sloupce se podrobněji probírají v oddílu „Jak se vytvoří uložená rutina“.

procs_priv V tabulce procs_priv jsou uloženy informace o přístupových oprávněních vyjadřující, kteří uživatelé mohou komunikovat s rutinami definovanými v tabulce proc. Struktura tabulky procs_priv je uvedena v tabulce 31-2. Tabulka 31-2. Tabulka procs_priv databáze mysql Sloupec

Datový typ

Null

Výchozí hodnota

Host

char(60)

Ne

Není

Db

char(64)

Ne

Není

User

char(16)

Ne

Není

Routine_name

char(64)

Ne

Není

Routine_type

enum('FUNCTION', 'PROCEDURE')

Ne

Není


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.