bachelor thesis

132
Vysoká škola ekonomická v Praze Fakulta informatiky a statistiky Katedra informačního a znalostního inženýrství Studijní program: Aplikovaná informatika Obor: Informatika Srovnání PHP frameworků Phalcon, Nette a Zend BAKALÁŘSKÁ PRÁCE Student : Jiří Rebenda Vedoucí : Ing. et Ing. Stanislav Vojíř Oponent : Ing. Jiří Zumr 2014

Upload: jiri-rebenda

Post on 21-Feb-2017

520 views

Category:

Documents


12 download

TRANSCRIPT

Page 1: Bachelor Thesis

Vysoká škola ekonomická v Praze

Fakulta informatiky a statistiky

Katedra informačního a znalostního inženýrství

Studijní program: Aplikovaná informatika

Obor: Informatika

Srovnání PHP frameworků Phalcon,

Nette a Zend

BAKALÁŘSKÁ PRÁCE

Student : Jiří Rebenda

Vedoucí : Ing. et Ing. Stanislav Vojíř

Oponent : Ing. Jiří Zumr

2014

Page 2: Bachelor Thesis

Prohlášení:

Prohlašuji, že jsem bakalářskou práci zpracoval samostatně a že jsem uvedl všechny použité

prameny a literaturu, ze které jsem čerpal.

V Praze dne 12. května 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Jiří Rebenda

Page 3: Bachelor Thesis

Poděkování

Zde bych rád poděkoval Ing. et Ing. Stanislavu Vojíři jakožto vedoucímu bakalářské práce

za podnětné připomínky a čas, který jí věnoval. Za provedenou gramatickou korekturu rov-

něž děkuji svým rodičům.

Page 4: Bachelor Thesis

Abstrakt

Dostupnost jazyka PHP a jeho rozšíření napříč vývojáři webových aplikací zapříčiňuje exis-

tenci mnoha projektů na něm postavených. S růstem jeho popularity rostly (a pravděpodobně

do budoucna růst budou) i požadavky na něj kladené. Mnoho z nich nemusí přímo souviset

s jazykem jako takovým, nýbrž s potřebami danými vnějšími okolnostmi (rozvoj Internetu

apod.). Jednou z reakcí na existencí stále se opakujících se problémů a jejich rostoucí kom-

plexitu jsou speciální knihovny známé též jako frameworky.

Tato bakalářská práce se věnuje porovnání tří vybraných frameworků (Zend Framework 2.3,

Nette 2.1.2 a Phalcon 1.3.1). V první (kratší) části jsou zprvu deklarovány některé základní

pojmy a omezení daná prostředím PHP. Dále jsou spolu s popisem jednotlivých kritérií, na

základě kterých jsou frameworky dále porovnávány, uvedeny otázky, na něž jsou v hlavní

části práce poskytnuty (více či méně explicitní) odpovědi.

Druhá – teoreticko-praktická část – se již zabývá rozborem frameworků v souvislosti s defi-

novanými problémovými oblastmi. Smyslem popisu aplikačního rozhraní frameworků spolu

s ukázkami kódu je popsat čtenáři eventuální rozdíly v pojetí řešení některých vybraných

problémů. Práce se rovněž okrajově dotýká způsobů, jakými lze hodnotit jejich relativní ob-

líbenost.

Výstupem práce není kladné, či záporné hodnocení některého z frameworků. Práce by nao-

pak měla být chápána jako jeden z možných zdrojů např. při rozhodování se, zda některému

z frameworků věnovat vyšší pozornost, či nikoliv. Dílčím přínosem je i fakt, že jsou potvr-

zeny některé axiomatické předpoklady (např. co se týče jejich rychlosti a oblíbenosti).

Klíčová slova

PHP, porovnání frameworků, webový vývoj, Zend, Nette, Phalcon.

Page 5: Bachelor Thesis

Abstract

Wide usage of the PHP language across web developers and its good availability results in

existence of many projects built on it. Unfortunately, due to the growth of PHP popularity

more requirements are imposed on it. Not all of them tend to be related directly to the lan-

guage itself but they can be affected by the external conditions (like e.g. Internet evolution,

etc.). Special libraries (also known as frameworks) are response to existence of permanently

repetitive tasks and growing complexity of problems being solved not only in the context of

web development.

There are three PHP framework representatives compared in this paper (Zend Framework

2.3, Nette 2.1.2 and Phalcon 1.3.1). In the first section, some fundamental terms are declared

as well as some inherent limitations of the PHP language itself. Further, various comparison

criterions are introduced together with additional research questions which are more or less

answered in the main section.

The second theoretical-practical section analyses the frameworks in the context of the de-

fined problem domains. The main purpose of the application programming interface review

together with included code snippets is to describe possible differences in approaches ap-

plied for some specific problems. Additionally, some options for measuring framework pop-

ularity mentioned in earlier section are used, too.

In the end, frameworks are not evaluated either in positive or negative way. The final eval-

uation remains on the actual reader. The main focus is to provide basic insight into all three

frameworks and possibly to (de)motivate to deeper exploration any of them. Also, as matter

of secondary objectives some axiomatic assumptions are validated (like speed and popularity

of the frameworks).

Keywords

PHP, frameworks comparison, web development, Zend, Nette, Phalcon.

Page 6: Bachelor Thesis

Obsah

1 Úvod ........................................................................................................... 1

1.1 Cíle práce ............................................................................................................... 1

1.2 Předpoklady a omezení práce .............................................................................. 2

1.3 Struktura práce ..................................................................................................... 2

2 Rešerše stávajících prací ........................................................................... 3

3 PHP frameworky .......................................................................................... 5

3.1 Základní termíny ................................................................................................... 5

3.1.1 PHP (Hypertext Preprocessor) ................................................................ 5

3.1.2 PHP framework......................................................................................... 6

3.1.3 Návrhové vzory ........................................................................................ 7

3.2 Oblíbenost PHP frameworků ................................................................................ 9

3.2.1 Popularita ve vyhledávači Google .......................................................... 9

3.2.2 Popularita v diskuzních fórech a sociálních sítích ............................... 9

3.2.3 Vývojářská aktivita ................................................................................. 10

3.2.4 Počet pracovních nabídek ..................................................................... 10

3.3 Kritéria pro porovnání ........................................................................................ 10

3.3.1 Technické požadavky frameworku ....................................................... 10

3.3.2 Autoloading tříd ..................................................................................... 10

3.3.3 MVC ......................................................................................................... 11

3.3.4 DI (Dependency Injection) ..................................................................... 11

3.3.5 Komponentový vývoj ............................................................................. 12

3.3.6 Šablonový systém .................................................................................. 13

3.3.7 Formuláře ............................................................................................... 14

3.3.8 Session a Cookies ................................................................................. 14

3.3.9 Databázová abstrakce ........................................................................... 15

3.3.10 Autorizace, autentizace ......................................................................... 16

3.3.11 Lokalizace ............................................................................................... 17

3.3.12 Využití cache .......................................................................................... 17

3.3.13 Ladění a zpracování chyb ..................................................................... 18

3.3.14 Rychlost .................................................................................................. 19

3.3.15 Ostatní ..................................................................................................... 22

4 Porovnání PHP frameworků ..................................................................... 23

4.1 Technické požadavky frameworku .................................................................... 23

4.1.1 Zend ........................................................................................................ 23

4.1.2 Nette ........................................................................................................ 23

4.1.3 Phalcon ................................................................................................... 24

4.2 Autoloading tříd .................................................................................................. 24

Page 7: Bachelor Thesis

4.2.1 Zend ........................................................................................................ 24

4.2.2 Nette ........................................................................................................ 25

4.2.3 Phalcon ................................................................................................... 25

4.3 MVC ...................................................................................................................... 26

4.3.1 Zend ........................................................................................................ 26

4.3.2 Nette ........................................................................................................ 29

4.3.3 Phalcon ................................................................................................... 33

4.4 DI (Dependency Injection) .................................................................................. 35

4.4.1 Zend ........................................................................................................ 35

4.4.2 Nette ........................................................................................................ 37

4.4.3 Phalcon ................................................................................................... 39

4.5 Komponentový vývoj .......................................................................................... 40

4.5.1 Zend ........................................................................................................ 40

4.5.2 Nette ........................................................................................................ 41

4.5.3 Phalcon ................................................................................................... 43

4.6 Šablonový systém .............................................................................................. 44

4.6.1 Zend ........................................................................................................ 44

4.6.2 Nette ........................................................................................................ 47

4.6.3 Phalcon ................................................................................................... 49

4.7 Formuláře ............................................................................................................ 51

4.7.1 Zend ........................................................................................................ 51

4.7.2 Nette ........................................................................................................ 54

4.7.3 Phalcon ................................................................................................... 56

4.8 Session a Cookies .............................................................................................. 58

4.8.1 Zend ........................................................................................................ 58

4.8.2 Nette ........................................................................................................ 60

4.8.3 Phalcon ................................................................................................... 61

4.9 Databázová abstrakce ........................................................................................ 63

4.9.1 Zend ........................................................................................................ 63

4.9.2 Nette ........................................................................................................ 65

4.9.3 Phalcon ................................................................................................... 67

4.10 Autorizace, autentizace ...................................................................................... 71

4.10.1 Zend ........................................................................................................ 71

4.10.2 Nette ........................................................................................................ 72

4.10.3 Phalcon ................................................................................................... 73

4.11 Lokalizace ............................................................................................................ 73

4.11.1 Zend ........................................................................................................ 73

4.11.2 Nette ........................................................................................................ 74

4.11.3 Phalcon ................................................................................................... 75

4.12 Využití cache ....................................................................................................... 75

4.12.1 Zend ........................................................................................................ 75

Page 8: Bachelor Thesis

4.12.2 Nette ........................................................................................................ 77

4.12.3 Phalcon ................................................................................................... 78

4.13 Ladění a zpracování chyb .................................................................................. 80

4.13.1 Zend ........................................................................................................ 80

4.13.2 Nette ........................................................................................................ 81

4.13.3 Phalcon ................................................................................................... 82

4.14 Rychlost ............................................................................................................... 84

4.14.1 Celkové zpracování požadavku ............................................................ 84

4.14.2 Výkonnost databázové vrstvy ............................................................... 87

4.15 Ostatní ................................................................................................................. 92

4.15.1 Licenční omezení ................................................................................... 92

4.15.2 Dokumentace ......................................................................................... 93

4.15.3 Komunita spojená s frameworkem ....................................................... 93

4.15.4 Počet pracovních nabídek ..................................................................... 95

4.15.5 Existující rozšíření ................................................................................. 95

5 Závěr ......................................................................................................... 97

Terminologický slovník ................................................................................... 98

Seznam literatury ........................................................................................... 101

Seznam obrázků a tabulek ............................................................................ 108

Základní text .............................................................................................................. 108

Seznam obrázků ............................................................................................. 108

Seznam tabulek .............................................................................................. 108

Přílohy ....................................................................................................................... 109

Seznam tabulek .............................................................................................. 109

Příloha A: Výsledky rychlostního měření ..................................................... 110

A.1 Celkové zpracování požadavku ....................................................................... 110

A.2 Výkonnost databázové vrstvy .......................................................................... 119

Page 9: Bachelor Thesis

1 Úvod 1

1 Úvod Tvorba softwaru zahrnuje celou řadu jak obecných tak i specifických činností a bezpochyby

klade poměrně vysoké nároky na osoby zodpovědné za jeho samotnou realizaci. Zejména

pak v kontextu vývoje webových/internetových aplikací je nutné podotknout (odhlédneme-

li od obecných požadavků jako jsou např. zkušenosti vývojáře), že mezi běžné kvalifikační

požadavky patří alespoň základní znalost hned několika různých technologií, přičemž se zá-

roveň předpokládá hlubší znalost alespoň jedné z nich.

K základním požadavkům patří znalost jednoho konkrétního programovacího/skriptovacího

jazyka určeného k vývoji na straně serveru (např. PHP, ASP .NET C#, …) a sloužícího k ob-

sloužení vnějších požadavků (např. požadavek internetového prohlížeče ke stažení webové

stránky), tak celá řada klientsky založených (angl. client-side) jazyků orientovaných hlavně

na sémantickou a grafickou část odpovědi vrácené serverem (HTML stránka, CSS, JS, …).

Nadstavbou je pak znalost práce s nejrůznějšími knihovnami a jedná-li se o jazyk PHP, který

je v současnosti vůbec nejpopulárnějším webově orientovaným jazykem1, pak se tímto nej-

častěji rozumí znalost některého z PHP frameworků. Náplní této práce je popis tří vybraných

zástupců lišících se svým pojetím, rozsahem i stářím. Jelikož každý může od frameworku

očekávat něco jiného, je celkové hodnocení jednotlivých frameworků ponecháno na čtenáři.

Práce by měla posloužit jako výchozí bod např. při rozhodování, kterému frameworku vě-

novat více pozornosti v závislosti na konkrétních preferencích čtenáře.

1.1 Cíle práce

Vycházíme-li z předchozího rozdělení, tato práce se zabývá jedním z dílčích aspektů souvi-

sejících s vývojem na straně serveru, a to konkrétně v jazyce PHP za využití několika vy-

braných a v současnosti veřejně dostupných frameworků: Zend, Nette, Phalcon. Primárním

cílem práce je představení těchto frameworků, popis jejich charakteristických rysů, mož-

ností, které nabízejí a praktické porovnání jejich použitelnosti z pohledu vývojáře.

Hlavním důvodem volby právě těchto tří frameworků je zájem autora porovnat různé pří-

stupy pro řešení běžných problémů v rámci vývoje webových aplikací, do jaké míry jsou

jednotlivé problémové oblasti pokryty frameworkem a případně do jaké míry je ponechán

prostor vývojáři např. k úpravě jeho standardního chování apod. Důležitým výstupem práce

je jejich pozitivní, avšak kritické porovnání na základě definovaných kritérií, která jsou uve-

dena v první části práce.

1 Vyplívá z dat zveřejněných (Q-Success, 2014).

Page 10: Bachelor Thesis

1 Úvod 2

1.2 Předpoklady a omezení práce

Práce je určena všem zájemcům o praktický vývoj v PHP za použití frameworků. Předpo-

kládá se alespoň základní znalost problematiky objektově orientovaného programování

(OOP) a to ideálně v návaznosti na podporu OOP konstrukcí ze strany PHP. Dále orientace

v prostředí PHP, případně jiného obdobného jazyka. Podmínkou je rovněž znalost obecných

principů souvisejících s vývojem webových stránek a aplikací a povědomí o existenci návr-

hových vzorů.

1.3 Struktura práce

Práce je rozdělena na dvě části. První část práce seznamuje čtenáře s vybranými hledisky

vývoje webových aplikací za podpory PHP frameworků. V této části jsou definovány zá-

kladní pojmy použité v práci. Rovněž jsou popsány některé problémy a omezení související

s vývojem webových aplikací, obzvláště v souvislosti s nasazením některého z frameworků.

V návaznosti na jejich identifikaci jsou následně definována kritéria, na základě kterých je

porovnání realizováno. Druhá část obsahuje již samotné srovnání frameworků, přičemž

v rámci jedné problémové oblasti jsou porovnány všechny tři frameworky navzájem a to

vždy v pořadí Zend, Nette, Phalcon. Struktura a způsob porovnání frameworků jsou převzaty

a vychází především z (Křižan, 2010), případně jiných podobně zaměřených prací.

Page 11: Bachelor Thesis

2 Rešerše stávajících prací 3

2 Rešerše stávajících prací Souhrn existujících prací zabývajících se tématikou komparace PHP frameworků lze v zá-

sadě rozdělit na dva typy:

Práce zabývající se komplexním popisem jednoho či více frameworků, kdy jsou

srovnávány na základě několika parametrů, tento druh prací lze rozdělit ještě na další

dva samostatné podtypy:

o Srovnání frameworků v rámci jazyka PHP,

o Srovnání frameworků různých platforem.

Srovnání frameworků na základě jediné vybrané oblasti, kterou frameworky nabí-

zejí.

Velmi komplexní srovnání čtyř vybraných frameworků (CodeIgniter, Zend, Prado, Yii) po-

dává (Křižan, 2010). Autor věnoval poměrně rozsáhlý prostor teoretické části, ve které po-

pisuje problematiku tvorby webových aplikací v prostředí PHP a stejně tak vyzdvihuje

významné vlastnosti, kterými se frameworky obecně vyznačují. Popsány jsou základní ar-

chitektonické vzory a požadavky na framework. Na tuto část plynule navazuje oddíl věno-

vaný elementární charakteristice zvolených frameworků včetně údajů o šíři komunity, která

je s nimi spojena. Následně jsou definována kritéria, na základě kterých autor provedl srov-

nání a to včetně metrik, které jsou ale ve všech případech hodnocených kritérií prakticky

totožná a spočívají v identifikaci toho, zdali daný framework konkrétní oblast podporuje či

nikoliv včetně případného komentáře. Autor na závěr neopomenul ani interpretaci výsledků

srovnání, které jsou popsány relativně výstižně a jasně.

Z prací věnovaných více než jednomu PHP frameworku lze zmínit (Koščo, 2013), ve které

jsou porovnány frameworky Zend a Symfony. Za užitečnou část práce lze považovat už jen

fakt, že autor v samostatné kapitole demonstroval důvody, proč pro porovnání zvolil právě

tyto dva zástupce – faktor oblíbenosti je zde doložen exaktními údaji z veřejně dostupných

internetových zdrojů (diskuzní fóra, popularita ve vyhledávačích apod.). Struktura hodno-

cení spočívá v demonstraci možností frameworků vytvořením vzorové aplikace v každém

z nich. Vyhodnocení opět spočívá ve stanovení vah kritérií, které jsou na konci interpreto-

vány za použití tzv. Fullerovy2 metody.

Z dalších prací věnujících se však rozboru pouze jednoho frameworku lze zmínit bakalář-

skou práci o českém frameworku Nette (Tölg, 2012). Zde autor kromě obecně platných prin-

cipů popisuje i konkrétní příklady využití návrhových vzorů, které Nette uplatňuje.

2 Metoda spočívá v postupném porovnání dvojic kritérií mezi sebou a určení, zdali je

první kritérium důležitější než druhé, případně zda se jejich důležitost rovná. (Žižka,

2008)

Page 12: Bachelor Thesis

2 Rešerše stávajících prací 4

Samozřejmostí jsou zmínky i o některých jeho specifických vlastnostech, které např. jiné

frameworky vůbec nenabízejí. Celkový dojem z kvality práce však mírně zhoršuje poměrně

familiární vyjadřování autora a zhoršená čitelnost uváděných výpisů kódu.

K dispozici jsou i práce orientované na srovnání některého z PHP frameworků s framewor-

kem určeným pro jinou platformu, jak představuje ve své relativně rozsáhlé práci (Frank,

2013). Délka je ovlivněna především tím, že autor rozpracoval i tzv. zadavatelsko-analytic-

kou část pro vytvoření vzorové aplikace a mj. také množstvím kódu, kterými autor demon-

stroval jejich praktické využití. Autor popisuje zvolená kritéria jasně a srozumitelně

a nezahlcuje čtenáře implementačními detaily během jejich srovnávání, což eventuální zá-

jemce o daný framework vybízí k dohledání těchto informací z jiného zdroje (např. doku-

mentace).

Pravděpodobně vůbec nejznámějšímu frameworku Zend je věnována pozornost hned v ně-

kolika pracích. Např. (Kutišová, 2013) srovnává jeho 2 majoritní verze a změny ke kterým

došlo v rámci novější verze a to opět včetně vytvoření vzorové aplikace v obou verzích.

Page 13: Bachelor Thesis

3 PHP frameworky 5

3 PHP frameworky Vytvoření „dokonalé“ aplikace, ať již webové či desktopové, je snem snad každého, kdo se

na jejím vývoji podílí. Pakliže framework obecně je považován za nástroj napomáhající

k dosažení tohoto cíle, je vhodné pokusit se určit důvody, které tento názor podporují.

Následující část má za cíl v úvodu stručně popsat důležité termíny, které jsou v práci použity

a představit čtenáři základní informace o jazyku PHP, jeho specifických možnostech,

zejména pak v kontextu PHP frameworků. Dále jsou představeny obecné požadavky na fra-

mework a v souladu s tím i výčet jejich vybraných charakteristik, spolu s dalšími termíny

souvisejícími s vývojem webových aplikací. Rovněž jsou uvedeny příklady frameworků

a část je věnována i přehledu jejich „oblíbenosti“.

3.1 Základní termíny

Tato část si klade za cíl stručně charakterizovat vybrané pojmy, které lze z povahy práce

požadovat za fundamentální. Jelikož jsou však tyto termíny zároveň popsány v mnoha jiných

pracích, je kladen důraz na identifikaci méně zřejmých faktorů a důsledků např. z použití

frameworku, souvisejících zejména s jejich reálným nasazením. Vzhledem k charakteru

práce jsou okrajově zmíněny i některé další nepřímo související pojmy či problémy týkající

se návrhu aplikace obecně.

3.1.1 PHP (Hypertext Preprocessor)

PHP je dynamický interpretovaný skriptovací jazyk, který je převážně určen k vývoji webo-

vých stránek a aplikací a vyznačuje se tím, že jej lze zakomponovat přímo do HTML (The

PHP Group, 2014) a umožňuje tak tvorbu dynamických a interaktivních webových stránek

(PHP 5 Tutorial, 2014).

Fakt, že se jedná právě o dynamický a skriptovací jazyk je kruciální, jelikož z něj plynnou

v porovnání s jinými platformami mj. tyto důsledky:

Skript je při každém požadavku interpretován tzn., dochází k jeho opětovnému par-

sování (analýze), interpretaci a vykonání, na rozdíl od kompilovaných jazyků, kde

tento proces probíhá zpravidla pouze jednou. (IBM Corporation, 2010)

Při použití interpretovaného jazyka rovněž odpadá nutnost při každé změně celý pro-

gram rekompilovat (Vanguard Software Corporation, 2013)

Ve srovnání se staticky typovanými jazyky je typ proměnné určen za běhu, přičemž

během vykonání skriptu může dojít i k jeho změně. Toho lze s výhodou využít v celé

Page 14: Bachelor Thesis

3 PHP frameworky 6

řadě situací, zároveň se ale relativně zvyšuje potenciální chybovost, jelikož je chyba

detekována až za běhu skriptu.

PHP a OOP (objektově orientované programování)

Současná podoba OOP modelu vychází z jeho poslední majoritní verze 5 (PHP: Introduction

- Manual, 2014), kdy byl kompletně přepsán a doplněn o nové možnosti. PHP podporuje

většinu obvyklých OOP konstrukcí (abstrakce, třídy, dědičnost, viditelnost, …) známých

např. ze silně OOP jazyků (např. C++, Java, C#, …), avšak některé z nich jsou podporovány

jen částečně a s jistými omezeními (např. přetěžování metod).

OOP model je zároveň rozšířen o některé zvláštní konstrukce, jako jsou např. tzv. magické

metody3 (angl. magic methods), jejichž znalost je důležitá nejen pro obecnou práci s objekty

(konstrukce/destrukce instancí), ale i pro další řadu specifických činností, jelikož umožňují

dosáhnout úspory kódu, potažmo času. Z hlediska nutnosti znalosti jejich existence je nutné

je považovat za esenciální, jelikož principů magických metod využívají typicky právě nej-

různější PHP knihovny/frameworky, o kterých je řeč dále.

3.1.2 PHP framework

Pojem framework lze v obecném měřítku chápat jako „souhrn principů, myšlenek, které jsou

používány v rámci rozhodování, či strukturu, která podporuje určitou činnost“ (framework

- definition of framework by Macmillan Dictionary, 2014). V kontextu softwarového vývoje

lze pak uvést odvozenou definici, která říká, že „framework je určitá knihovna, která

poskytuje základní podpůrnou strukturu pro vývoj aplikací pro konkrétní prostředí“

(Application Framework, 2014).

Z praktického hlediska pak framework4 představuje určitou sadu tříd, knihoven a nástrojů,

jehož cílem by mělo být usnadnění práce při vývoji aplikací. (Tölg, 2012) Možnosti daného

frameworku jsou pak samozřejmě dány jeho aplikačním rozhraním (dále jen API5), jehož

návrh může ovlivnit i použitelnost frameworku jako celku. Podstatným znakem frameworku

je dle (Křižan, 2010) to, že třídy v něm obsažené mají implicitně definováno určité chování,

které by mělo být z principu výhodné a proto i užitečné.

3 Seznam všech magických metod je k dispozici na http://www.php.net/manual/en/lan-

guage.oop5.magic.php.

4 Nebude-li dále uvedeno jinak, má se na mysli vždy PHP framework.

5 Z anglického Application Programming Interface.

Page 15: Bachelor Thesis

3 PHP frameworky 7

Frameworků určených pro jazyk PHP existuje celá řada6, přičemž platí, že jsou v tomto ja-

zyce zároveň i napsány. Výjimku tvoří v současnosti jako jeden z mála7 framework Phalcon,

který je vytvořen v jazyce C a je distribuován jako zásuvný modul pro PHP. Z existujících

frameworků, z nichž některé jsou charakterizovány v pracích podobného zaměření, je možné

zmínit např.:

Symfony (http://symfony.com),

CakePHP (http://cakephp.org),

CodeIgniter (http://ellislab.com/codeigniter),

Yii (http://www.yiiframework.com),

Laravel (http://laravel.com).

Omezení

Frameworky zpravidla usnadňují tzv. „opakující se rutinní práci“ a umožňují vývojáři sou-

středit se spíše na implementaci doménové logiky s prostředky daného frameworku či dal-

ších knihoven. Problém však může nastat v případě, že řešený problém nelze s daným

výchozím chováním vyřešit. Na řadě je pak buď přeformulování problému za účelem při-

způsobení se daným možnostem či změna/rozšíření výchozího chování frameworku. Míra

přizpůsobení frameworku daným podmínkám proto hraje důležitou roli z hlediska jeho po-

užitelnosti.

V neposlední řadě je nutné poukázat na fakt, že jakýkoliv realizovatelný problém je možné

s danými prostředky vyřešit zpravidla několika způsoby. Vhodnost řešení je posuzována

subjektivně, protože závisí a zároveň je odrazem zkušeností a je ovlivněna komplexní zna-

lostí frameworku (příkladem může být (ne)vědomé nedodržování konvencí daných frame-

workem atd.).

3.1.3 Návrhové vzory

Jedním z fenoménů, na který dříve či později narazí každý vývojář, je časté opakování stej-

ného kódu v rámci jediného či více programů/skriptů. Možné důsledky a problémy s tímto

spojené jsou motivací k nalezení způsobu, jak tomuto stavu v budoucnu předejít. Jednu

z možných cest nabízí aplikace tzv. „návrhových vzorů, což jsou obecné, znovupoužitelné

6 http://www.bestwebframeworks.com/compare-web-frameworks/php/

7 Jiným zástupcem je framework Yaf (http://www.yafdev.com).

Page 16: Bachelor Thesis

3 PHP frameworky 8

způsoby řešení běžných softwarových problémů“ (Design Patterns, 2014). Zároveň lze kon-

statovat, že „návrhové vzory nejsou hotovým řešením daného problému, nýbrž je lze chápat

spíše jako šablony pro postup jeho řešení“ (Design Patterns, 2014).

V předešlé části byla zmíněna teze, že cílem použití frameworku by mělo být usnadnění

vývoje aplikací. Jak toho lze ale reálně dosáhnout? Nabízí se odpověď, že jsou to právě

návrhové vzory, za pomoci kterých se lze tomuto cíli při nejmenším přiblížit. Vývoj s vědo-

mím existence a především skutečného použití návrhových vzorů vede v ideálním případě

k relativně znovupoužitelnému, lépe udržitelnému a testovatelnému kódu. (Design Patterns,

2014)

MVC (Model View Controller)

„Návrhový vzor MVC patří mezi nejznámější a nejdiskutovanější návrhové vzory“ (Fowler,

a další, 2002) zejména pak v souvislosti s vývojem webových aplikací, jelikož jeho určitou

implementaci obsahují všechny majoritní frameworky. MVC lze považovat za paradigma,

jehož prostřednictvím je aplikační architektura rozdělena na 3 na sobě relativně8 nezávislé

vrstvy:

Model – Vše, co představuje tzv. „business logiku“ aplikace je součástí této vrstvy;

často bývá model chybně interpretován jako databáze, prakticky tato vrstva sice

často s databází pracuje, ale z obecného hlediska lze do této vrstvy zahrnout veškerou

práci s daty, která jsou tak zapouzdřena a oddělena od zbytku aplikace (Křižan,

2010). Ve skutečnosti však model může a často obsahuje celou sekvenci operací než

jen získání či ukládání dat (např. generování objednávky spolu s vystavením faktury

a její následné odeslání e-mailem uživateli apod.).

View (pohled) – „Pohled zobrazuje model“ (Fowler, a další, 2002), resp. data z mo-

delu a to prostřednictvím uživatelského rozhraní (UI – User Interface). Prezentace

dat ve webových aplikacích je nejčastěji dána výstupem do HTML stránky.

Controller (řadič) – Řadič zajišťuje oboustrannou „komunikaci“ mezi vrstvou mo-

delu (např. získání, resp. uložení dat) a pohledem (např. zobrazení, resp. získání dat).

Důsledné rozdělení zodpovědností za každou z oblastí do zvláštních vrstev s sebou přináší

řadu výhod, mezi které patří:

Data jsou oddělena od jejich prezentace, tudíž jedna sada dat může být zobrazena

v různých výstupních formátech.

Pohled může zobrazovat data z různých zdrojů, která jsou mu předána řadičem.

8 Relativní vztah je uveden proto, že jedna z vrstev (řadič) musí v principu fungovat jako

prostředník mezi dalšími dvěma.

Page 17: Bachelor Thesis

3 PHP frameworky 9

Každou z vrstev je možné (v ideálním případě) vytvářet a testovat relativně samo-

statně.

3.2 Oblíbenost PHP frameworků

Následující kapitola představuje stručnou rešerši přístupů k porovnání relativní

„oblíbenosti“ PHP frameworků mezi sebou navzájem (nikoliv tedy v porovnání s jinými

platformami). Metodika porovnání často vychází ze srovnání několika faktorů:

1. Popularita ve vyhledávači Google.

2. Popularita v diskuzních fórech a sociálních sítích (např. www.stackoverflow.com).

3. „Aktivnost vývoje“ – souvisí s počtem přispěvatelů, počtem vydaných verzí apod.

4. Počet pracovních nabídek s požadavkem na znalost konkrétního frameworku.

Z příkladů srovnání tohoto typu lze uvést jednak diplomovou práci (Koščo, 2013) a jednak

z řady „online testů“ např. (Korop, 2013).

3.2.1 Popularita ve vyhledávači Google

Pro zjištění oblíbenosti z pohledu vyhledávání ve vyhledávači Google použil jak (Koščo,

2013), tak i (Korop, 2013) oficiální nástroj společnosti Google - Google Trends9. Omezení

tohoto nástroje uvádí již (Koščo, 2013), z nichž lze podtrhnout zejména faktor volby samot-

ného klíčového slova (existuje více verzí frameworků). Pro doplnění lze poznamenat ještě

další faktor, kterým je rozlišení geografického rozložení, jehož změnou lze docílit zásadního

rozdílu ve výsledcích měření.

3.2.2 Popularita v diskuzních fórech a sociálních sítích

Popularitu v diskuzních a jiných fórech lze sledovat na základě rozdělení jejich typů:

1) fóra věnovaná konkrétnímu frameworku,

počet registrovaných uživatelů,

počet příspěvků.

2) obecně založená fóra obsahující témata i s jinou, byť ne přímo související tématikou.

9 http://www.google.com/trends/

Page 18: Bachelor Thesis

3 PHP frameworky 10

Absolutní hodnoty těchto měření lze získat relativně snadno, jak předkládá (Koščo, 2013).

3.2.3 Vývojářská aktivita

Do této skupiny lze zahrnout hodnocení četnosti vydaných verzí (počet „commitů“ do repo-

sitáře projektu) a počet vývojářů či přispěvatelů projektu.

3.2.4 Počet pracovních nabídek

Obdobně jako při zjišťování oblíbenosti v diskuzních fórech lze i tento faktor relativně jed-

noduše porovnat zadáním dotazu do vyhledávače některého z inzertních serverů. Za předpo-

kladu, že nabídky inzerovaných pracovních pozic odpovídají skutečnosti, může výsledek

porovnání na základě tohoto parametru velmi dobře poukázat na relativní oblíbenost v rámci

daného regionu.

3.3 Kritéria pro porovnání

V nadcházející kapitole jsou popsána kritéria, na základě kterých budou jednotlivé frame-

worky porovnány. Volba kritérií vychází jednak z vlastní zkušenosti autora a jednak z prací

podobného charakteru, zejm. pak z (Křižan, 2010).

3.3.1 Technické požadavky frameworku

S ohledem na skutečnost, že každý framework definuje vlastní systémové požadavky pro

jeho nasazení, jsou v tomto bodě shrnuty požadavky deklarované jeho autory. Je pravidlem,

že kromě základního požadavku, kterým je určitá verze PHP, bývá doporučováno či přímo

vyžadováno i specifické nastavení běhového (angl. runtime) prostředí (např. pomocí PHP

direktiv či aktivací některých rozšíření).

3.3.2 Autoloading tříd

Autoloading je mechanismus umožňující dodatečné nahrávání zdrojových souborů, typicky

obsahující deklarace tříd a rozhraní, až v případě jejich prvního použití. V PHP pro registraci

tzv. autoloaderů (což jsou objekty, které samotný proces provádí) slouží funkce

Page 19: Bachelor Thesis

3 PHP frameworky 11

spl_autoload_register10. Existuje několik přístupů, jakým lze autoloading automatizovat

a proto jsou stručně charakterizovány jednotlivé přístupy všech tří frameworků.

Specifickým často využívaným přístupem je standard PSR-0. Pro účely práce je důležité

zmínit, že PSR-0 vychází z přesně definovaných konvencí, kde struktura zdrojových sou-

borů v rámci adresářové struktury musí reflektovat názvy jmenných prostorů, ve kterých

jsou deklarovány. Přesné podmínky jsou definovány v (PHP Framework Interoperability

Group, 2013).

3.3.3 MVC

Nativní podpora architektury MVC je považována za jeden ze základních požadavků vůbec

a jeho (ne)naplnění je předmětem první porovnávané oblasti. V rámci srovnání je charakte-

rizován tzv. „životní cyklus“ aplikace vytvořené v daném frameworku a možnosti obsluhy

serverových požadavků. Snahou je rovněž identifikovat případně konvence, které frame-

work v souvislosti s tímto vzorem zavádí.

3.3.4 DI (Dependency Injection)

„Dependency Injection je jedním z nejvíce nepochopených konceptů objektově-

orientovaného programování“ (Seemann, Putting Dependency Injection on the map, 2012),

přitom se nejedná o nic jiného, než pojmenování jedné ze základních technik „čistého“

objektově-orientovaného návrhu. Důsledné respektování tohoto paradigmatu znamená při-

způsobení definic tříd, potažmo jejich API, přesvědčení, že každá vnější závislost musí být

objektu předána skrze jeho veřejné rozhraní. „Dependency Injection je souhrnem principů

a návrhových vzorů softwarového návrhu, které umožňují vytvářet kód, který není těsně

svázaný11“ (Seemann, A Dependency Injection tasting menu, 2012).

Z praktického hlediska porozumění principu DI znamená, že výsledný kód navržených tříd

neobsahuje žádné12 skryté závislosti a vše, co třída ke své funkčnosti potřebuje, jí je předáno

z vnějšku, tzn., „že objekty mohou mezi sebou prostřednictvím přesně daných vazeb

navzájem komunikovat s minimální znalostí sebe navzájem“ (Freeman, Freeman, Sierra, &

Bates, 2004). Kód se proto stává relativně udržitelnějším, znovupoužitelným a lépe testova-

telným.

10 http://www.php.net/manual/en/function.spl-autoload-register.php

11 Z angl. tight coupling.

12 V praxi nemusí být tento idealistický stav reálně dosažitelný (např. používání nativních

funkcí apod.), případně není z nejrůznějších důvodů žádoucí.

Page 20: Bachelor Thesis

3 PHP frameworky 12

Na základě (Fowler, Inversion of Control Containers and the Dependency Injection pattern,

2004) a (Seemann, DI patterns, 2012) lze rozlišit 3 základní techniky DI:

Constructor Injection – injektáž závislostí za pomocí konstruktoru,

Property Injection – injektáž závislostí změnou hodnoty veřejné vlastnosti třídy,

Method Injection – injektáž skrze veřejnou metodu třídy.

Relativní výhody a nevýhody těchto přístupů demonstruje (Grudl, DI a předávání závislostí,

2012), kdy zároveň poukazuje na problémy spojené s DI v prostředí jazyka PHP.

V souvislosti s DI bývají rovněž často skloňovány pojmy, jako jsou Inversion of Control

(IOC) a DI Container (DI kontejner) a není překvapením, že s DI velmi úzce souvisí. První

z termínů (IOC) pouze vyzdvihuje samotný princip DI a „znamená, že objekty, na kterých

objekt závisí, nejsou vytvářeny tímto objektem“, nýbrž je tato činnost přenechána objektům

jiným tzn., že „jsou tyto objekty získávány z vnějšího zdroje“ (Eini, 2006). Prostředkem

umožňujícím tento proces do určité míry zautomatizovat13 je právě DI kontejner, jehož

hlavní funkcí je obstarat vytváření instancí tříd „na jednom místě“. Toho je dosaženo často

automatickým sestavením stromu závislostí, které DI kontejner dokáže rozpoznat na základě

jeho vstupní konfigurace. (Kutišová, 2013)

Cílem srovnání frameworků v pokrytí této oblasti je:

a) obecné dodržování DI principu,

b) existence/podpora DI kontejneru (zdali jej framework obsahuje či nikoliv, v jaké po-

době a jaké možnosti konfigurace nabízí).

3.3.5 Komponentový vývoj

Hlavní myšlenkou komponentového vývoje je snaha o redukci stále se opakujícího se kódu

a znuvupoužitelnost určitých součástí aplikace, což ostatně koresponduje se smyslem frame-

worku. Proto je tento faktor zohledněn a v práci je porovnávána jeho inherentní podpora

ze strany frameworku. „Komponenty jsou relativně malé a nezávislé části určitého

systému.“ (Bose) Filosofie vychází z přesvědčení, že systém by měl být tvořen pokud možno

z existujících komponent, za účelem zrychlení vývoje a snížení nákladů.

V případě, že žádnou relevantní komponentu nelze použít, je nutné ji vytvořit a to buď vlast-

ními silami, či externě. Jelikož je jazyk PHP volně šiřitelný (tzv. open-source) a zároveň

13 Záleží na konkrétní implementaci DI kontejneru a případně na možnostech jazyka.

Page 21: Bachelor Thesis

3 PHP frameworky 13

interpretovaný, mohou často vývojáři využít komponent vytvořených někým jiným a even-

tuálně si je za určitých podmínek přizpůsobit k použití ve vlastních projektech (záleží

na licenčních podmínkách, v zásadě je to ale technicky možné).

Z hlediska porovnání frameworků v této oblasti je cílem zjistit, zda obsahují předpřipravené

třídy, které umožní tvorbu znovupoužitelných komponent a zdali framework sám je sestaven

z relativně nahraditelných komponent.

3.3.6 Šablonový systém

PHP je ze své podstaty jazyk určený pro tvorbu šablon, vkládáním PHP kódu lze docílit

dynamicky generovaného HTML výstupu. Tento způsob14 - kombinace psaní „business

logiky“ a kódu pro vygenerování výstupu - je sice relativně snadný, na druhou stranu je však

ve většině případů nevhodný a dnes již může být považován za zastaralý. Klasický přístup

v zásadě nekoresponduje s rozdělením rolí v MVC architektuře, kde vrstva pohled je rela-

tivně izolována od vrstev ostatních a její zodpovědností je prezentace dat.

Ukazuje se však, že samotná separace sice přináší některé výhody, stále je však kodér nucen

psát čisté PHP, což znamená, že tvůrce šablony musí zároveň kromě značkovacích jazyků

(X)HTML znát i jazyk PHP, což sebou může přinést i některá bezpečností rizika. Navíc,

„míchání“ čistého PHP kódu a HTML, má za následek znepřehlednění obsahu šablony (ne-

týká se výstupu). Za účelem odstranění těchto a dalších nedokonalostí jazyka, případně jeho

rozšířením, vznikla řada speciálních šablonových systémů.

Smyslem šablonového systému je tedy odstínění kodéra od „nedokonalostí“ jazyka, zvýšení

bezpečnosti a v neposlední řadě zpřehlednění kódu šablony. Často je jejich implementace

koncipována jako rozšíření původního jazyka, přičemž výsledná syntaxe je napříč většinou

systémů prakticky totožná. Odhlédneme-li od faktu, že tvůrce šablon musí navzdory oddě-

lení od ostatních částí aplikace znát přinejmenším strukturu vstupních parametrů šablony,

stává se výsledný kód relativně přehlednějším a udržitelnějším.

Mezi typické znaky šablonového systému patří:

1. práce s proměnnými (deklarace, přiřazování hodnot, výpis, „escapování“15),

2. if konstrukce a cykly (s dodatečnými rozšířeními),

3. pomocné funkce (tzv. „helpery“),

4. vkládání/skládání/dědičnost šablon,

14 Dále označován jako „klasický“ způsob.

15 Jedná se o techniku nahrazování určitých znaků za znaky tzv. „bezpečné“, případně způ-

sob, jak předejít jejich chybné intepretaci.

Page 22: Bachelor Thesis

3 PHP frameworky 14

5. podpora lokalizace.

Porovnání je realizováno s přihlédnutím k těmto vlastnostem, srovnány jsou i možnosti zá-

měny „nativního“ šablonového systému frameworku za jiný. Cílem porovnání je rovněž

identifikovat specifické rozdíly v možnostech šablonových jazyků.

3.3.7 Formuláře

Vývoj webových aplikací obnáší nejen generování určitého výstupu uživateli prostřednic-

tvím HTML na straně jedné, nýbrž nutně zahrnuje i problematiku zpracování dat získaných

od uživatele. Jedním z mechanismů, který vznikl z důvodu nutnosti data od uživatelů nejen

zobrazovat ale pochopitelně i získávat, jsou právě HTML formuláře. (Kosek, 1999)

V rámci srovnání možností generování HTML formulářů v jednotlivých frameworcích jsou

důležité následující aspekty:

1. Data, která chceme od uživatelů obdržet, mohou být různé povahy, resp. formátu.

2. Z důvodu konzistence a zajištění bezpečnosti je nutné data určitým způsobem vali-

dovat, přičemž složitost těchto validačních pravidel je odvislá od charakteru dat

a aplikační logiky, proto srovnání zahrnuje definici jak obvyklých pravidel tak i mož-

nost definice pravidel vlastních.

3. Charakterizován je způsob, jakým lze formuláře vytvářet a generovat výsledný

HTML kód (případně v souvislosti s používaným šablonovým systémem).

3.3.8 Session a Cookies

Prostředky session, resp. cookies slouží k překonání omezení protokolu HTTP, který je be-

zestavový tím, že onu „stavovost“ dokáží zajistit. (Shafik & Ramsey, 2007) V obecném

slova smyslu slouží cookies k ukládání stavových dat na straně klienta (angl. user agent),

přičemž jeho typickým představitelem je webový prohlížeč. Cookies se přenáší obousměrně,

k prvotnímu uložení, resp. odeslání cookie klientovi slouží HTTP hlavička Set-Cookie. Kli-

ent by tuto hlavičku měl umět zpracovat a následně při každém dalším požadavku spolu

s ostatními daty odesílat i právě tyto uložené cookies, které lze pak na straně serveru zpětně

zpracovat. (Internet Engineering Task Force, 2011)

Session se liší od cookies ve způsobu uložení stavových dat, která již nejsou ukládána

na straně klienta, nýbrž na straně serveru. Pro korektní spárování stavových dat s klientem

(např. uživatelem) je nutné zajistit přenos tzv. session ID, což je jednoznačný identifikátor

dané session, pomocí některého z dvou možných způsobů (The PHP Group, nedatováno):

Cookies – session ID je uloženo v samostatné cookie,

Page 23: Bachelor Thesis

3 PHP frameworky 15

URL parametr – session ID se přenáší prostřednictvím URL jako hodnota speciál-

ního parametru.

Jazyk PHP podporuje přímou práci s daty uloženými jak v session, tak i cookies. Jelikož

potřeba zaznamenání a udržení určitých dat napříč několika HTTP požadavky vzniká velmi

často, je výhodné zvolit nějaký předem specifikovaný způsob pro práci s těmito daty (např.

za účelem odstínění vývojáře od nízko-úrovňových funkcí PHP, které se napříč různými

verzemi jazyka mohou potenciálně lišit).

Zásadní otázky pro srovnání frameworků jsou proto tyto:

1. Definuje framework nějaký unifikovaný způsob pro práci se session a cookies?

2. Liší se přístupy v práci se session/cookies v jednotlivých frameworcích? Případně

jak?

3.3.9 Databázová abstrakce

Pojem databáze lze v obecném měřítku definovat jako určitý uspořádaný soubor dat.

(Dictionary.com, nedatováno) V praxi se však tímto pojmem často míní některý z relačních

databázových16 systémů. V kontextu jazyka PHP se často jedná o volně šiřitelný systém

MySQL, ke kterému lze přistupovat pomocí nativních PHP funkcí. Existence celé řady dal-

ších alternativních databázových systémů (rovněž vycházejících z jazyka SQL), které mo-

hou zároveň mít svá jistá specifika, jsou jednou z příčin pro zavedení další vrstvy pro práci

s databází.

Smyslem databázové abstrakce je odstínění vývojáře od implementačně závislých vlastností

konkrétního databázového systému. Za předpokladu, že vývojář chce tvořit databázově re-

lativně nezávislou aplikaci, pak pravděpodobně bude zvažovat zavedení některé z abstrakč-

ních vrstev, které frameworky zpravidla poskytují. Databázová abstrakce by celkově mj.

měla přinést ulehčení práce vývojáři např. usnadněním zápisu databázových dotazů prostřed-

nictvím objektově orientovaného API. (Křižan, 2010)

Otázky pro porovnání:

1. Pro jaké databázové systémy existuje ze strany frameworku nativní podpora?

16 Dále se pod pojmem databázový systém míní databázový systém relační založený na ja-

zyku SQL.

Page 24: Bachelor Thesis

3 PHP frameworky 16

2. Obsahuje vrstva databázové abstrakce kromě API souvisejícího s manipulací dat

(DML – Data Manipulation Language) tak i API pro popis/definici jejich struktury

(DDL – Data Definition Danguage)?

3. Je možné vykonané SQL příkazy logovat17?

Srovnání frameworků zahrnuje i hrubé otestování rychlosti databázové vrstvy, jehož zadání

je blíže popsáno na straně 21.

3.3.10 Autorizace, autentizace

Dalším problémem, se kterým je nutné se během vývoje webových aplikací určitým způso-

bem „vypořádat“, je otázka zabezpečení, neboli ověřování totožnosti uživatele (autenti-

zace) a řízení přístupu k různým částem aplikace (autorizace). Obě části spolu úzce

souvisí, protože v závislosti na autentizaci uživatele dochází zároveň k ověření, zdali je pří-

stup k danému zdroji18 autorizován. Stejně tak se lze setkat s modelovou situací, kdy je

uplatňován reverzní přístup - uživateli, který nemá dostatečná oprávnění (např. není přihlá-

šen), je nabídnuta možnost, jak dané oprávnění nabýt (např. přihlášením do systému).

Otázky pro srovnání:

1. Jaké možnosti framework z pohledu potřeby autorizace a autentizace uživatelů na-

bízí?

2. Obsahuje framework nějakou konkrétní implementaci pro řízení přístupu (známého

též pod zkratkou ACL - Access Control List)?

3. Na základě čeho je konkrétní uživatel (spojený s aktuální session) identifikován?

4. Je dobrým zvykem, že hesla uživatelů nejsou z bezpečnostních důvodů ukládána

ve své původní podobě, ale jako „zahešované“ (angl. hashed) řetězce znaků. Nabízí

framework nějaký vlastní sjednocený způsob hešování?

17 Viz kapitola 3.3.13.

18 Zdrojem se míní jakákoliv obecná součást aplikace (např. komponenta, stránka, apod.).

Page 25: Bachelor Thesis

3 PHP frameworky 17

3.3.11 Lokalizace

Základem dobře navrženého frameworku umožňující jeho široké použití je jeho dostatečná19

obecnost. Mezi znaky široce použitelného frameworku lze zařadit podporu lokalizace, neboli

„proces překladu aplikačních zdrojů do lokalizovaných verzí pro každou z aplikačně

podporovaných kultur“ (Microsoft, 2014). V nejjednodušších případech se jedná pouze

o zajištění toho, že veškeré zprávy, které jsou (nebo mohou být) uživateli zobrazovány jsou

přeloženy do jednotlivých jazyků.

Bohužel, lokalizace v ideálním případě obnáší vyřešení několika specifických problémů da-

ných rozlišností světových kultur a jazyků. Jejich široká rozmanitost staví autory frame-

worku před poměrně složitý úkol, jehož cílem je to, aby výstup aplikace byl v souladu

s regionálními rozlišnostmi. Ukazuje se, že někdy je framework koncipován tak, že podpora

pro lokalizaci ve frameworku je, avšak jeho konkrétní implementace je ponechána na vývo-

jáři.

Otázky pro srovnání:

1. Disponuje framework zabudovanými lokalizačními prostředky?

2. Umožňuje framework definovat vlastní lokalizační prostředky?

3. Které součásti frameworku jsou „lokalizovatelné“?

3.3.12 Využití cache

Cache je „dočasné datové úložiště. Je to druh paměti, který představuje jednoduchý

a efektivní způsob jak zvýšit výkon webových aplikací – díky ukládání relativně statických

dat do cache a jejich načítání z cache, když jsou vyžadována, se šetří čas i výkon jinak nutný

k jejich opakovanému generování nebo získání z originálního úložiště“. (Křižan, 2010)

Použití cache zahrnuje transformační proces určitého kódu do takové podoby, pro kterou

platí předpoklad, že je efektivnější, než kód původní. Z pohledu přistoupení k využívání

cache nelze z určitostí říci, kdy se již cache „vyplatí“ a kdy ji lze považovat za „zbytečnou“.

Z pohledu PHP frameworků lze pak využít některých již implementačně zvládnutých řešení,

které byly vytvořeny za účelem usnadnění práce s cache a odstíněním vývojáře od konkrét-

ních vnitřních implementačních detailů cache (vývojář pracuje pouze s její API).

19 Vždy záleží na konkrétních požadavcích, zda lze framework považovat za dostatečně

obecný, tzn. případ od případu.

Page 26: Bachelor Thesis

3 PHP frameworky 18

Otázky pro srovnání:

1. Nabízí framework možnost používat cache?

2. Umožňuje framework měnit/přidávat vlastní úložiště pro data v cache?

3. Jakým způsobem lze cache invalidovat (zneplatnit)?

3.3.13 Ladění a zpracování chyb

Princip a cíl procesu ladění lze charakterizovat jako snahu o odhalení existujících či poten-

ciálních chyb programu (v prostředí jazyka PHP je jím skript). Fakt, že PHP je jazyk inter-

pretovaný, může vést k relativně větší chybovosti (velkou mírou se na ní mohou podílet

zejména chyby formálního charakteru – překlepy apod.), protože veškeré chyby se mohou

projevit až za běhu skriptu. Proto je snahou frameworku proces ladění (angl. debugging)

vývojáři usnadnit a zefektivnit.

PHP obsahuje sadu vestavěných funkcí20, které slouží pro zpracování chyb (angl. errors)

a výjimek (angl. exceptions). Framework zpravidla vytváří nadstavbu nad těmito funkcemi

a přidává další přidanou hodnotu tím, že chybové stavy dokáže např. relativně přehledně

vizualizovat.

V souvislosti nejen s laděním, ale i praktickým provozem webových aplikací je velmi často

žádoucí zachycovat určité stavy (nemusí se jednat pouze o stavy chybové) zavedením tzv.

„logování“ (angl. logging), čímž je možné zachycovaná data zpětně analyzovat. (Lecky-

Thompson, Nowicki, & Myer, 2009) PHP opět nabízí nativní funkci pro jednoduchou práci

s chybovým logem21, jejíž použití ale nemusí z různých důvodů postačovat (např. nedosta-

tečná strukturovanost a nepřehlednost).

Otázky pro srovnání:

1. Jakým způsobem ve frameworku probíhá zpracování, resp. zachycení chybových

stavů (errors/exceptions)?

2. Obsahuje framework nějaký vizualizační nástroj určený k ladění?

3. Umožňuje framework nějaký druh nadstavbového logování?

20 http://cz2.php.net/manual/en/ref.errorfunc.php

21 Jedná se o vestavěnou funkci error_log (http://cz2.php.net/manual/en/function.error-

log.php).

Page 27: Bachelor Thesis

3 PHP frameworky 19

3.3.14 Rychlost

Celkové zpracování požadavku

Objektivně porovnávat rychlost frameworku je obtížné, protože výsledky může ovlivnit

mnoho faktorů. Srovnání je provedeno na základě vytvoření jednoduché aplikace v každém

z frameworků. Její realizace je koncipována tak, aby verze vytvořená v jednom z nich (co se

týče funkcionality) byla ekvivalentní vůči ostatním.

Aplikace spočívá ve vytvoření tří stránek sloužících pro výpis jednoduché databáze knih:

1. Vytvoření domovské stránky obsahující odkaz na seznam knih.

2. Stránka se seznamem všech knih s možností zobrazit detaily.

3. Stránka s podrobnostmi o knize.

Modelová část aplikace je sdílená napříč všemi mutacemi aplikace. Jako zdroj databáze knih

slouží XML soubor Books.xml, který obsahuje celkem 5 knih (element //book/book). Pro zís-

kání kolekce všech knih či vyhledání jediné (dle jejího ID) je primárně určena fasáda22

JR\FrameworkComparison\Model\Facades\BookFacade.

V rámci srovnání bude pro každou stránku měřen celkový čas obsloužení skriptu (případné

nepodstatné části budou přeskočeny) a množství maximální alokované paměti. Výsledky

jsou přes pomocnou třídu JR\FrameworkComparison\Utils\Logger logovány do souboru

timelog.csv. Pro měření rychlosti bude použit nástroj

Nette\Diagnostics\Debugger::timer($name = NULL).

Měření bude provedeno dvojfázově:

1) „Caching fáze“ – slouží k odlišení vlivu použití cache, v rámci frameworku Nette je

abstrahováno od doby nutné k prvotní indexaci souborového systému (RobotLoader);

u frameworku Zend je tato fáze vynechána, protože se žádná cache nevyužívá;

2) „Cached fáze“ – v této fázi se předpokládá, že veškerá cache je již uložena a tudíž

by nemělo napříč měřeními docházet k významnějším časovým rozdílům.

Na každou stránku a fázi připadá celkem 10 měření (s výjimkou Zend, kde první fáze bude

vynechána), celkem tedy proběhne 50 měření. Výsledky v každé části jsou zprůměrovány

a následně interpretovány. Prostředí, ve kterém je měření prováděno, uvádí Tabulka 1.

22 Zjednodušující obalová třída pro práci s „nízko-úrovňovým“ nebo složitým API dalších

tříd a rozhraní, viz pojem Fasáda v terminologickém slovníku.

Page 28: Bachelor Thesis

3 PHP frameworky 20

Ačkoliv Nette je možné provozovat i v jeho tzv. „minifikované“ verzi (veškerý zdrojový

kód je umístěn v jediném optimalizovaném PHP souboru), bude pro měření použito jeho

standardní distribuce.

Tabulka 1: Běhové prostředí pro porovnání frameworků (Zdroj: autor)

Parametr Hodnota

Verze PHP 5.4.25

Webový server Apache/2.4.7 (Win32)

Operační systém Windown 8.1 Pro

Procesor Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz 2.29 GHz

Operační paměť 8.00 GB

Výkonnost PHP lze pozitivně ovlivnit nasazením tzv. akcelerátoru. Jedním z nich je rozší-

ření Zend OPcache, které zvyšuje rychlost PHP ukládáním předkompilovaného byte kódu

skriptů do sdílené paměti. To má v optimálním případě za následek zkrácení doby nutné

pro načtení jednotlivých skriptů odstraněním nutnosti jejich opětovné rekompilace při kaž-

dém požadavku. (The PHP Group, 2014)

Pro ověření výše uvedeného předpokladu bude sloužit další blok měření sestávající se do-

hromady z dalších 50 samostatných měření. Podmínky a způsob měření vycházejí z popisu

výše s tím rozdílem, že navíc bude aktivováno Zend OPcache rozšíření, jehož vstupní kon-

figuraci zachycuje následující tabulka (všechny ostatní parametry nabývají výchozích hod-

not).

Page 29: Bachelor Thesis

3 PHP frameworky 21

Tabulka 2: Nastavení Zend OPcache rozšíření (Zdroj: autor)

Parametr Hodnota

Verze rozšíření opcache-7.0.3-5.4-ts-vc9-x8623

opcache.enable 1

opcache.memory_consumption 300

opcache.interned_strings_buffer 8

opcache.max_accelerated_files 8000

opcache.fast_shutdown 1

opcache.enable_cli 1

opcache.use_cwd 1

Přesný význam všech konfiguračních direktiv popisuje (The PHP Group, 2014).

Výkonnost databázové vrstvy

Pro srovnání rychlosti a paměťové náročnosti databázové vrstvy proběhne podobně jako

v předchozím případě sada měření, které jsou zaměřeny na zjištění výkonnosti:

1. Získání všech záznamů z tabulky,

2. Získání jednoho konkrétního záznamu z tabulky (na základě jeho ID).

Pro lepší vypovídací hodnotu bude měřen pouze čas související se samotným položením

dotazu a získáním výsledku. Zdrojovým databázovým systémem je MySQL, pro který exis-

tuje podpora ve všech třech frameworcích. Struktura dat (seznamu knih) odpovídá tabulce

book, jak je uvedeno ve výpisu 1. Rozlišen bude vliv akcelerátoru a způsob tvorby dotazu:

1. Manuální tvorba dotazu (zpravidla jediný příkaz, resp. metoda),

2. Postupné skládání dotazu (objektově orientovaný způsob konstrukce dotazu).

Pro účely měření výkonnosti 2. způsobu bude u frameworku Phalcon použito jeho „vysoko-

úrovňového“ jazyka PHQL. Důvodem je ověření, zda i přes jistou míru jeho specifičnosti24,

dosáhne lepších výsledků než Zend nebo Nette.

23 Dostupné z http://windows.php.net/downloads/pecl/releases/opcache/7.0.3/.

24 Tím, že daný dotazovací jazyk je již přímo propojen s určitým modelem a nelze jej použít

nezávisle na něm.

Page 30: Bachelor Thesis

3 PHP frameworky 22

Výpis 1: Struktura zdrojové tabulky book (Zdroj: autor)

CREATE TABLE `book` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `author` varchar(255) NOT NULL, `date_published` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 INSERT INTO `book` (`id`, `name`, `author`, `date_published`) VALUES (1, 'Inferno', 'Dan Brown', '2013-05-14'), (2, 'A Game of Thrones', 'George R.R. Martin', '2003-01-01'), (3, 'World War Z', 'Max Brooks', '2006-09-12'), (4, 'Bad Monkey', 'Carl Hiaasen', '2013-06-11'), (5, 'Into the Wild', 'Jon Krakauer', '1997-01-20'), (6, 'My book', 'John Doe', '2014-05-08');

3.3.15 Ostatní

Mezi další vlastnosti, které lze u každého frameworku identifikovat a do jisté míry porovná-

vat, patří kromě faktorů technického charakteru rovněž řada socioekonomických, jako jsou:

licenční podmínky užití,

dokumentace,

komunita spojená s frameworkem,

existující rozšíření,

atd.

Page 31: Bachelor Thesis

4 Porovnání PHP frameworků 23

4 Porovnání PHP frameworků Náplní následující části práce je porovnání konkrétních tří vybraných frameworků:

1) Zend Framework 2.3,

2) Nette 2.1.2,

3) Phalcon 1.3.1.

Cílem je nabídnout čtenáři celkový přehled o možnostech těchto frameworků za účelem

identifikace případných rozdílů ve způsobech jejich použití apod., přičemž popis vychází

z kritérií a otázek definovaných v předchozí části.

Výchozí předpoklady porovnání znázorňuje Tabulka 3.

Tabulka 3: Výchozí předpoklady pro porovnání frameworků (Zdroj: autor)

Zend Framework 225 Nette Phalcon

Verze 2.3 2.1.2 1.3.1

Oficiální webové

stránky

http://frame-

work.zend.com

http://nette.org/ http://phal-

conphp.com

4.1 Technické požadavky frameworku

4.1.1 Zend

Dle (Weier O'Phinney, 2014) nejsou explicitně požadovány žádné speciální požadavky, je-

diným výchozím požadavkem je stanovení minimální verze PHP 5.3.23, která musí být

na webovém serveru nainstalována.

4.1.2 Nette

Framework Nette vyžaduje minimální verzi PHP alespoň 5.3.1. Na rozdíl od ostatních fra-

meworků disponuje speciálním nástrojem „Requirements Checker“, který slouží ke kon-

trole splnění dalších specifických požadavků kladených frameworkem. Nástroj je součástí

standardní distribuce frameworku a jeho smyslem je ověření, že běhové prostředí serveru

25 Dále je již uváděn pouze zkrácený název Zend.

Page 32: Bachelor Thesis

4 Porovnání PHP frameworků 24

splňuje všechny požadavky. Zároveň platí, že nesplnění některého z nich neznamená kom-

pletní nefunkčnost frameworku, nýbrž např. pouze určité části či rozšíření. Výstupem je ta-

bulkové zobrazení jednotlivých kritérií s případným rozšiřujícím popisem. (Nette

Foundation, 2014)

4.1.3 Phalcon

Framework Phalcon stejně jako Nette vyžaduje minimální verzi PHP 5.3.1. Distribuce fra-

meworku je realizována v porovnání s jinými frameworky jako rozšíření prostředí PHP for-

mou zvláštní knihovny. To znamená, že zdrojový kód je napsaný přímo v jazyce C, a proto

v zásadě existují dvě možnosti, jak balíček nainstalovat:

a) stažení zkompilovaného binární balíčku pro Windows,

b) stažení a následné zkompilování balíčku přímo pro konkrétní Linux distribuci.

Pro jeho následné zprovoznění je nutné balíček aktivovat patřičnou úpravou hlavního kon-

figuračního souboru PHP php.ini, která spočívá v přidání následujícího řádku (název kni-

hovny se může lišit v závislosti na platformě), viz Výpis 2.

Výpis 2: Aktivace Phalcon DDL rozšíření (Zdroj: (Phalcon Team and contributors, 2014))

extension=php_phalcon.dll

Na druhou stranu, přestože instalace v zásadě složitá není, faktické zprovoznění frameworku

obnáší změnu konfigurace PHP. Proto mohou být možnosti jeho reálného nasazení zásadním

způsobem omezeny, zejm. má-li dojít k jeho nasazení na některém ze sdílených webhostin-

gových prostředí, které nemá vývojář „přímo pod svoji kontrolou“.

4.2 Autoloading tříd

4.2.1 Zend

Zend obsahuje čtyři druhy autoloaderů (jmenný prostor Zend\Loader):

StandardAutoloader – vychází ze standardu PSR-0,

ClassMapAutoloader – předpokládá namapování tříd na patřičné zdrojové soubory,

pro zautomatizování lze využít speciální nástroj, který je součástí frameworku

a dokáže mapu vygenerovat procházením adresářové struktury (manuálně),

Page 33: Bachelor Thesis

4 Porovnání PHP frameworků 25

ModuleAutoloader – určen pro nahrávání modulů (dokáže zpracovat i komprimované

archivy) (Zend Technologies Ltd., 2014),

PluginClassLoader – umožňuje tvorbu tzv. aliasů, čili zástupných názvů rozhraní

a tříd.

4.2.2 Nette

Nejdůležitější komponentou pro automatické nahrávání tříd, potažmo rozhraní je třída

Nette\Loades\RobotLoader. Framework rovněž obsahuje speciální autoloader

Nette\Loaders\NetteLoader, který jako zdroj interně používá pole s definicemi názvů tříd

a cest k příslušným zdrojovým souborům a primárně je určen pouze pro nahrávání frame-

workových komponent.

Princip fungování RobotLoaderu je originální, protože se chová podobně jako vyhledávací

robot (tzv. crawler), který rekurzivně prochází strukturu webu za účelem indexace obsahu.

RobotLoader obdobně prochází strukturu souborového systému a pro jakoukoliv nalezenou

třídu a rozhraní si „zapamatuje“ cestu ke zdrojovému souboru, ve kterém se daná deklarace

nachází. Pro svoji funkčnost RobotLoader vyžaduje specifikaci typu cache úložiště a regis-

traci daných adresářů, ve kterých se nalézají zdrojové soubory, které mají byt indexovány.

(Nette Foundation, 2014). Samozřejmě, že doba prvotního vybudování (adresáře se prochází

rekurzivně), resp. obnova cache je přímo úměrná množství a velikosti souborů, které musí

při indexaci analyzovat.

V případě potřeby lze RobotLoaderu indexaci určitých adresářů i zakázat, což může celko-

vou dobu analýzy v závislosti na konkrétních podmínkách značně zkrátit (zejména pokud se

jedná např. o produkty 3. stran, které mají již vlastní systém autoloadingu). RobotLoader

pro zajištění konzistence vyžaduje jednoznačnost deklarace tříd a rozhraní, pokud při inde-

xaci zjistí deklaraci již zaindexované třídy/rozhraní, vyvolá výjimku.

Výpis 3: RobotLoader - zakázání indexace adresáře (Zdroj: (Nette Foundation, 2014))

# soubor netterobots.txt # zakáže indexaci adresáře /Zend Disallow: /Zend

4.2.3 Phalcon

Autoloader Phalcon reprezentovaný třídou Phalcon\Loader sdružuje hned několik

autoloadingových strategií (seřazeno podle priority) (Phalcon Team and contributors, 2014):

Page 34: Bachelor Thesis

4 Porovnání PHP frameworků 26

1. registrace tříd – nejvýřečnější metoda – každá třída má přiřazenu cestu ke zdrojo-

vému souboru,

2. registrace jmenných prostorů – obdoba PSR-0, ke jmenným prostorům jsou přiřa-

zeny adresáře (1:1), ve kterých se dané třídy, resp. rozhraní nachází,

3. registrace prefixů – obdoba předchozího způsobu s tím rozdílem, že názvy jmen-

ných prostorů jsou odděleny podtržítkem,

4. registrace adresářů – relativně nejnáročnější metoda, protože se daná třída/rozhraní

vyhledává postupně ve všech zaregistrovaných adresářích, zároveň se při prohledá-

vání nahraje první nalezený soubor.

4.3 MVC

4.3.1 Zend

Framework Zend obsahuje řadu rozhraní a tříd zastřešující proces zpracování požadavku

a vrácení odpovědi, které jsou umístěny ve jmenném prostoru Zend\Mvc. Pro obsloužení po-

žadavku slouží rozhraní Zend\Mvc\ApplicationInterface. Smyslem třídy implementující toto

rozhraní je zapouzdření vnitřní logiky životního cyklu aplikace a poskytnout tak vývojáři

možnost jejího přizpůsobení dle konkrétních požadavků.

Jelikož proces obsloužení lze relativně dobře zobecnit, poskytuje framework (stejně jako

frameworky ostatní) jeho základní implementaci, kterou představuje třída

Zend\Mvc\Application26. Třída z principu její interní logiky vyžaduje předání aplikační kon-

figurace a instanci třídy Zend\ServiceManager\ServiceManager, která je základní implemen-

tací návrhového vzoru service locator. Objekt typu service locator zajišťuje získávání

instancí dalších objektů, v tomto konkrétním případě však za cenu ztráty celkové

„průhlednosti“.

Reálné použití výchozí aplikační třídy (za určitých podmínek) tedy předpokládá implicitní

znalost vnitřní implementace, jelikož servisní třída musí poskytovat následující služby

(Introduction to the MVC Layer, 2014):

1. Zend\EventManager\EventManager – Zend je událostmi řízený („event driven”) frame-

work, z důležitých funkcí, která tato třída zajišťuje lze zmínit:

26 Dále jen jako tzv. aplikační třída.

Page 35: Bachelor Thesis

4 Porovnání PHP frameworků 27

a. Připojování (metoda attach) a odpojování (metoda detach) tzv. posluchačů

(angl. listeners).

b. Spouštění událostí (metoda trigger), včetně možnosti definovat za jaké pod-

mínky lze událost vyvolávat (metoda triggerUntil).

2. Zend\ModuleManager\ModuleManager – jelikož Zend vychází z principu, že aplikace by

měla být složena ze samostatných modulů, definuje pro jejich inicializaci rozhraní

Zend\ModuleManager\ModuleManagerInterface, jehož základní implementaci předsta-

vuje právě tato třída,

3. Zend\Http\PhpEnvironment\Request – obalová třída příchozího HTTP požadavku,

4. Zend\Http\PhpEnvironment\Response – obalová třída pro HTTP odpověď aplikace.

Aplikační třída dále využívá řadu dalších pomocných komponent:

1. Zend\Mvc\RouteListener – zapouzdření tzv. „routovacího“ mechanismu, jehož úko-

lem je převedení HTTP požadavku na požadavek aplikační,

2. Zend\Mvc\DispatchListener – s využitím výstupu routování a dalších subkomponent

obaluje proces získání aplikačního požadavku a jeho obsloužení, tj. vrácení výstupu,

3. Zend\Mvc\View\ViewManager – komponenta zastřešující vrstvu pohled v MVC para-

digmatu (např. vytváření pohledu, registrace pomocných funkcí, apod.).

Z pohledu vývojáře je důležité, že tyto a další třídy zpravidla vždy implementují obecné

rozhraní stanovené frameworkem, čímž je dosaženo relativně širších možností, jak životní

cyklus v případě nutnosti upravit na základě specifických požadavků.

Způsobů, jak aplikační třídu použít, je v zásadě několik, v nejjednodušším případě spočívá

v zavolání statické metody Application::init, která provede inicializaci aplikace za použití

výchozích služeb, jak je znázorněno v následujícím výpisu:

Výpis 4: Ukázka nejjednodušší formy inicializace aplikační třídy Zend (Zdroj: (Zend

Technologies Ltd., 2014))

use Zend\Loader\AutoloaderFactory; use Zend\Mvc\Application; use Zend\Mvc\Service\ServiceManagerConfig; use Zend\ServiceManager\ServiceManager; // aktivace autoloaderu AutoloaderFactory::factory(); // získání konfigurace ze souboru $configuration = include 'config/application.config.php'; // inicializace a spuštění aplikace

Page 36: Bachelor Thesis

4 Porovnání PHP frameworků 28

Application::init($configuration)->run();

Routování

„Routování reprezentuje akci párování HTTP požadavku na požadavek aplikační“ (Zend

Technologies Ltd., 2014), což prakticky vzato znamená, že dojde k analýze URI (Uniform

Resource Identifier) adresy a na základě stanovených kritérií či vzorů je možné určit cílový

řadič aplikace, který požadavek zpracuje.

Zend obsahuje dvě výchozí implementace aplikačního routeru (Zend Technologies Ltd.,

2014):

1. Zend\Mvc\Router\SimpleRouteStack,

2. Zend\Mvc\Router\Http\TreeRouteStack.

Obě třídy implementují rozhraní Zend\Mvc\Router\RouteInterface, které definuje jednak to-

vární metodu RouteInterface::factory pro vytváření instancí jednotlivých route, metodu

pro ověření zda předaný požadavek (objekt typu Zend\Stdlib\RequestInterface) odpovídá

pravidlům dané route (RouteInterface::match(Request $request)) a metodu pro zpětnou

konstrukci URI adresy (RouteInterface::assemble(array $params = array(), array

$options = array())).

Párování route probíhá standardně (na rozdíl od frameworku Nette) metodou LIFO (Last In

First Out), proto je korektního chování dosaženo postupnou registrací route obecných násle-

dovaných specifičtějšími, případně využitím nepovinného parametru pro stanovení priority

route (reprezentováno číselnou hodnotou, kde vyšší hodnota znamená vyšší prioritu).

Framework Zend je specifický tím, že rovněž obsahuje sadu několika speciálních HTTP

route umístěných ve jmenném prostoru Zend\Mvc\Router\Http. Jejich smyslem je poskytnout

vývojáři snadný způsob jak vytvářet routovací pravidla na základě určité vybrané části pro-

tokolu HTTP. (Zend Technologies Ltd., 2014)

Framework umožňuje definici route pro spouštění aplikace v příkazové řádce (konzoli),

která je oddělená od route klasických, nicméně konkrétní specifikace možných voleb a tvaru

route je upravena tak, aby bylo možné zadávat poměrně jasné a přitom stručné příkazy, jak

ukazuje (Zend Technologies Ltd., 2014).

Řadiče

Vrstva řadič architektury MVC je podporována ze strany frameworku za pomoci

Zend\Mvc\Controller\AbstractActionController. Z obecného hlediska framework považuje

za řadič jakoukoliv třídu, která implementuje rozhraní Zend\Stdlib\DispatchableInterface,

Page 37: Bachelor Thesis

4 Porovnání PHP frameworků 29

které definuje jedinou metodu dispatch(Request $request, Response $response = null).

(Zend Technologies Ltd., 2014)

Pro usnadnění práce framework obsahuje další pomocné samostatné komponenty

(pluginy27), z nichž lze uvést několik příkladů (Zend Technologies Ltd., 2014):

Zend\Mvc\Controller\Plugin\Forward – umožňuje vyvolat akci jiného řadiče,

Zend\Mvc\Controller\Plugin\PostRedirectGet – přesměrování na danou URL či

akci,

Zend\Mvc\Controller\Plugin\Layout – umožňuje změnu výstupního rozvržení (angl.

layout) pohledu,

Zend\Mvc\Controller\Plugin\FlashMessenger – vytváření dočasně platných uživatel-

ských informačních zpráv, existují 4 možné typy zpráv, pro každou zprávu je defi-

nována zvláštní metoda.

Přidání uživatelsky definovaných pluginů je možné skrze konfiguraci aplikace. Vyvolání

funkcionality pluginu spočívá v zavolání metody AbstractController::plugin($pluginName,

array $options = null). Z důvodu zvýšení pohodlnosti je možné použít i zkrácený zápis,

protože třída implementuje magickou metodu __call, jak ukazuje Výpis 5. (Zend

Technologies Ltd., 2014)

Výpis 5: Možnost zkráceného zápisu volání služeb (Zdroj: autor)

// předpokládá volání uvnitř třídy řadiče $this->url();

4.3.2 Nette

Vývoj frameworku Nette se řídí několika obecnými principy, mezi nimiž je definování urči-

tých konvencí a jejich důsledné dodržování. Jejich znalost je ve výchozím stavu po vývojáři

dokonce vyžadována, což vede k relativně lepším návykům zkracující dobu vývoje a v ide-

álním případě i redukci chybovosti.

Obdobně jako framework Zend, Nette pro zapouzdření zpracování aplikační logiky používá

samostatnou třídu Nette\Application\Application28, která na rozdíl od frameworku Zend

neimplementuje žádné obecné rozhraní, nýbrž pouze dědí od základního společného předka

všech tříd frameworku Nette\Object. Díky tomu disponuje každá dědící třída schopností

27 Zásuvné moduly.

28 Dále uváděna pouze jako tzv. aplikační třída.

Page 38: Bachelor Thesis

4 Porovnání PHP frameworků 30

definice veřejných událostí, které lze pak snadno vyvolávat, jak ukazuje Výpis 6. Jednodu-

chosti je dosaženo zavedením konvence pro pojmenování událostí a možnostmi jazyka PHP,

konkrétně existencí magické metody __call.

Výpis 6: Deklarace a vyvolání události ve frameworku Nette (Zdroj: autor)

use Nette\Object; class Foo extends Object { public $onBar = array(); public function raiseBar() { $this->onBar($this, ‘foo’); } } $foo = new Foo(); $foo->onBar = function (Foo $fooObject, $str) { echo $str; }; $foo->raiseBar(); // vypíše: // foo

Závislosti aplikační třídy se sice v principu příliš neliší od těch uvedených v souvislosti s fra-

meworkem Zend, poznamenat lze však fakt, že závislosti jsou definovány průhlednějším

způsobem, protože aplikace pro svůj chod vyžaduje 4 konkrétní typy objektů implementující

stanovená rozhraní a nespoléhá se na jejich implicitní existenci uvnitř service locatoru.

Routování

Pro účely podpory routování je zavedeno obecné rozhraní Nette\Application\IRouter, jenž

definuje metody pro:

1) mapování HTTP požadavku na aplikační požadavek –

IRouter::match(Nette\Http\IRequest $httpRequest),

2) konverzi aplikačního požadavku na URL – IRouter::constructUrl(Request

$appRequest, Nette\Http\Url $refUrl).

Kromě zmíněných metod jsou dále definovány dvě konstanty, jejichž existence akcentuje

schopnost frameworku rozlišovat speciální typy route (Nette Foundation, 2014):

Page 39: Bachelor Thesis

4 Porovnání PHP frameworků 31

1) IRouter::ONE_WAY – routy označované tímto příznakem jsou jednosměrné v tom

smyslu, že aplikace provádí pouze mapování HTTP požadavku, nikoli však již re-

verzní generování URL,

2) IRouter::SECURED – slouží pro „vynucení“ používání zabezpečeného HTTPS proto-

kolu.

Framework kromě toho, že umožňuje zavedení vlastních uživatelsky definovaných routerů,

obsahuje rovněž několik základních implementací zmíněného rozhraní, jejich možnosti po-

užití se liší v závislosti na potřebách vývojáře a technických podmínkách, které jsou dány

provozním prostředím:

1. Nette\Application\Routers\SimpleRouter – nejjednodušší forma, která však neu-

možňuje generovat tzv. „cool“ adresy, na druhou stranu neklade žádné speciální po-

žadavky na cílové provozní prostředí,

2. Nette\Application\Routers\Route – pokročilá tvorba route, která umožňuje poměrně

přehledným způsobem definovat vstupní, resp. výstupní tvar URL adresy za použití

tzv. masek (např. výchozí hodnoty parametrů, validační výrazy, překlady, apod.);

na rozdíl od frameworku Zend lze masku za určitých podmínek definovat přehledně

a dostatečně konkrétně i bez nutnosti definovat každý parametr route zvlášť za po-

moci konfiguračního pole,

3. Nette\Application\Routers\RouteList – ve své podstatě nepředstavuje nic jiného,

než kolekci route Nette\Application\Routers\Route; v porovnání s frameworkem

Zend, jsou routy zpracovány FIFO (First In First Out) metodou,

4. Nette\Application\Routers\CliRouter – router pro zpracování požadavků (příkazů)

zadaných prostřednictvím příkazové řádky; dle (Nette Foundation, 2014) zatím ex-

perimentálního charakteru.

Řadiče

Architektura frameworku Nette vychází z modelu MVP, který je obdobou modelu MVC.

Pojem řadič je nahrazen pojmem presenter a jeho význam je dle (Frank, 2013) modifikovaný

tak, že oproti řadiči obstarává kromě aplikační i logiku prezentační. Pro zjednodušení je

presenter dále chápán jako ekvivalent řadiče. Z pohledu frameworku lze za řadič, resp. pre-

senter označit jakoukoliv třídu vycházející (dědící) z abstraktní třídy

Nette\Application\UI\Presenter (přesněji řečeno třídu implementující rozhraní

Nette\Application\IPresenter). (Nette Foundation, 2014)

Funkci presenteru lze demonstrovat znázorněním jeho životního cyklu, viz Obrázek 1.

Page 40: Bachelor Thesis

4 Porovnání PHP frameworků 32

Obrázek 1:

Životní cyklus Nette presenteru (Zdroj: (Nette Foundation, 2014))

Životní cyklus Presenteru (Nette Foundation, 2014):

1. startup() – metoda sloužící k inicializaci Presenteru, při jejím přepsání je vyžado-

váno zavolání její rodičovské verze,

2. action<NázevAkce>(…) – slouží k oddělení doménové logiky od vykreslovací části,

umožňuje např. přesměrování na jinou akci,

3. handle<NázevSignálu>(…) – obslužné metody pro tzv. signály; signál představuje

„komunikaci se serverem pod prahem normálního pohledu, tedy akce, které se dějí,

aniž by se změnil pohled“ (Nette Foundation, 2014),

4. beforeRender() – metoda volaná těsně před vykreslením vhodná např. pro úpravu

šablony pro více pohledů současně,

5. render<NázevAkce>(…) – metoda sloužící k úpravě pohledu, za jinak nezměněných

okolností dojde k vykreslení automaticky a proto v této fázi nejčastěji dochází pouze

k předání proměnných šabloně,

Page 41: Bachelor Thesis

4 Porovnání PHP frameworků 33

6. afterRender() – metoda volaná před konečným vykreslením pohledu – odesláním

aplikační odpovědi v textové podobě (chybí na obrázku),

7. shutdown($response) – ukončení běhu Presenteru.

Presenter obsahuje řadu pomocných metod, které slouží např. k přesměrování, vyvolání chy-

bového stavu, zasílání bleskových zpráv (angl. flash messages), aj. Na rozdíl od frameworku

Zend však tato funkcionalita není dána samostatnými pluginy, nýbrž jsou součástí API pre-

senteru. Požadované chování lze proto upravit jedině přepsáním konkrétní metody v dědící

třídě.

V rámci rozvoje frameworku, převládá poměrně značná tendence upouštět od používání

service locatoru, což se projevuje i tím, že další nutné služby, které presenter potřebuje

ke svému chodu, jsou mu transparentně předány v metodě Presenter::injectPrimary(…).

(Nette Foundation, 2014)

4.3.3 Phalcon

Základním kamenem MVC modelu ve frameworku Phalcon je aplikační třída

Phalcon\Mvc\Application, která „zapouzdřuje veškeré komplexní operace související

s vytvářením instancí všech potřebných komponent“ (Phalcon Team and contributors, 2014).

Toto tvrzení může vzbudit mylný dojem, že se v jedná o DI kontejner. Z hlediska třídní

hierarchie se jedná o potomka třídy Phalcon\DI\Injectable, což již naznačuje, že aplikační

třída je naopak speciální třídou, které lze vkládat/předávat vnější závislosti za pomoci me-

tody Phalcon\DI\InjectionAwareInterface::setDI(Phalcon\DiInterface

$dependencyInjector).

Z pohledu praktického použití jsou důležité následující metody:

1. Application::handle(string $uri = null) – metoda pro obsloužení příchozího po-

žadavku, která je obdobou metody Nette\Application\Application::run(), avšak

na rozdíl od ní, metoda vrací specifickou odpověď (instanci třídy) typu

Phalcon\Http\ResponseInterface; hodnotu takto získanou lze následně jednoduše

předat na standardní výstup,

2. Application::registerModules($modules, $merge = null) – funguje jako registrátor

modulů aplikace; framework tedy očekává jejich manuální registraci.

Routování

Stejně jako ostatní frameworky, Phalcon podporuje standardní proces routování za pomoci

rozhraní Phalcon\Mvc\RouterInterface. Zodpovědnost za správnou registraci jednotlivých

route je ponechána právě jemu a jeho výchozí implementací je třída Phalcon\Mvc\Router.

Routy jsou složeny z masek/vzorů, regulárních výrazů apod., jejichž zápis se nikterak příliš

Page 42: Bachelor Thesis

4 Porovnání PHP frameworků 34

neliší např. od frameworku Nette. Pro speciální případy užití umožňuje rozhraní kromě ji-

ného také omezit vstupní HTTP metodu na některou z hodnot definovaných tímto protoko-

lem, jak ukazuje dokumentační příklad (Phalcon Team and contributors, 2014).

Framework disponuje speciálním typem routeru Phalcon\Mvc\Router\Annotations, který

umožňuje definici tvaru route přímo v konkrétních třídách řadičů prostřednictvím tzv. ano-

tačních komentářů. Jedná se o vlastnost ojedinělou napříč porovnávanými frameworky, byť

ve výsledku může za určitých podmínek vést k paradoxnímu znepřehlednění aplikace29, pro-

tože routy již nejsou definovány na jednom místě, ale napříč několika soubory.

Řadiče

Vytváření instancí a volání příslušných akcí (angl. dispatching) provádí třída

Phalcon\Mvc\Dispatcher. Celý proces je cyklického charakteru a založený na událostech,

přičemž některé události jsou „zastavitelné“30. Zděděním třídy Phalcon\Mvc\Controller do-

jde k deklaraci nového řadiče a pro zpracování akcí jsou definovány příslušné metody, při-

čemž platí, že každá akce musí mít definovánu svoji metodu (rozdíl oproti Nette, kde metoda

reprezentující určitou akci nutně deklarována být nemusí). Názvy obslužných metod ve vý-

chozím stavu musí reflektovat stejnou konvenci jako v případě frameworku Zend, jak uka-

zuje Výpis 7.

Výpis 7: Konvence pro pojmenování akce řadiče (Zdroj: autor)

// <name> … název akce public function <name>Action() { … }

Z hierarchického hlediska je třída řadiče potomkem stejné třídy jako třída aplikační, čímž je

zajištěn jednotný způsob předávání externích závislostí prostřednictvím již zmíněné metody

InjectionAwareInterface::setDI($dependencyInjector). Používání této metody je však

svým způsobem rezignací na princip DI, protože třídě jsou takto předány ve skutečnosti

i závislosti, které vůbec nepotřebuje.

Veškerá dodatečná funkcionalita týkající se např. přesměrovávání, zasílání bleskových

zpráv apod., je realizována prostřednictvím příslušných rozšíření, které lze v rámci zjedno-

dušení (obdobně jako ve frameworku Zend) volat přímo uvnitř řadiče způsobem, který na-

stiňuje Výpis 8.

29 Záleží na rozsahu aplikace, na stanovení a dodržení konvencí apod.

30 To znamená, že pokud jakýkoliv posluchač (obslužná metoda) vrátí hodnotu false, dojde

k ukončení činnosti.

Page 43: Bachelor Thesis

4 Porovnání PHP frameworků 35

Výpis 8: Zkrácený způsob volání rozšíření uvnitř řadiče (Zdroj: autor)

public function indexAction() { // <nazevRozsireni> … platný název zaregistrovaného rozšíření $this-><nazevRozsireni>(…); }

Více informací ohledně registrace rozšíření, resp. DI (netýká se pouze frameworku Phalcon)

je podáno v následující kapitole.

4.4 DI (Dependency Injection)

4.4.1 Zend

Důsledné dodržování principů DI je v určitých případech obtížné (např. špatný architekto-

nický návrh), někdy dokonce nemusí být z důvodu zjednodušení požadováno. Výsledkem

však může být horší testovatelnost a snížení průhlednosti rozhraní, resp. tříd. Příkladem bu-

diž aplikační třída Zend\Mvc\Application, která vyžaduje předání instance třídy

Zend\ServiceManager\ServiceManager (service locator). Otázkou zůstává, zdali je toto zjed-

nodušení v tomto případě skutečně nutné31.

Framework obsahuje robustní implementaci vlastního DI kontejneru, jenž je reprezentován

třídou Zend\Di\Di. Základního požadavku na funkcionalitu DI kontejneru – vytváření in-

stancí tříd – je dosaženo definicí metody Di::newInstance($name, array $params = array(),

$isShared = TRUE). Zavoláním této metody dojde k vytvoření nové instance požadované

třídy, přičemž hodnoty parametrů požadovaných konstruktorem třídy lze určit v druhém pa-

rametru. Třetí parametr určuje, zda je možné vytvořenou instanci opětovně použít při zavo-

lání metody Di::get($name, array $params = array()), která v případě, že instance

požadované třídy s danými parametry byla již vytvořena, vrací právě tuto existující instanci.

Kontejner v nejjednodušším případě nevyžaduje žádnou specifickou konfiguraci. Pro správu

vzájemných závislostí tříd a porozumění struktuře tříd, které má kontejner spravovat, slouží

tzv. definiční seznam (třída Zend\Di\DefinitionList). Definiční seznam je v principu pou-

hou obálkou pro pole definicí, které jsou dány polem instancí tříd implementujících rozhraní

Zend\Di\Definition\DefinitionInterface. Framework obsahuje několik základních druhů

definic (všechny se nacházejí ve jmenném prostoru Zend\Di\Definition):

1. ArrayDefinition – nejjednodušší explicitní způsob popisu struktury,

31 Díky tomu, že lze nahlédnout do implementačních detailů třídy.

Page 44: Bachelor Thesis

4 Porovnání PHP frameworků 36

2. RuntimeDefinition – výchozí definice pro definiční seznam, který strukturu zjišťuje

za běhu skriptu,

3. CompilerDefinition – podobný princip jako u RuntimeDefinition, s tím rozdílem, že

za běhu zjištěná „zkompilovaná“ struktura tříd může být uložena na disk pro pozdější

použití a tím odpadá proces introspekce při každém běhu skriptu (Zend Technologies

Ltd., 2014),

4. BuilderDefinition – umožňuje překonat problém se vkládáním závislostí v přípa-

dech, kdy nelze použít tzv. type hinting tím, že jsou pro tyto případy programově

definována zvláštní pravidla (Zend Technologies Ltd., 2014),

5. ClassDefinition – definice struktury pouze pro konkrétní třídu.

DI kontejner a řadiče

Ačkoliv se to může zdát překvapivé, Zend v rámci řadičů DI kontejner ve výchozím stavu

vůbec nepoužívá. Naopak se spoléhá na existenci service locatoru v podobě třídy

Zend\ServiceManager\ServiceManager. Vkládání závislostí do řadičů a dostání tak principu

DI lze realizovat např. konfigurací, jak ukazuje Výpis 9 (modifikovaný příklad převzat

z (Sluiman, 2012)).

Výpis 9: Příklad předání externí závislosti řadiči za pomocí setter injection (Zdroj: (Sluiman,

2012))

///////////////////////// // soubor s řadičem namespace MyModule\Controller; class FooController extens Zend\Mvc\Controller\AbstractActionController { private $myService; public function setMyService($myService) { $this->myService = $myService; } } ///////////////////////// // soubor s konfigurací use MyModule\Controller; // konfigurace return array(

'controllers' => array( 'factories' => array(

Page 45: Bachelor Thesis

4 Porovnání PHP frameworků 37

'MyModule\Controller\Foo' => function($serviceManager) { $controller = new Controller\FooController;

$myService = $serviceManager->getServiceLocator() ->get('myService');

$controller->setMyService($myService);

return $controller; },

), ),

);

Z příkladu je patrné, že v případě, kdy nechceme uvnitř řadiče používat service locator, jsme

„nuceni“ používat poměrně „krkolomného“ způsobu předávání závislostí. Neexistuje tedy

žádný frameworkem automatizovaný proces vkládání externích závislostí přímo do řadiče

(myšleno transparentním způsobem v duchu DI) a řešení tohoto problému je ponecháno

na vývojáři.

4.4.2 Nette

Srovnáme-li definici závislostí aplikačních tříd pro framework Zend a Nette, druhá ze jme-

novaných deklaruje výčet závislostí nikoliv pomocí obecného service locatoru, nýbrž po-

mocí jasně specifikovaných parametrů. Předpoklad, že aplikační třída Nette neobsahuje

žádné skryté závislosti, lze snadno ověřit nahlédnutím do kódu příslušné třídy.

Univerzální DI kontejner představuje třída Nette\DI\Container, který umožňuje veškeré zá-

kladní operace spojené se správou služeb (přidávání, odebírání, ověřování existence). O se-

stavení („zkompilování“) kontejneru se stará třída Nette\DI\Compiler, která pracuje s tzv.

rozšířeními (angl. extensions). Framework obsahuje několik typů těchto rozšíření umístě-

ných ve jmenném prostoru Nette\DI\Extensions:

1. NetteExtension – obsahuje sadu základních služeb frameworku,

2. PhpExtension – rozšíření umožňující nastavení tzv. PHP direktiv,

3. ConstantsExtension – speciální typ rozšíření pro definici PHP konstant,

4. ExtensionsExtension – umožňuje registraci dalších rozšíření v konfiguračním sou-

boru.

Silnou vlastností Nette DI kontejneru je to, že disponuje tzv. auto-wiringem – automatickým

mechanismem rozpoznání závislostí konstruktorů tříd na základě jejich signatury. Nutnost

explicitně definovat hodnoty parametrů je tak omezena na minimum (v závislosti na složi-

tosti a explicitnosti – vyžaduje tzv. type hinting).

Page 46: Bachelor Thesis

4 Porovnání PHP frameworků 38

DI kontejner je velmi úzce spjat s konfigurací samotného frameworku, resp. aplikace

a na rozdíl od frameworku Zend se vyznačuje tím, že konfiguraci lze kromě běžného způ-

sobu definice přímo pomocí kódu psaného v PHP (konfigurační pole) provádět pomocí

zvláštního konfiguračního souboru ve formátu NEON32, který tak činí konfiguraci relativně

úspornější, co do množství textu nutného k zápisu a může tak přispět k přehlednosti (např.

v porovnání se zmíněným způsobem zápisu pomocí konfiguračního pole či XML atp.).

Ve skutečnosti překonává některé nevýhody ostatních způsobů (INI – neumožňuje zanořo-

vání, XML – je poměrně nepřehledné a nutí psát více textu, než by bylo bezpodmínečně

nutné, PHP – nejefektivnější způsob zápisu, ale zároveň relativně náchylný k chybám v pří-

padě většího množství kódu).

DI kontejner a řadiče33

Pro přímý přístup k DI kontejneru uvnitř řadiče je sice z historických důvodů možné použít

metody Presenter::getContext(), což lze považovat za určitý ekvivalent metody

AbstractController::getServiceLocator() v frameworku Zend, v současnosti se ale již

jedná o zavržený (angl. deprecated) přístup. Momentálně jsou ze strany frameworku podpo-

rovány dva způsoby předávání závislostí dovnitř řadiče:

1) property injection – vyžaduje použití anotačního komentáře @inject a zároveň musí

být tyto vlastnosti definovány jako veřejné (angl. public),

2) method injection – definice speciálních jednoúčelových metod, jejichž název musí

splňovat danou konvenci (inject<NazevSluzby>) které jsou volány výchozí továrnou

(angl. factory) řadičů (třída Nette\Application\PresenterFactory).

Následující Výpis 10 demonstruje praktické použití obou způsobů:

Výpis 10: Příklad dvou způsobů předání externích závislostí presenteru za pomoci property

a method injection (Zdroj: autor)

// předpokládá se existence třídy MyNamespace\Foo a její registrace // v rámci konfigurace služeb DI kontejneru namespace MyNamespace; // property injection class MyPresenter extends Nette\Application\UI\Presenter { /** * @inject

32 http://ne-on.org

33 V souvislosti s frameworkem Nette je význam označení Presenter ztotožněn s pojmem

řadič.

Page 47: Bachelor Thesis

4 Porovnání PHP frameworků 39

* @var MyNamespace\Foo */ public $foo; } // method injection class MyPresenter extends Nette\Application\UI\Presenter { private $foo; public function injectFoo(Foo $foo) { // jelikož se jedná o jednoúčelovou metodu, pro zajištění konzistence

// je vhodné přidat podmínku zamezující přepsání // již existující instance (vyvolání výjimky)

$this->foo = $foo; } }

4.4.3 Phalcon

Opět, uvedeme-li způsob, jakým jsou předány vnější závislosti do aplikační třídy frame-

worku Phalcon, zjistíme, že se prakticky příliš neliší od aplikační třídy Zend, jelikož v kon-

struktoru vyžaduje celý DI kontejner. S podivem lze pak porozumět dokumentačním

komentářům34, které deklarují, že jednotlivé komponenty frameworku jsou navzájem rela-

tivně oddělené (ukazuje se, že nic není dokonalé).

Byť je kontejner v obecné rovině reprezentován třídou Phalcon\DI, v praktické rovině vyža-

dující co největší míru zjednodušení (tudíž nutnost psát méně kódu při zachování požado-

vané funkčnosti) je možné použít třídu typu Phalcon\DI\FactoryDefault, která se o registraci

základních služeb postará automaticky.

Kromě základních metod pro přidávání, odebírání, či ověřování existence určitých služeb,

DI kontejner např. umožňuje za běhu za určitých podmínek35 změnu třídy, kterou služba

reprezentuje či dodatečnou změnu parametrů (Phalcon Team and contributors, 2014) (bez

toho, aby bylo nutné službu nejprve odebrat a následně opětovně přidat s novými parametry).

Z dalších zvláštností (v porovnání s ostatními frameworky) lze uvést:

34 http://docs.phalconphp.com/en/latest/reference/di.html#our-approach

35 Záleží na zvoleném způsobu registrace služby.

Page 48: Bachelor Thesis

4 Porovnání PHP frameworků 40

1) DI kontejner lze použít k vytváření instancí tříd, i když tyto třídy nejsou v kontejneru

zaregistrovány (při nenalezení služby s daným názvem se framework pokusí nalézt

třídu s tímto názvem a vytvořit její instanci),

2) Pokud třída zastoupená službou implementuje rozhraní

Phalcon\DI\InjectionAwareInterface, DI kontejner této třídě automaticky předá in-

stanci sebe sama za pomocí metody

InjectionAwareInterface::setDI(Phalcon\DiInterface $dependencyInjector);

vlastnost zmiňuji v reakci na již zmíněné prohlášení autorů o volné provázanosti fra-

meworkových komponent a ačkoliv může v jistých případech být užitečná, jedná se

o popření principu DI,

3) Existence statické metody Phalcon\DI::getDefault(), která je součástí dokumentace

DI36 opět vede k otázce, do jaké míry to s DI myslí autoři frameworku vážně (možná

implicitně předpokládají, že případný čtenář si je vědom potenciálních problémů

s tím spojených).

Konfigurace kontejneru je (přinejmenším v porovnání s frameworkem Nette) z pohledu

„pohodlnosti“ relativně náročná, protože kontejner nedisponuje žádným mechanismem

pro automatické rozpoznání a přenášení externích závislostí napříč objektovým grafem.

DI kontejner a řadiče

Přístup k DI kontejneru uvnitř řadiče, který je potomkem třídy Phalcon\DI\Injectable je

prakticky stejný jako ve frameworku Zend, díky existenci metody Injectable::getDI().

Žádný automatizovaný způsob jak předat řadiči externí závislostí, který by zároveň reflek-

toval DI přístup, Phalcon nenabízí.

4.5 Komponentový vývoj

4.5.1 Zend

Jednotlivé části, resp. třídy frameworku lze považovat za relativně samostatné a znovupou-

žitelné komponenty. Poměrně hojně je používáno abstraktních rozhraní, čímž je dosaženo

relativní nahraditelnosti jednotlivých komponent jednak komponentami nacházejícími se již

ve frameworku samotném, ale i těmi z 3. stran.

36 http://docs.phalconphp.com/en/latest/reference/di.html#accessing-the-di-in-a-static-way

Page 49: Bachelor Thesis

4 Porovnání PHP frameworků 41

Framework je rozdělen do logických součástí, jejichž distribuce je realizována v zásadě

dvěma způsoby:

1) 1 balíček obsahující všechny součásti standardní distribuce,

2) každá logická část distribuována zvlášť odděleně od ostatních (pomocí nástroje

Composer)37.

Výhodnou druhého způsobu je především to, že specifickou část frameworku lze použít sa-

mostatně a v případě, že daný balíček přeci jen vyžaduje další externí komponenty, dokáže

tyto závislosti Composer sám rozpoznat (pomocí konfiguračního souboru composer.json,

který je umístěn v balíčku) a v případě nutnosti dodatečně komponenty automaticky získat.

Na druhou stranu, hovoříme-li o komponentách a jejich rozdělení na komponenty:

1) vykreslitelné,

2) nevykreslitelné,

framework Zend prakticky nepředstavuje žádné abstraktní pojetí pro oba typy. Architektura

není hierarchického charakteru a nelze vypozorovat žádný přímý logický vztah typu rodič-

potomek.

4.5.2 Nette

Podobně jako Zend, je framework Nette složen z logických částí, liší se však především

celkovým množstvím komponent. U tvůrců frameworku Nette převládá relativní střídmost

v pohledu na to, co vše by měl framework nabízet nativně a které oblasti již ponechat uživa-

telům. Proto framework poskytuje způsob, jak tuto rozšiřitelnost zajistit pomocí definice

abstraktních rozhraní. V porovnání s frameworkem Zend se může zdát, že programování

proti rozhraní je v Nette použito paradoxně v menším rozsahu. Tento dojem je ovlivněn

celkově menším počtem komponent a odlišnou filosofií frameworku.

Framework však představuje vlastní originální pojetí pro komponentový vývoj aplikací, je-

likož explicitně rozlišuje vykreslitelné a nevykreslitelné komponenty aplikace a zavádí

obecný hierarchický stromový model pro tvorbu a skládání jednotlivých komponent dohro-

mady v jeden celek. Strukturu komponentového modelu znázorňuje Výpis 11.

Výpis 11: Komponentový model frameworku Nette (Zdroj: (Nette Foundation, 2014))

Nette\Object | +- Nette\ComponentModel\Component { IComponent } |

37 Kompletní seznam balíčků je k dispozici na adrese https://packages.zendframework.com.

Page 50: Bachelor Thesis

4 Porovnání PHP frameworků 42

+- Nette\ComponentModel\Container { IContainer } | +- Nette\Application\UI\PresenterComponent { ISignalReceiver, IStatePersistent } | +- Nette\Application\UI\Control { IPartiallyRenderable } | +- Nette\Application\UI\Presenter { IPresenter }

Ultimátním předkem všech tříd frameworku je třída Nette\Object. Děděním od této třídy do-

chází k určité standardizaci chování všech objektů frameworku, protože odstraňuje některé

nedostatky jazyka PHP a zároveň přináší některé užitečné vlastnosti (Nette Foundation,

2014):

1) Třídy jsou tzv. striktní - v případě odkazování se na neexistující třídní proměnnou

dojde k vyvolání výjimky,

2) Definice vlastností třídy za pomocí tzv. getterů a setterů – doplňuje možnost de-

finice vlastností známých např. z jazyka C#, kdy se lze odkazovat na třídní vlastnost

přímo pomocí jejího názvu i přesto, že viditelnost vnitřní proměnné reprezentující

tuto vlastnost by tento přístup neumožňovala,

3) Události – na rozdíl od ostatních frameworků jsou události vyvolávány přímo

na konkrétních objektech, nikoliv za pomoci externího „správce událostí“; realizo-

váno definicí veřejné třídní proměnné s patřičným názvem, který musí splňovat kon-

venci (např. public $on<NazevUdalosti> = array();),

4) Rozšiřující metody (angl. extension methods) – umožňují za běhu přidávat do exis-

tující třídy další veřejné metody,

5) Reflexe a anotace – vzájemně spolu souvisí, neboť za pomoci reflexe (získání for-

málních informací o třídě) lze jednoduše získat např. seznam všech anotací (speciální

způsob zápisů dokumentačního komentáře) dané třídy, metody či proměnné.

Obecnými potomky Nette\Object jsou dle diagramu následující třídy:

Nette\ComponentModel\Component – zajišťuje, že každá komponenta má definován

svůj název (z pohledu hierarchie komponent) a může či nemusí být potomkem kom-

ponenty jiné, resp. kontejneru,

Nette\ComponentModel\Container – komponenta, která umožňuje samotnou tvorbu

hierarchie, neboť obsahuje metody pro dynamickou správu svých potomků,

Nette\Application\UI\PresenterComponent – speciální typ komponenty předurčující

její použití v rámci presenteru; tyto komponenty umožňují např. uchovávání svého

stavu prostřednictvím URL a zpracovávání signálů,

Page 51: Bachelor Thesis

4 Porovnání PHP frameworků 43

Nette\Application\UI\Control – vykreslitelná komponenta, poměrně silný prvek

frameworku, protože umožňuje sestavení aplikace z různých především uživatelsky

definovaných částí, přičemž způsob vykreslení lze ovlivnit např. pouhou změnou ša-

blon,

Nette\Application\UI\Presenter – z diagramu je patrné, že Presenter v podání fra-

meworku Nette není nic jiného, než speciální typ vykreslitelné komponenty, který

navíc dokáže zpracovat aplikační požadavek a způsob jeho zpracování je dán jeho

životním cyklem.

Framework je sice distribuován mj. i jako balíček pro Composer, nicméně pouze jako celek.

Žádostem o rozdělení frameworku na samostatné balíčky bylo prakticky vyhověno až

ve verzi 2.2 beta138.

4.5.3 Phalcon

Komponenty frameworku Phalcon jsou rozděleny stejně jako u obou předchozích frame-

worků do příslušných jmenných prostorů, ale narazit lze opět na paradox spojený s DI

a programováním proti rozhraní. Velká část tříd implementuje alespoň jedno obecné roz-

hraní, často se jedná o Phalcon\Events\EventsAwareInterface pomocí, kterého lze zařídit po-

slouchání událostí, či rozhraní Phalcon\DI\InjectionAwareInterface, které však navzdory

názvu znamená, že je třídě možné předat celý DI kontejner, resp. service locator a nikoliv

závislosti přesně specifikované.

Budeme-li chtít nalézt jakousi paralelu s ohledem na zavedení abstraktní třídy reprezentující

(ne)vykreslitelnou komponentu, pak se jejímu účelu nejvíce podobá třída

Phalcon\Mvc\User\Component a to i přesto, že nedefinuje žádné podobné metody a ani nedis-

ponuje jejími vlastnostmi. Prakticky se pouze jedná o co do funkčnosti prázdnou třídu, která

má však k dispozici přímý přístup k řadě služeb poskytovaných frameworkem, které jsou

de facto sdílené napříč celou aplikací, což přináší výhody (z pohledu pohodlnosti vývojáře),

avšak i jednu zásadní nevýhodu - třída je závislá na celém DI kontejneru, jehož obsah je

relativně „neznámý a nestálý“, protože služby mohou být registrovány a odebírány dyna-

micky a komponenta se stává relativně hůře testovatelnou.

Možnosti distribuce frameworku coby soustavy samostatných balíčků je omezena faktem,

že se jedná o framework kompilovaný z jazyka C, tudíž pro použití byť jen určité kompo-

nenty je nutné „sáhnout“ po celém rozšíření.

38 http://forum.nette.org/en/1464-nette-framework-2-2-beta1-released

Page 52: Bachelor Thesis

4 Porovnání PHP frameworků 44

4.6 Šablonový systém

4.6.1 Zend

Šablonový systém frameworku Zend se skládá z několika vrstev (Zend Technologies Ltd.,

2014) z nichž základní je Zend\View\View, která obsahuje definici tzv. strategií pro mapování

aplikačního požadavku na výstup pohledu. Tyto strategie jsou dvojího typu:

1. Vykreslovací strategie (angl. rendering strategies) – na základě požadavku určují,

jaký vykreslovač (angl. renderer) bude použit,

2. Strategie odpovědi (angl. response strategies) – určují podobu konečné odpovědi.

Definicí vlastních strategií lze ovlivnit chování aplikace, co se týče jejího výstupu např.

pro každý modul zvlášť.

Framework je specifický tím, že sám o sobě pro kódování šablon nenabízí vlastní šablono-

vací jazyk, tak jak je to běžné u jiných frameworků, nýbrž ve výchozím stavu nabízí

tzv. „PHP vykreslovač“ (třída Zend\View\Renderer\PhpRenderer), jehož elementární vlast-

ností je to, že kód šablon je psán přímo v jazyce PHP, viz Výpis 12, proto je kód interpreto-

ván „tak jak je“. Jedná se poměrně o efektivní způsob tvorby šablon, co se týče výkonosti

(za cenu zhoršení srozumitelnosti celkového kódu).

Výpis 12: Ukázka šablony psané pro PhpRenderer (Zdroj: autor)

// soubor s šablonou <h1>Rows</h1> <?php if (count($this->rows) == 0): ?> <p>No rows…</p> <?php else: ?>

<ul> <?php foreach ($this->rows as $row): ?> <li> <?php echo $this->escapeHtml($row->name); ?> </li> <?php endforeach; ?> </ul> <?php endif; ?>

Kromě PHP vykreslovače obsahuje framework i dva další:

Zend\View\Renderer\JsonRenderer – generování odpovědi ve formátu JSON,

Zend\View\Renderer\FeedRenderer – generování RSS feedu.

Page 53: Bachelor Thesis

4 Porovnání PHP frameworků 45

Pro ukládání, resp. registraci proměnných šablonám slouží prvek typu

Zend\View\Model\ViewModel (pohledový model), který je obálkou pro tzv. kontejnery pro-

měnných (angl. Variables Containers) a umožňují nastavení konkrétní šablony pro daný po-

hled. Pomocí pohledového modelu lze tvořit hierarchickou strukturu, jeden ViewModel může

obsahovat i další potomky typu ViewModel, čímž je podpořena např. možnost vytvářet a sklá-

dat znovupoužitelné pohledy. Pro maximální zvýšení pohodlnosti je možné použít několik

způsobů, jak proměnnou pohledovému modelu, resp. šabloně „předat“, jak demonstruje

Výpis 13.

Výpis 13: Způsoby registrace šablonových proměnných (Zdroj: autor)

////////////////////////////////////////////////// // registrace proměnných v konstruktoru ViewModelu // metoda zpracování akce řadiče public function indexAction() { $viewModel = new \Zend\View\Model\ViewModel(array( ‘myVariable’ => ‘test’, ‘otherVariable’ => ‘test_2’,

)); return $viewModel;

} /////////////////////////////////////////////////// // registrace proměnných metodou public function indexAction() { $viewModel = new \Zend\View\Model\ViewModel(); // registrace proměnných každé zvlášť $viewModel->setVariable(‘myVariable’, ‘test’); $viewModel->setVariable(‘otherVariable’, ‘test_2’); // nebo lze použít hromadnou registraci // druhý parametr určuje, zda má dojít k přepsání existujícího // kontejneru s proměnnými či nikoliv $viewModel->setVariables(array( ‘myVariable’ => ‘test’, ‘otherVariable’ => ‘test_2’, ), true); return $viewModel; } ///////////////////////////////////////////////////

Page 54: Bachelor Thesis

4 Porovnání PHP frameworků 46

// registrace pomocí magických metod public function indexAction() { $viewModel = new \Zend\View\Model\ViewModel(); $viewModel->myVariable = ‘test’; $viewModel->otherVariable = ‘test_2’; return $viewModel; }

V závislosti na použitém vykreslovači lze uvnitř šablon používat helpery. V případě

PHP vykreslovače lze seznam dostupných helperů ovlivnit pomocí třídy

Zend\View\HelperPluginManager39, která již obsahuje seznam všech výchozích helperů po-

skytovaných frameworkem. Přidat další helper lze buď pomocí patřičné metody správce hel-

perů (de facto se jedná o speciální podtyp třídy Zend\ServiceManager\ServiceManager, který

je, jak již bylo zmíněno, implementací service locatoru), či v rámci konfigurace modulu/apli-

kace.

Způsob použití helperů v šabloně nastiňuje Výpis 14, framework poskytuje relativně poho-

dlnou možnost zkráceného zápisu. Konkrétně se jedná o příklad použití escapování pro-

měnné. Upozornit je třeba na fakt, že escapování není tzv. kontextové, čili konkrétní způsob

escapování je zapotřebí manuálně určit použitím patřičné metody (liší se např. escapování

pro HTML, CSS, JS, URL apod.). Rovněž, samotný fakt, že escapování neprobíhá automa-

ticky, ale na základě požadavku vyvolaného použitím helperu, je celkový kód šablony po-

měrně nepřehledný a náchylný ke vzniku potenciálních bezpečnostních děr.

Výpis 14: Příklad použití helperu uvnitř šablony (Zdroj: autor)

// Příklad předpokládá: // 1] registraci helperu pod názvem escapeHtml, // 2] existence proměnné $myVariable. <div class=”test”> // vypíše escapovaný obsah proměnné $myVariable <?php echo $this->escapeHtml($myVariable); ?> </div>

Framework nabízí speciální sadu helperů souvisejících s problematikou lokalizace a inter-

nacionalizace. Nejobecnějším z nich je helper standardně registrovaný pod názvem

„translate“, který slouží k překladu zpráv. Nechybí helpery pro tvorbu lokalizovaných hod-

not týkajících se data a času, měn, ani číselných údajů.

39 Dále jako tzv. správce helperů.

Page 55: Bachelor Thesis

4 Porovnání PHP frameworků 47

4.6.2 Nette

Základní komponenty pro tvorbu šablon představují třídy:

Nette\Templating\Template – obecný typ šablony; na vstupní zdroj šablony je možné

aplikovat tzv. filtry a následně ji vykreslit/uložit,

Nette\Templating\FileTemplate – speciální typ šablony, pro kterou platí, že je repre-

zentována fyzickým souborem na disku.

Obě implementace automaticky používají cache (konkrétně Nette\Caching\Cache), toto cho-

vání nelze nijak potlačit (lze ovlivnit pouze typ úložiště cache, viz kapitola 4.12.2 na straně

77).

Šablona jako taková není přímo spjata s určitým pohledem a lze ji např. použít i samostatně

bez dalších vrstev modelu MVC.

Rozhraní pro šablonu (Nette\Templating\ITemplate), resp. šablonu reprezentovanou soubo-

rem (Nette\Templating\IFileTemplate), nedeklaruje, že lze proměnné či helpery do šablony

registrovat. Registraci proměnných a helperů však třída Nette\Templating\Template defi-

nuje. Separace odpovědností (tak jak tomu je např. u Zend), je zde z pohledu komplexity

nízká, neboť z principu věci není ani zapotřebí40.

Nette však obsahuje svůj vlastní šablonovací jazyk Latte, který je právě oním nejčastějším

a výchozím filtrem, který je na danou šablonu aplikován a představuje jednu z klíčových

součástí frameworku. Na rozdíl od základu šablonového systému reprezentovaného zejména

třídou Nette\Templating\FileTemplate, je balíček Latte rozdělen do několika úrovní, resp.

tříd. Latte obsahuje speciální třídu pro parsování kódu šablony a jeho následnou kompilaci.

V rámci šablony lze používat tzv. makra, která jsou prakticky pouhým rozšířením možností

jazyka PHP. Každé makro je v rámci kompilace převedeno na odpovídající volitelný sled

PHP kódu, přičemž jazyk Latte umožňuje dvojí způsob jejich zápisu:

„klasický zápis“ pomocí složených závorek41,

„n:makro“ zápis, který lze použít uvnitř HTML tagu obdobně jako HTML atributy.

Rozdíl zápisu a zároveň elegantnost jazyka má za cíl představit Výpis 15.

Výpis 15: Příklad dvojího zápisu Latte maker (Zdroj: autor)

/////////////////////////// // klasický zápis

40 Rozčlenění je patrné až u konkrétního filtru Latte.

41 Ve skutečnosti se nemusí vždy nutně jednat o složené závorky, protože záleží na aktuálním

nastavení syntaxe – symbolu ohraničujícím zápis makra.

Page 56: Bachelor Thesis

4 Porovnání PHP frameworků 48

<ul> {foreach $rows as $row} <li>{$row->name}</li> {/foreach} </ul> /////////////////////////// // n:makro zápis <ul> <li n:foreach=“$rows as $row“>{$row->name}</li> </ul>

Z příkladu Výpis 15 je patrné, že pro způsob jak proměnnou vypsat je přímočarý pomocí

uvedení jejího názvu do oddělovače maker (v tomto případě složené závorky). Příklad je

totožný s příkladem uvedeným u frameworku Zend za účelem vyzdvižení jedné podstatné

vlastnosti jazyka Latte, kterou je automatické escapování veškerého dynamicky generova-

ného výstupu. Escapování lze potlačit použitím helperu noescape42. Navíc, způsob

escapování je automaticky určen na základě kontextu, ve kterém má k výpisu dojít (HTML,

JS, apod.).

Kromě základních maker ovlivňujících běh skriptu známých z jazyka PHP (if, for, while,

atd.), Latte obsahuje i další pomocné, které usnadňují zápis některých specifických

konstrukcí nebo mají jiný speciální význam43:

makra související s výpisem formulářů, resp. formulářových prvků,

makra umožňující skládat několik šablon dohromady, definice rozvržení, dě-

dičnost šablon,

makro pro použití cache,

makra pro tvorbu aplikačních odkazů,

atd.

Vývojář rovněž není omezen výchozí sadou maker, jelikož Latte podporuje i registraci ma-

ker uživatelsky definovaných.

42 Z historických důvodu je možné escapování možné potlačit uvedením vykřičníku před

obsah, který má být vypsán. V současné verzi frameworku je však tento způsob již zavr-

žený a jeho použití vede k vyvolání chyby.

43 Kompletní seznam maker s jejich popisem a příklady užití lze nalézt např.

na http://doc.nette.org/cs/2.1/default-macros.

Page 57: Bachelor Thesis

4 Porovnání PHP frameworků 49

Helpery jsou standardně zapisovány pomocí svislé čáry předcházející názvu helperu (např.

{$myVariable|trim}). Pro parametrizované helpery stačí za název helperu přidat dvojtečku

následovanou seznamem hodnot parametrů oddělenými čárkami (např.

{$myVariable|truncate:64}). Stejně jako makra je možné do šablony registrovat i helpery

vlastní.

4.6.3 Phalcon

Podobně jako u frameworku Nette je možné rozdělit šablonový systém Phalcon na dvě

vrstvy:

1. Vrstva pohled (třída Phalcon\Mvc\View) – vychází z modelu MVC,

2. Vlastní šablonovací jazyk Volt.

Pod pojmem šablona se vždy míní nějaký konkrétní pohled, obdobně jako je tomu u frame-

worku Zend, což představuje rozdíl mezi těmito frameworky a frameworkem Nette, který

chápe šablony jako prostředek pro tvorbu pohledu a navíc rozlišuje, zda je šablona reprezen-

tována fyzickým souborem, či nikoliv.

Rovněž API definované rozhraním, které implementuje (Phalcon\View\ViewInterface) je po-

měrně „košaté“ a kromě obecných metod pro registraci proměnných definuje i metody pro

nastavení cest ke zdrojovým souborům šablon, metody pro nastavení rozvržení a další44.

Metoda ViewInterface::registerEngines(array $engines) je jistým ekvivalentem metody

Template::registerFilter($callback), odhlédneme-li od rozdílu v názvosloví, jejich smysl

zůstává stejný – umožnit vývojáři registraci jiných šablonových vykreslovačů (tzv. adap-

térů). Součástí distribuce Phalcon jsou dva typy:

Phalcon\Mvc\View\Engine\Php – šablonovací jazyk PHP,

Phalcon\Mvc\View\Engine\Volt – rozšíření jazyka PHP (obdobně jako

Nette\Latte\Engine).

Pohled je navíc z povahy API vždy spojován s určitým řadičem a jeho akcí. Specifickým lze

nazvat i způsob, jakým lze ovlivnit (ne)vykreslení daného pohledu, kdy na rozdíl od frame-

worku Nette se tato možnost řídí nastavením přímo na tomto objektu. Jinými slovy, nemá-li

v rámci akce řadiče dojít k vykreslení pohledu, ale např. k přesměrování, je nutné vykreslení

manuálně deaktivovat viz Výpis 16.

Výpis 16: Způsob deaktivace vykreslení pohledu (Zdroj: (Phalcon Team and contributors, 2014))

class UsersController extends \Phalcon\Mvc\Controller

44 Viz dokumentace http://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_ViewInter-

face.html.

Page 58: Bachelor Thesis

4 Porovnání PHP frameworků 50

{ public function closeSessionAction() { // přesměrování $this->response->redirect('index/index'); // deaktivace vykreslení pohledu (šablony) $this->view->disable(); } }

Helpery jsou registrovány přímo do globálního DI kontejneru, bez nutnosti registrace

do konkrétních pohledů (rozdíl oproti ostatním frameworkům).

Šablonový vykreslovač Volt jako řada ostatních podporuje všechny základní konstrukce.

V porovnání s Latte se mírně liší svojí syntaxí, jak demonstruje Výpis 17. Ačkoliv jej lze

použít i samostatně, zůstává částečně závislý na DI kontejneru, který používá pro volání

dodatečných služeb použitých v šabloně45.

Výpis 17: Přehled základní syntaxe jazyka Volt (Zdroj: autor)

{# soubor s šablonou #} {# na rozdíl od Latte, nelze funkce jazyka PHP v makrech využívat napřímo (bez předchozí registrace), mimo makra příkazy PHP zapisovat lze #} {# kontrolní příkazy jsou ohraničeny složenou závorkou následovanou znakem procenta #} {# použití filtru (helperu) jehož název je uveden za svislou čárou pro spočítání počtu položek v kolekci #} {% if rows|count == 0 %} <p>No rows…</p> {% else %} <ul> {% for row in items %} {# vypsání hodnoty výrazu je ohraničeno dvojitými složenými závorkami #} <li>{{ row|e }}</li> {% endfor %} </ul> {% endif %}

45 http://docs.phalconphp.com/en/latest/reference/volt.html#inject-services-into-a-template

Page 59: Bachelor Thesis

4 Porovnání PHP frameworků 51

Na rozdíl od Latte, kdy řídící i vypisovací příkazy jsou zapisovány pomocí stejného sym-

bolu, Phalcon tyto dva typy přísně rozlišuje a neumožňuje ani jejich případnou změnu. Na-

opak názvy proměnných mohou a musí být uváděny bez symbolu $. Helper e, resp. escape

slouží k escapování HTML výstupu. Pro escapování v odlišném kontextu je zapotřebí použít

tomu určené ekvivalenty (např. escape_css, escape_js). Omezení plynoucí z nutnosti expli-

citního používání escapovacích helperů lze částečně překonat za pomoci zvláštního makra,

kterým lze automatické escapování vynutit (byť pouze pro HTML).

Výpis 18: Automatické escapování v systému Volt (Zdroj: autor)

{# zápis: #} {{ foo|escape }} {# totožný s: #} {% autoescape true %} {{ foo }} {% endautoescape %}

Zdrojem kompilátoru (Phalcon\Mvc\View\Engine\Volt\Compiler) vstupního kódu šablony

může být kromě fyzického souboru i textový řetězec (proměnná typu string), pro jehož

kompilaci slouží metoda Compiler::compileString($viewCode, $extendsMode = NULL).

4.7 Formuláře

4.7.1 Zend

Formuláře v podání frameworku Zend zahrnují několik různých komponent. Za základní

komponentu lze označit Zend\Form\Element, resp. Zend\Form\Fieldset, jejímž speciálním ty-

pem je třída Zend\Form\Form. Třída Fieldset zastřešuje základní práci s formulářem, co se

týče definice jeho vnitřních prvků (elementů), přičemž platí, že může obsahovat i libovolný

počet dále vnořených Fieldsetů.

Způsobů, jak samotný formulář konstruovat, nabízí framework hned několik (liší se svojí

složitostí a možnostmi znovupoužitelnosti) (Zend Technologies Ltd., 2014):

1. Metoda postupného skládání formuláře ze samostatných elementů,

2. Použití výchozí tovární třídy Zend\Form\Factory,

3. Vytvoření formuláře děděním třídy Zend\Form\Form,

Page 60: Bachelor Thesis

4 Porovnání PHP frameworků 52

4. Anotacemi definovaný formulář46.

Vývojář má k dispozici celou řadu jak klasických, tak i speciálních formulářových prvků

(elementů), které lze do formuláře přidávat (jmenný prostor Zend\Form\Element), pro tvorbu

uživatelsky definovaných elementů slouží rozhraní Zend\Form\ElementInterface.

Pro definici validačních pravidel slouží rozhraní vyčleněné mimo jmenný prostor formulářů

Zend\InputFilter\InputFilterProviderInterface, které definuje jedinou metodu

InputFilterProviderInterface::getInputFilterSpecification(), jejíž návratovou hodno-

tou je pole s definicí požadovaných pravidel. Validační pravidla jsou proto oddělena

od vlastních formulářových prvků, což může při tvorbě formulářů působit relativně zma-

tečně.

Validační pravidla jako taková jsou reprezentována třídami implementující rozhraní

Zend\Validator\ValidatorInterface. Ve stejném jmenném prostoru se pak nachází kromě

pravidel obvyklých (např. kontrola platnosti emailové adresy, délky řetězce, číselné hod-

noty) i několik dalších, které lze považovat za specifické (např. kontrola IBAN, číslo kreditní

karty, apod.). Autoři je navíc implementovali tak, aby případné validační chyby byly něko-

likastupňové, takže jedno validační pravidlo může obsahovat několik druhů typu chyb, které

tak mohou být uživateli výstižněji popsány pomocí zpráv, které přesněji popisují chybu,

ke které došlo. Každé další uživatelské pravidlo tedy musí být reprezentováno konkrétní

třídou.

Výpis 19: Příklad vytvoření definice formuláře pomocí tovární třídy (Zdroj: autor)

use Zend\Form\Factory, Zend\Validator; $factory = new Factory(); $form = $factory->createForm(array( 'elements' => array( array( 'spec' => array( 'type' => 'Zend\Form\Element\Text', 'name' => 'name', 'options' => array( 'label' => 'Name', ), ), ), ), 'input_filter' => array( 'name' => array(

46 Vyžaduje externí knihovnu Doctrine\Common, viz http://framework.zend.com/man-

ual/2.3/en/modules/zend.form.quick-start.html#using-annotations.

Page 61: Bachelor Thesis

4 Porovnání PHP frameworků 53

// název je povinný (je nutné ho vyplnit) 'required' => TRUE, 'validators' => array( // délka názvu musí být alespoň 3 znaky new Validator\StringLength(array( 'min' => 3, )), ), ), ), ));

Zpracování hodnot formuláře spočívá v předání vstupních „syrových“ GET/POST dat in-

stanci formuláře pomocí metody Form::setData($data), následovaného voláním metody

pro validaci Form::isValid(). Pro získání zpracovaných dat slouží metoda Form::getData(),

pro získání chybových zpráv způsobených validací formuláře pak metoda

Form::getMessages().

Užitečnou funkcionalitu však přináší komponenty typu Zend\Stdlib\Hydrator\

HydratorInterface (Hydrátor), které lze s výhodou využít právě v souvislosti s formuláři.

Jejich smyslem je „poskytnout mechanismus pro naplnění objektu na základě vstupních dat

a obráceně” (Zend Technologies Ltd., 2014). Za pomocí Hydrátorů lze realizovat proces

v odborné sféře známý jako binding47. Binding v souvislosti s formuláři znamená

obousměrné namapování určité entity (třídy doménového modelu) na konkrétní formulář,

resp. jeho prvky. Příklad ilustruje Výpis 20 převzatý z oficiální dokumentace.

Výpis 20: Formulářový binding (Zdroj: (Zend Technologies Ltd., 2014))

$contact = new ArrayObject; $contact['subject'] = '[Contact Form] '; $contact['message'] = 'Type your message here'; $form = new Contact\ContactForm; $form->bind($contact); $data = array( 'name' => 'John Doe', 'email' => '[email protected]', 'subject' => '[Contact Form] \'sup?', ); $form->setData($data); if ($form->isValid()) { /*

47 Českým ekvivalentem může být např. svázání nebo napamování.

Page 62: Bachelor Thesis

4 Porovnání PHP frameworků 54

obsah proměnné $contact: array( 'name' => 'John Doe', 'email' => '[email protected]', 'subject' => '[Contact Form] \'sup?', 'message' => 'Type your message here', ) */ }

Pro vykreslení formuláře uvnitř šablony lze použít několik předdefinovaných helperů. Těsně

před jeho vykreslením je však zapotřebí nejprve zavolat metodu Form::prepare(). Způsob

vykreslení se řídí stejným principem jako při tvorbě klasického HTML formuláře (uvedený

sled předpokládá použití v rámci šablony s existující proměnnou $form reprezentující in-

stanci předem definovaného formuláře):

1) Vykreslení otevírací značky (tagu) $this->form()->openTag($form);,

2) Vykresleni jednotlivých formulářových prvků (elementů):

V závislosti na typu formulářového prvku lze vykreslit jeho popisek (angl.

label), samotný prvek (angl. input), chybové zprávy pro daný prvek,

Pro výchozí formulářové prvky existují odpovídající helpery (třídy ze jmen-

ného prostoru Zend\Form\View\Helper s názvem Form<TypElementu>), pří-

padně lze použít obecnou variantu (třída FormInput),

Pro vykreslení všech částí najednou pomocí jediného příkazu lze použít hel-

per $this->formRow(ElementInterface $element = NULL).

3) Vykreslení ukončovací značky (tagu) $this->form()->closeTag();.

4.7.2 Nette

Podobně jako framework Zend, Nette formulář chápe jako komponentu skládající se z lo-

gických celků, tzv. kontejnerů48 (třída Nette\Forms\Container, která je speciálním typem

kontejneru ve smyslu komponentového modelu Nette). Proto lze formulář skládat z libovol-

ných dalších „pod-formulářů“, přesněji řečeno kontejnerů, obdobně jako to umožňuje Zend.

Formulář jako celek je reprezentován třídou Nette\Forms\Form a je speciálním typem kontej-

neru. Tvorbu jeho definice framework podporuje výhradně objektově orientovaným způso-

bem pomocí metod Form::add<TypPrvku>(…), ve většině případů je povinně vyžadován pouze

48 Dále se pod pojmem kontejner má na mysli formulářový kontejner.

Page 63: Bachelor Thesis

4 Porovnání PHP frameworků 55

název takto přidané komponenty (povinnost deklarace jedinečného názvu vyplývá z kompo-

nentového modelu).

Validační pravidla jsou definována na rozdíl od frameworku Zend pro každý prvek zvlášť

a umožňují navíc vytvářet podmínky, za kterých je validace jednotlivých prvků prováděna.

Pravidla jsou zaregistrována pomocí volitelné kombinace metod49:

1. BaseControl::addRule($operation, $message = NULL, $arg = NULL) – přidání vali-

dačního pravidla s volitelnou zprávou, která je určena k zobrazení uživateli v případě

nesplnění podmínek daných pravidlem; některá pravidla vyžadují uvedení hodnoty

pro 3. parametr, který je jinak volitelný (např. max./min. délka řetězce); jako hod-

notu parametru $operation lze uvést i callback, resp. anonymní funkci, která před-

stavuje např. uživatelsky definované pravidlo (její výstupní hodnota by měla být

typu boolean),

2. BaseControl::addCondition($operation, $value = NULL) – stanovení podmínky

pro uplatnění následujících validačních pravidel,

3. BaseControl::addConditionOn(IControl $control, $operation, $value = NULL) –

stejné jako v předchozím bodě s tím rozdílem, že podmínku je možné aplikovat na

jiný prvek.

Kromě obecně platných pravidel (např. validace emailu, číselné hodnoty, regulární výrazy,

povinnost vyplnění hodnoty, min./max. délka apod.), existuje možnost přidání vlastních

pravidel pomocí callbacků či anonymních funkcí. Pro kontrolu, že formulář neobsahuje

chyby a zároveň byl korektně odeslán, slouží metoda Form::isSuccess(). Zpracované hod-

noty vrací metoda Container::getValues(), resp. Form::getValues($asArray = FALSE).

Vstupní data si formulář dokáže získat sám, proto je formuláři není nutné předávat manuálně.

Výpis 21: Příklad definice formuláře (Zdroj: autor)

use Nette\Forms\Form; // vytvoření přihlašovacího formuláře $form = new Form(); $form->addText(‘login’, ‘Login’) ->setRequired(‘Prosím zadejte Váš login.’) ->addRule(Form::EMAIL, ‘Prosím, zkontrolujte platnost e-mailu.’) ->addRule(function (Nette\Forms\IControl $control) { // zde může být implementována např. logika ověření, // zda zadaný e-mail je aktivován, apod. if (...) {

49 Jedná se o metody třídy Nette\Forms\Controls\BaseControl, jejímž potomkem jsou

všechny konkrétní typy formulářových prvků.

Page 64: Bachelor Thesis

4 Porovnání PHP frameworků 56

return FALSE; } return TRUE; }, ‘Váš účet byl zablokován.’); $form->addPassword(‘pass’, ‘Heslo’) ->setRequired(‘Prosím, zadejte Vaše heslo.’); $form->addSubmit(‘Prihlásit’);

Vykreslení celého formuláře obstarává tzv. vykreslovač (třída implementující rozhraní

Nette\Forms\IFormRenderer) a díky přepsání metody Form::__toString(), jej lze snadno vy-

kreslit např. za pomoci výchozího vykreslovače

Nette\Forms\Rendering\DefaultFormRenderer, který obsahuje množství parametrů, kterými

lze vykreslení ovlivnit. Pro manuální vykreslení lze s výhodou využít systému Latte, který

obsahuje specializovaná makra, viz Výpis 22.

Výpis 22: Příklad použití Latte maker pro manuální vykreslení formuláře (Zdroj: autor)

{# soubor s šablonou #} {# předpokládá existenci komponenty myForm, viz dále #} {form myForm class => ‘myForm’} {# makra podporují nastavení HTML atributů #} {label login /}{input login} {# input typu text #} {label pass /}{input pass} {# input typu password #} {input submitForm} {# odesílací tlačítko typu submit #} {/form}

Formuláře jsou z pohledu komponentového modelu Nette specifickou komponentou, jelikož

na rozdíl od komponent ostatních je nativně podporována jejich lokalizovatelnost. Zároveň

pro použití formuláře v rámci Presenteru slouží tomuto přizpůsobená třída

Nette\Application\UI\Form, která již funguje na principu tzv. signálů.

Další ojedinělou a bezpochyby užitečnou vlastností Nette je (alespoň co se týče porovnáva-

ných frameworků), že součástí distribuce je i javascriptový obslužný soubor

client_side\netteForms.js pro provádění validace na straně klienta, který podporuje všechny

základní validační pravidla a umožňuje registraci obslužného javascriptu i pro uživatelsky

definovaná pravidla.

4.7.3 Phalcon

Třidou reprezentující formulář je typ Phalcon\Forms\Form, který se na rozdíl od ostatních

frameworků může skládat pouze z tzv. elementů (třídy implementující rozhraní

Phalcon\Forms\ElementInterface). Pro Phalcon je tedy typickým znakem, že ve výchozím

stavu neumožňuje formulář rozdělit na samostatné logické části ani pomocí tzv. fieldsetů.

Page 65: Bachelor Thesis

4 Porovnání PHP frameworků 57

Způsob tvorby formuláře je principiálně podobný tomu, který byl představen v sekci Nette

i Zend. Jednotlivé prvky jsou přidávány obecnou metodou Form::add($element, $postion =

null, $type = null). Z porovnávaných frameworků obsahuje distribuce nejmenší počet typů

elementů, které lze ihned použít.

K elementům lze přidávat validační pravidla pomocí metody

ElementInterface::addValidator($validator). Pravidla jsou reprezentována tzv. validátory

(třídy implementující rozhraní Phalcon\Validation\ValidatorInterface), sadu výchozích

dostupných validátorů obsahuje jmenný prostor Phalcon\Validation\Validator. Tvorba

vlastních pravidel zákonitě vede k nutnosti deklarace dodatečných tříd.

Pro validaci formuláře slouží metoda Form::isValid($data = NULL, $entity = NULL), která

přijímá jako parametr zejména vstupní data formuláře odeslané uživatelem (v nejjedno-

dušším případě superglobální pole $_GET/$_POST).

Formuláře poskytují podobný mechanismus pro binding objektů jako framework Zend.

Vstupní objekt lze k formuláři připojit buď při jeho vytvoření (parametr konstruktoru) nebo

dodatečně pomocí metody Form::setEntity($entity). Názvy proměnných, které musejí být

pochopitelně deklarované jako veřejné, musí korespondovat s názvy příslušných formulářo-

vých prvků, podporovány jsou však i tzv. gettery a settery, které mají před třídními proměn-

nými přednost. Má-li však dojít ke zpětnému naplnění entity daty z formuláře, je zapotřebí

zavolat metodu Form::bind($data, $entity, $whitelist = NULL), případně tento krok vy-

nechat a data spolu s instancí vstupní entity předat metodě Form::isValid($data = NULL,

$entity = NULL). Tento krok je bohužel pro zaručení správného chování nutný a lze jej

považovat za poněkud zvláštní, protože neprobíhá automaticky.

Výpis 23: Příklad definice formuláře a jeho zpracování (Zdroj: autor)

// předpokládá se existence třídy SomeEntity s definovanými metodami // SomeEntity::setName($name) a SomeEntity::getName(). use Phalcon\Forms\Form, Phalcon\Forms\Element, Phalcon\Validation\Validator; $entity = new SomeEntity(); $entity->setName('default_name'); // $entity->getName() => ‘default_name’ $form = new Form($entity); $form->add(new Element\Text('name')); $form->get(‘name’)->addValidator(new Validator\PresenceOf()); $form->add(new Element\Submit('submit')); // $form->getValue(‘name’) => ‘default_name’ if ($form->isValid($_POST, $entity)) {

Page 66: Bachelor Thesis

4 Porovnání PHP frameworků 58

// uložení entity... // $entity->getName() => hodnota zadaná ve formuláři }

Vykreslit formulář lze dvěma způsoby:

1. Pomocí PHP kódu,

2. Pomocí šablonového systému Volt.

První metoda spočívá v kombinaci ručně psaného HTML (např. otevírací a ukončovací

značky tagu form) a používání kombinace metod Form::render($name, $attributes = NULL)

pro vykreslení formulářového prvku, resp. Form::label($name, $attributes = NULL)

pro vykreslení jeho popisku.

Alternativní metodou je využít šablonového systému Volt a sady předregistrovaných

funkcí50, které pro generování HTML kódu vnitřně používají tzv. užitkovou třídu (angl.

utility class) Phalcon\Tag. Obzvláště u této metody může vyvstat problém s udržitelností

zdrojového kódu formuláře, protože kód HTML formuláře nemusí odpovídat jeho logické

definici např. uvnitř řadiče. Každou změnu ve struktuře a názvosloví je pro zachování funkč-

nosti nutné promítnout i do kódu v šabloně.

4.8 Session a Cookies

4.8.1 Zend

Zend poskytuje vývojáři plnohodnotnou abstrakci od používání nativních funkcí PHP sou-

visejících se session. Balík komponent ze jmenného prostoru Zend\Session zajišťuje

následující funkce:

1. Konfigurace session – rozhraní Zend\Session\Config\ConfigInterface – nastavení

základních vlastností session jako je název nebo doba životnosti,

2. Session kontejner – třída Zend\Session\Container – slouží jako jednotné místo

pro uchovávání session dat, která tak lze ukládat do logicky oddělených částí (po-

mocí jmenného prostoru) (Zend Technologies Ltd., 2014),

3. Session manažer – rozhraní Zend\Session\ManagerInterface - správa session jako

celku (např. inicializace a ukončení session),

50 http://docs.phalconphp.com/en/latest/reference/volt.html#using-tag-helpers

Page 67: Bachelor Thesis

4 Porovnání PHP frameworků 59

4. Pro ukládání a čtení session dat slouží rozhraní

Zend\Session\SaveHandler\SaveHandlerInterface,

5. Úložiště session – rozhraní Zend\Session\Storage\StorageInterface – určuje typ

umístění session dat,

6. Validátory – rozhraní Zend\Session\Validator\ValidatorInterface – slouží ke sní-

žení rizika podvržení session (angl. session hijacking) (Zend Technologies Ltd.,

2014).

Jako význačná vlastnost se jeví skutečnost, že téměř všechny komponenty jsou vázány obec-

nými rozhraními, čili není problém nahradit výchozí komponenty za jiné. Za zmínku stojí

také fakt, že ne všechny komponenty vnitřně pracují přímo s nativními prostředky PHP

pro práci se session51, aby tak bylo dosaženo lepších možností nasazení např. na jiné sys-

témy.

Cookie, jelikož je druhem HTTP hlavičky, je reprezentována třídou

Zend\Http\Header\SetCookie. Pro přístup k seznamu cookies přijatých v HTTP požadavku

lze použít metody Zend\Http\Request::getCookie(). Přiklad použití cookies je uveden v ná-

sledujícím výpisu.

Výpis 24: Příklad použití cookies (Zdroj: autor)

// TestController.php use Zend\Http\Header\SetCookie; class TestController extends Zend\Mvc\Controller\AbstractActionController { public function indexAction() { // příchozí cookies $requestCookies = $requestHeaders = $this->getRequest()->getCookie(); // vytvoření nové HTTP cookie hlavičky $myCookie = new SetCookie( ‘myCookie’, // název ‘testValue’, // hodnota time() + 7200, // životnost ‘/’ // cesta ); // výstupní hlavičky HTTP odpovědi $responseHeaders = $this->getResponse()->getHeaders(); // přidání vytvořené cookie hlavičky

51 Např. funkce session_start() a superglobální proměnná $_SESSION.

Page 68: Bachelor Thesis

4 Porovnání PHP frameworků 60

$responseHeaders->addHeader($myCookie); // cookies odesílané spolu v HTTP odpovědi // již obsahuje $myCookie $responseCookies = $this->getResponse()->getCookie(); } }

4.8.2 Nette

Složitost abstrakce session je v porovnání se Zend výrazně nižší. Session data jsou rovněž

rozdělena do samostatných jmenných prostorů. V zásadě se lze setkat pouze s těmito kom-

ponentami:

1. Třída Nette\Http\Session – obálka nad nativními PHP funkcemi pro inicializaci

a ukončení session, pomocí které lze session zároveň konfigurovat; standardně je

součástí výchozích služeb frameworku a není ji nutné v rámci DI kontejneru manu-

álně vytvářet,

2. Session sekce - třída Nette\Http\SessionSection – kontejner pro session data (ob-

doba Zend\Session\Container),

3. Úložiště session dat - rozhraní Nette\Http\ISessionStorage (obdoba

Zend\Session\Storage\StorageInterface) – distribuce neobsahuje žádné jeho vý-

chozí implementace; od verze PHP 5.4 je navíc označen jako zavržený, jelikož PHP

definuje nativní rozhraní SessionHandlerInterface.

Výpis 25: Ukázka použití SessionSection v presenteru (Zdroj: autor)

class TestPresenter extends Nette\Application\UI\Presenter { /** @var string */ const MY_SESSION_SECTION_NAME = 'my_session_section_name'; public function actionDefault() { $sessionSection = $this->getSession(static::MY_SESSION_SECTION_NAME); $sessionSection->foo = 'bar'; echo $sessionSection->foo; // vypíše: // bar } }

Page 69: Bachelor Thesis

4 Porovnání PHP frameworků 61

Pro zpracování příchozích cookies slouží metoda rozhraní

Nette\Http\IRequest::getCookie($key, $default = NULL). Pro odeslání cookies formou

HTTP odpovědi pak metoda rozhraní Nette\Http\IResponse::setCookie($name, $value,

$expire, $path = NULL, $domain = NULL, $secure = NULL, $httpOnly = NULL). Pro repre-

zentaci cookie tedy neexistuje žádná frameworkem definovaná třída. V porovnání s frame-

workem Zend však Nette umožňuje jejich mazání skrze metodu

IResponse::deleteCookie($name, $path = NULL, $domain = NULL, $secure = NULL), vývojář

je proto odstíněn od způsobu, jakým ke smazání ve skutečnosti dojde (vynulování životnosti

dané cookie).

4.8.3 Phalcon

Session komponenty Phalcon jsou podobně jako u Nette oproti frameworku Zend relativně

málo rozčleněny. Pro práci se session ve frameworku Phalcon jsou zásadní následující roz-

hraní (jmenný prostor Phalcon\Session):

1. AdapterInterface,

2. BagInterface.

Upozornit je třeba na fakt, že dojde-li v rámci běhu skriptu k několikanásobnému instancio-

vání třídy Phalcon\Session\Adapter\Files (základní implementace AdapterInterface),

resp. nastartování session v jedné z nich, metoda Files::isStarted() v ostatních instancích

vrací FALSE, i když již session nastartována byla (byť v rámci jiné instance téže třídy).

Výpis 26: Příklad použití třídy Bag (Zdroj: autor)

$bag = new Bag(‘myBagNamespace’); $bag->foo = ‘bar’; // var_dump($bag->foo); // vypíše: // string(3) "bar"

Výpis 27: Příklad použití třídy Files (Zdroj: autor)

$files = new Files(array( 'uniqueId' => 'myUniqueNamespaceName', )); if (!$files->isStarted()) { // zde může potenciálně dojít k vyvolání // systémové chyby typu E_NOTICE $files->start(); }

Page 70: Bachelor Thesis

4 Porovnání PHP frameworků 62

$files->foo = 'bar'; // var_dump($files->foo); // vypíše: // string(3) "bar"

Třída Phalcon\Http\Response\Cookies nabízí zjednodušený způsob práce s cookies, protože

je není potřeba získávat z HTTP požadavku, existující cookies jsou automaticky součástí

HTTP odpovědi. Ke službě lze přistoupit v rámci DI kontejneru, podmínkou použití je buď

nastavení tzv. kryptovacího klíče (v případě, že není nastaven, dojde k upozornění hláškou)

nebo vypnutí kryptování. (Phalcon Team and contributors, 2014)

Výpis 28: Způsob zprovoznění služby cookies v rámci DI kontejneru (Zdroj: (Phalcon Team and

contributors, 2014))

////////////////////////////////// // 1. způsob // deaktivace kryptování $di->set('cookies', function() { $cookies = new Phalcon\Http\Response\Cookies(); $cookies->useEncryption(FALSE); return $cookies; }); ////////////////////////////////// // 2. způsob // nastavení kryptovacího klíče $di->set('crypt', function() { $crypt = new Phalcon\Crypt(); $crypt->setKey('#1dj8$=dp?.ak//j1V$'); return $crypt; });

Stejně jako ve frameworku Nette, nejsou jednotlivé cookies reprezentovány nějakou speci-

fickou třídou, nýbrž pro jejich nastavení, resp. získání slouží metoda

Phalcon\Http\Response\CookiesInterface::set($name, $value = NULL, $expire = NULL,

$path = NULL, $secure = NULL, $domain = NULL, $httpOnly = NULL),

resp. Phalcon\Http\Response\CookiesInterface::get($name).

Page 71: Bachelor Thesis

4 Porovnání PHP frameworků 63

4.9 Databázová abstrakce

4.9.1 Zend

Adaptér (třída Zend\Db\Adapter\Adapter) je základní komponentou zastřešující práci

s tzv. ovladači (angl. drivers) – třídami implementující rozhraní

Zend\Db\Driver\DriverInterface – určenými reprezentující jednotlivé databázové systémy.

Abecedně seřazeno se jedná o následující třídy (jmenný prostor Zend\Db\Driver):

IbmDb2\IbmDb2,

Mysqli\Mysqli,

Oci8\Oci8,

Pdo\Pdo,

Pgsql\Pqsql,

Sqlsrv\Sqlsrv.

Příklad použití Mysqli adaptéru pro získání seznamu všech knih uložených v databázi zná-

zorňuje následující výpis.

Výpis 29: Příklad použití databázového adaptéru (Zdroj: autor)

use Zend\Db\Adapter\Adapter, Zend\Db\Adapter\Driver\Mysqli; $connectionInfo = array( 'hostname' => '127.0.0.1', // localhost 'username' => 'foo', 'password' => 'bar', 'database' => 'test', ); $connection = new Mysqli\Connection($connectionInfo); $driver = new Mysqli\Mysqli($connection); $adapter = new Adapter($driver); $statement = $adapter->query('SELECT * FROM book'); $results = $statement->execute(); // vypíše názvy všech nalezených knih foreach ($results as $row) { echo ($row['name']) . '<br>'; }

Page 72: Bachelor Thesis

4 Porovnání PHP frameworků 64

Předchozí příklad lze přepsat do upravené podoby, ve které je dotaz konstruován přes spe-

ciální objektově orientované API:

Výpis 30: Tvorba dotazu za pomocí objektově orientovaného API (Zdroj: autor)

use Zend\Db\Adapter\Adapter, Zend\Db\Adapter\Driver\Mysqli, Zend\Db\Sql\Sql; $connectionInfo = array( 'hostname' => '127.0.0.1', // localhost 'username' => '', 'password' => '', 'database' => 'test', ); $connection = new Mysqli\Connection($connectionInfo); $driver = new Mysqli\Mysqli($connection); $adapter = new Adapter($driver); $sql = new Sql($adapter); $select = $sql->select(); $select->from('book'); $statement = $adapter->query($sql->getSqlStringForSqlObject($select)); $results = $statement->execute(); // vypíše názvy všech nalezených knih foreach ($results as $row) { echo $row['name'] . '<br>'; }

Pro konstrukci DDL dotazů lze využít vyčleněného API poskytovaného třídou

Zend\Db\Sql\Ddl, příklad použití je uveden v následujícím výpisu. Jeho možnosti jsou sice

omezené, nicméně základní operace, jako jsou vytváření a mazání tabulek podporovány jsou

(každá operace reprezentována zvláštní třídou)

Výpis 31: Příklad sestavení DDL dotazu objektově orientovaným způsobem (Zdroj: autor)

use Zend\Db\Adapter\Adapter, Zend\Db\Adapter\Driver\Mysqli, Zend\Db\Sql\Sql, Zend\Db\Sql\Ddl; $connectionInfo = array( 'hostname' => '127.0.0.1', // localhost 'username' => '', 'password' => '', 'database' => 'test', );

Page 73: Bachelor Thesis

4 Porovnání PHP frameworků 65

$connection = new Mysqli\Connection($connectionInfo); $driver = new Mysqli\Mysqli($connection); $adapter = new Adapter($driver); // definice nové dočasné tabulky (druhý parametr) $ddl = new Ddl\CreateTable('my_temporary_table', TRUE); $ddl->addColumn(new Ddl\Column\Integer('id', FALSE)); $ddl->addColumn(new Ddl\Column\Varchar('name', 255)); $sql = new Sql($adapter); $adapter->query( $sql->getSqlStringForSqlObject($ddl), // vygenerování výsledného SQL Adapter::QUERY_MODE_EXECUTE // příkaz se vykoná okamžitě );

Obdobně jako v případě formulářů je i zde možné použít tzv. hydrátorů, pomocí kterých lze

výsledky (řádky tabulky) převést na instance uživatelsky definovaných tříd reprezentujících

obvykle tzv. business entity doménového modelu. K tomuto účelu slouží třída

Zend\Db\ResultSet\HydratingResultSet, které stačí předat konkrétní typ hydrátoru a instanci

výstupní třídy. Použitím metody HydratingResultSet::initialize($dataSource) následně

dojde k procesu mapování vstupních hodnot řádků na volitelné třídní proměnné nově vytvo-

řených instancí objektu reprezentující zvolenou entitu.

Pro účely získání užitečných informací o prováděných dotazech lze použít tzv. profiler (třída

Zend\Db\Adapter\Profiler\Profiler), který poskytuje data o době vykonání dotazu a jeho

skutečné podobě ve formě SQL. Samotné ukládání (logování) těchto dat zůstává již na vý-

vojáři.

4.9.2 Nette

Nette stejně jako Zend podporuje několik nejpoužívanějších databázových systémů. Termi-

nologie zavedené v této souvislosti se rovněž neliší – zavedení tzv. ovladačů (tříd implemen-

tujících rozhraní Nette\Database\ISupplementalDriver). Podporované ovladače se nacházejí

ve jmenném prostoru Nette\Database\Drivers:

MsSqlDriver,

MySqlDriver,

OciDriver,

OdbcDriver,

PgSqlDriver,

Page 74: Bachelor Thesis

4 Porovnání PHP frameworků 66

Sqlite2Driver,

SqliteDriver,

SqlsrvDriver.

V principu existují v Nette (stejně jako ve frameworku Zend) dva způsoby pokládání dotazů:

1. Použití metody Nette\Database\Context::query($statement) pro tvorbu dotazů po-

mocí textového řetězce ve formátu SQL,

2. Použití tzv. tabulkového výběru Nette\Database\Table\Selection, pomocí kterého

lze tvořit dotazy již ve stylu objektově orientovaného API.

Příklad uvedený níže znázorňuje princip použití druhého způsobu.

Výpis 32: Příklad použití tabulkového výběru v Nette (Zdroj: autor)

use Nette\Database\Connection, Nette\Database\Context; $connection = new Connection('mysql:host=127.0.0.1;dbname=test'); $context = new Context($connection); $selection = $context->table('book'); // vypíše názvy všech knih foreach ($selection->fetchAll() as $book) { echo $book->name . PHP_EOL; } // vypíše názvy všech knih, jejichž autorem je Dan Brown foreach ($selection->where(array('author' => 'Dan Brown')) as $book) { echo $book->name . PHP_EOL; } // vypíše seznam všech knih a názvy k nim přiřazených tagů foreach ($selection as $book) { echo $book->name . ':' . PHP_EOL; foreach ($book->related('book_tag') as $bookTag) { echo $bookTag->tag->name . PHP_EOL; } echo PHP_EOL; }

Page 75: Bachelor Thesis

4 Porovnání PHP frameworků 67

Poslední z příkladů má za cíl demonstrovat možnost jednoduchého dotazování se do refe-

renčních tabulek propojených skrze cizí klíče bez nutnosti psát samostatné omezující52 do-

tazy. Navíc, díky „chytré“ implementaci se ve skutečnosti provedou pouze tři dotazy.

Následně se při každém průchodu cyklu již jen odfiltrují patřičné řádky dle referenční vazby.

Nette jako jediný z porovnávaných frameworků neposkytuje žádné vyhrazené API pro sklá-

dání DDL dotazů.

Logování dotazů, ač je ponecháno na vývojáři, je možné jej realizovat poměrně snadno díky

události Connection::onQuery, která vyvstane po (ne)úspěšném vykonání SQL dotazu.

Výpis 33: Princip zpracování události Connection::onQuery (Zdroj: autor)

use Nette\Database\Connection, Nette\Database\Context, Nette\Database\ResultSet; $connection = new Connection('mysql:host=127.0.0.1;dbname=test'); $context = new Context($connection); $connection->onQuery[] = function (Connection $connection, $result) { // v případě, že dojde během pokládání dotazu k vyvolání výjimky, // je její hodnota předána v hodnotě parametru $result, // jinak parametr obsahuje výsledek dotazu if ($result instanceof ResultSet) { echo $result->getQueryString() . PHP_EOL; } else { error_log($result->message); } }; $selection = $context->table('book');

4.9.3 Phalcon

Seznam standardně podporovaných databázových systémů čítá čtyři třídy – adaptéry

(jmenný prostor Phalcon\Db\Adapter\Pdo):

Mysql,

Oracle,

Postgresql,

52 Myšleno dotazy restriktivního charakteru.

Page 76: Bachelor Thesis

4 Porovnání PHP frameworků 68

Sqlite.

Phalcon se odlišuje od ostatních frameworků tím, že API pro objektově orientované skládání

souvisí s konkrétními modely, což jsou obecně třídy implementující rozhraní

Phalcon\Mvc\ModelInterface (výchozím předkem pro nejrychlejší tvorbu uživatelských mo-

delů je třída Phalcon\Mvc\Model). Model jako takový v podstatě reprezentuje databázovou

tabulku jako takovou, zároveň však i jeden záznam této tabulky.

Pro manipulaci s modely slouží vlastní „vysoko-úrovňový“ jazyk PHQL (Phalcon Query

Language). V praxi to znamená, že v dotazech je a musí být abstrahováno od názvů fyzic-

kých tabulek, resp. sloupců a místo nich se použije názvů modelů (tříd), resp. třídních pro-

měnných. Pro konstrukci dotazů objektově orientovaným způsobem lze využít třídy

Phalcon\Mvc\Model\Query\Builder, viz následující výpis.

Výpis 34: Příklad použití třídy Builder pro konstrukci PHQL dotazu

(Zdroj: (Phalcon Team and contributors, 2014))

// předpokládá existence modelů Robots a RobotsParts // $builder instanceof Phalcon\Mvc\Model\Query\BuilderInterface $rows = $builder->from('Robots') ->join('RobotsParts') ->orderBy('Robots.name') ->getQuery() ->execute();

Aplikační rozhraní adaptéru (vyplívající z rozhraní Phalcon\Db\AdapterInterface) je po-

měrně „košaté“, jelikož kromě metod určených k získávání informací o struktuře databázo-

vých objektů, obsahuje i metody pro konstrukci DDL dotazů, jejichž výsledná podoba je

pochopitelně vnitřně korigována tak, aby odpovídala specifikům konkrétního databázového

systému. I ty však, stejně jako v případě Zend, mají svá omezení (nelze např. určit kolaci

tabulky/sloupce).

Výpis 35: Ukázka přístupu k MySQL databázi v prostředí Phalcon (Zdroj: autor)

use Phalcon\Db\Adapter\Pdo\Mysql, Phalcon\Db\Column; $config = array( 'host' => '127.0.0.1', // localhost 'dbname' => 'test', ); $mysql = new Mysql($config); // dotaz vytvořený „manuálně“ $books = $mysql->query('SELECT * FROM `book`')->fetchAll(); // vypíše názvy všech nalezených knih

Page 77: Bachelor Thesis

4 Porovnání PHP frameworků 69

foreach ($books as $book) { echo $book['name'] . PHP_EOL; } // vloží do tabulky `book` nový záznam (novou knihu) $mysql->insert( // název tabulky 'book', // hodnoty array( 6, 'My book', 'John Doe', date('Y-m-d'), ), // názvy sloupců array( 'id', 'name', 'author', 'date_published', ) ); // pokusí se vytvořit novou tabulku `test_table` v databázi `test` $mysql->createTable( 'test_table', 'test', array( 'columns' => array( new Column( 'id', array( 'type' => Column::TYPE_INTEGER, 'notNull' => TRUE, 'unsigned' => TRUE, 'primary' => TRUE, 'autoIncrement' => TRUE, ) ), new Column( 'name', array( 'type' => Column::TYPE_VARCHAR, 'size' => 255, 'notNull' => TRUE, ) )

Page 78: Bachelor Thesis

4 Porovnání PHP frameworků 70

), ) );

Podobně jako ve frameworku Zend lze (nejen) pro účely logování využít událostí53, které

jsou za předpokladu připojeného správce událostí (EventsManager) automaticky vyvolávány,

z nichž nejdůležitější je asi ta následující po vykonání SQL dotazu.

Výpis 36: Způsob zpracování databázových událostí v prostředí Phalcon (Zdroj: autor)

use Phalcon\Db\Adapter\Pdo\Mysql, Phalcon\Db\Profiler, Phalcon\Events\Manager; $profiler = new Profiler(); $eventsManager = new Manager(); $eventsManager->attach( 'db:beforeQuery', function ($event, $mysql) use ($profiler) { $profiler->startProfile($mysql->getSQLStatement()); var_dump('before query: ' . $mysql->getSQLStatement()); } ); $eventsManager->attach( 'db:afterQuery', function ($event, $mysql) use ($profiler) { $profiler->stopProfile(); var_dump('after query: ' . $mysql->getSQLStatement()); } ); $mysql = new Mysql(array( 'host' => '127.0.0.1', // localhost 'dbname' => 'test', )); $mysql->setEventsManager($eventsManager); $books = $mysql->query('SELECT * FROM `book`'); var_dump($profiler->getLastProfile()->getTotalElapsedSeconds()); // vypíše: // string(34) "before query: SELECT * FROM `book`"

53 Seznam a popis všech událostí je k dispozici na http://docs.phalconphp.com/en/latest/re-

ference/db.html#database-events.

Page 79: Bachelor Thesis

4 Porovnání PHP frameworků 71

// string(33) "after query: SELECT * FROM `book`" // float(0.00037813186645508)

4.10 Autorizace, autentizace

4.10.1 Zend

Pro autentizaci uživatele framework definuje tzv. adaptéry. Za adaptér lze považovat jakou-

koliv třídu, která implementuje rozhraní Zend\Authentication\Adapter\AdapterInterface

deklarující jedinou metodu AdapterInterface::authenticate(). Účelem této metody je vrátit

výsledek ve formě Zend\Authentication\Result (v případě, že autentizaci nelze z nějakého

důvodu provést, měla by metoda vyvolat výjimku typu

Zend\Authentication\Adapter\Exception\ExceptionInterface). Několik výchozích typů

adapterů obsahuje již zmíněný jmenný prostor Zend\Authentication\Adapter.

Na základě výsledku autentizace lze pak určit, zdali byla úspěšná. Metodu

Result::getCode() je možné využít např. pro rozlišení různých chybových stavů, na základě

kterých autentizace selhala. Třídě by mělo být při chybné autentizaci předáno pole souvise-

jících chybových zpráv, které pak lze následně získat pomocí metody

Result::getMessages(). V případě úspěšné autentizace by měla metoda

Result::getIdentity() vracet tzv. identitu (např. objekt reprezentující uživatele), její přes-

nou podobu však třída nespecifikuje a je tedy plně v kompetenci vývojáře, jaký konkrétní

datový typ bude metoda vracet.

Nadstavbou adaptérů, která umožňuje i ukládání výsledku úspěšné autentizace (identity) je

třída Zend\Authentication\AuthenticationService (autentizační třída), která implementuje

rozhraní autentizační služby Zend\Authentication\AuthenticationServiceInterface. Au-

tentizační třída pro ukládání identity používá zvláštní rozhraní reprezentující typ úložiště

Zend\Authentication\Storage\StorageInterface (ve výchozím stavu je použit typ

Zend\Authentication\Storage\Session).

Navzdory tomu, že framework rozlišuje dva specifické typy autorizačního mechanismu,

žádné obecné rozhraní pro definici autorizátoru nedeklaruje. Jmenný prostor

Zend\Permissions obsahuje následující dvě sady tříd a rozhraní:

1) ACL,

2) Rbac.

Metody řízení přístupů jsou si navzájem podobné, obě vycházejí z principu existence urči-

tých rolí, kterým je umožněn, či zakázán přístup k určitému zdroji. Rozdíl lze vypozorovat

Page 80: Bachelor Thesis

4 Porovnání PHP frameworků 72

ze signatury metod AclInterface::isAllowed($role = null, $resource = null, $privilege

= null) a Rbac::isGranted($role, $permission, $assert = null). ACL akcentuje potřebu

řízení přístupu na základě rolí, kterým je povolen/zakázán přístup k určitým zdrojům

(pro přesnější specifikaci typu oprávnění slouží třetí nepovinný parametr – např. čtení, zápis

apod.), zatímco Rbac klade větší důraz na definování vztahu rolí a k nim definovaných opráv-

nění.

Zend jde co do možností zvýšení zabezpečení tak daleko, že pro hešování hesel deklaruje

vlastní rozhraní Zend\Crypt\Password\PasswordInterface, z nich vychází dvě základní im-

plementace (jmenný prostor Zend\Crypt\Password) (Zend Technologies Ltd., 2014):

Bcrypt – implementuje doporučovaný způsob hešování hesel tzv. bcrypt algoritmus,

Apache – podporuje hešovací mechanismy dané webovým serverem Apache54.

4.10.2 Nette

Pro ověření identity uživatele slouží tzv. autentizátor – třída implementující rozhraní

Nette\Security\IAuthenticator, resp. jeho metoda IAuthenticator::authenticate(array

$credentials), která na rozdíl od frameworku Zend přijímá jako parametr identifikační

údaje uživatele, na základě kterých má dojít k autentizaci.

Dalším rozdílem je to, že metoda nevrací nějaký obecný výsledek, nýbrž při úspěšné auten-

tizaci již konkrétní identitu uživatele (třídu implementující rozhraní

Nette\Security\IIdentity). Za opačné situace (při neúspěšném ověření) by mělo dojít k vy-

volání příslušné výjimky Nette\Security\AuthenticationException. Způsob rozlišení chy-

bových stavů je tedy ponechán na vývojáři.

Z pohledu příchozího HTTP požadavku je uživatel reprezentován třídou

Nette\Security\User, která obsahuje metody pro přihlašování a odhlašování uživatele a rov-

něž jeho identitu získanou autentizací. Pro ukládání těchto dat slouží rozhraní

Nette\Security\IUserStorage, ve výchozím stavu je použito ukládání do session (třída

Nette\Http\UserStorage).

Ve srovnání s ostatními frameworky se Nette odlišuje svým postojem vůči autorizaci tím, že

pro něj deklaruje obecné rozhraní Nette\Security\IAuthorizator (tzv. autorizátor) a ACL

(třídu Nette\Security\Permission), již považuje za jednu z konkrétních možností jeho im-

plementace. Ze signatury autorizační metody IAuthorizator::isAllowed($role, $resource,

$privilege) vyplývá, že autorizace spočívá v ověření, že určitá role má/nemá specifikované

oprávnění k danému zdroji (ostatně, z tohoto principu vychází i ostatní frameworky). Třída

Permission z velké části vychází z Zend\Permission\Acl.

54 http://httpd.apache.org/docs/2.2/misc/password_encryptions.html

Page 81: Bachelor Thesis

4 Porovnání PHP frameworků 73

Nette neobsahuje žádný kryptovací nástroj pro hešování hesel.

4.10.3 Phalcon

Oproti zbývajícím frameworkům Phalcon neobsahuje žádný předurčený autentizační systém

a uživatel tak není nijak identifikován. Pozornost tak lze věnovat jedině autorizaci a zabez-

pečení hesel.

Autorizační systém je založený na ACL, pro nějž bylo zavedeno rozhraní

Phalcon\Acl\AdapterInterface. Výchozím typem pro definici přístupových práv je třída

Phalcon\Acl\Adapter\Memory. Její název má za účel akcentovat fakt, že nakonfigurovaná

oprávnění jsou během doby vykonání skriptu uložena v operační paměti. Z podstaty věci se

však funkcionalita pochopitelně neliší od výše zmíněných Nette\Security\Permission

a Zend\Permissions\Acl\Acl, které co se týče názvu, abstrahují od způsoby uložení konfigu-

race.

Zásadním rozdílem, který ovlivňuje celkové zabezpečení aplikace je fakt, že adaptér Memory

ve výchozím stavu přístup k veškerým zdrojům povoluje. Pro změnu tohoto chování je za-

potřebí použít metodu AdapterInterface::setDefaultAction($defaultAccess), kde pro hod-

notu parametru $defaultAccess je vhodné použít předdefinovaných konstant:

Phalcon\Acl::DENY – zakázání přístupu,

Phalcon\Acl::ALLOW – povolení přístupu.

Pro hešování hesel je přímo určená metoda Phalcon\Security::hash($password,

$workFactor = NULL), která vnitřně používá bcrypt algoritmus stejně jako

např. Zend\Crypt\Password\Bcrypt. Pro zpětné porovnání hesla v syrové a zahešované po-

době slouží metoda Phalcon\Security::checkHash($password, $passwordHash,

$maxPasswordLength = null).

4.11 Lokalizace

4.11.1 Zend

Zend je ve svém přístupu k lokalizaci, resp. internacionalizaci ve srovnání s ostatními po-

rovnávanými frameworky jednoznačně nejobšírnější. Pro podporu univerzálního způsobu

lokalizace aplikace je zavedeno rozhraní Zend\I18n\Translator\TranslatorInterface dekla-

rující metody pro překlad zpráv:

Page 82: Bachelor Thesis

4 Porovnání PHP frameworků 74

TranslatorInterface::translate($message, $textDomain = 'default', $locale =

NULL),

TranslatorInterface::translatePlural($singular, $plural, $number, $textDomain

= 'default', $locale = NULL).

Zdrojem přeložených zpráv může být jakákoliv třída implementující rozhraní

Zend\I18n\Translator\Loader\RemoteLoaderInterface, resp. Zend\I18n\Translator\Loa-

der\FileLoaderInterface (v případě, že se přepokládá, že se zdrojová data načítají ze sou-

boru).

Pro lokalizaci údajů týkajících se data a času, měny a číselných hodnot slouží pohledové

helpery nacházející se ve jmenném prostoru Zend\I18n\View\Helper (příslušné pluginy jsou

v šabloně k dispozici standardně automaticky).

Specifický účel plní tzv. filtry (jmenný prostor Zend\I18n\Filter), které slouží (s určitým

omezením55) k úpravě vstupního textového řetězce a validátory (jmenný prostor

Zend\I18n\Validator), které dokáží ověřit platnost např. data a času, číselné hodnoty či tele-

fonního čísla s ohledem na cílenou zemi (angl. locale).

Celkově vzato automaticky nejsou lokalizované žádné součásti frameworku, byť

např. v rámci pohledu lze snadno použít výchozích helperů, k lokalizaci musí dojít expli-

citně. Zejména při použití DI/service locatoru se lokalizace stává poměrně jednoduchou čin-

ností bez nutnosti psát vlastní lokalizační logiku.

4.11.2 Nette

O poznání volnější vztah k lokalizaci je patrný na první pohled, neboť jedinou součástí fra-

meworku, která s lokalizací souvisí, je rozhraní Nette\Localization\ITranslator (překla-

dač). Protože logika překládání může být poměrně různorodá, framework žádnou výchozí

implementaci nenabízí56.

Přesto framework s možností lokalizace „počítá“, a to tím, že např. jeho šablonový jazyk

Latte podporuje makro pro překlad textových zpráv. Rovněž implementace formulářové

komponenty, resp. jeho prvků je vytvořena tak, aby jej bylo možné snadno lokalizovat, a to

pouhým specifikováním konkrétního překladače pomocí metody

Nette\Forms\Form::setTranslator(Nette\Localization\ITranslator $translator = NULL).

55 Nejsou podporovány všechny druhy jazyků, viz http://framework.zend.com/ma-

nual/2.3/en/modules/zend.i18n.filters.html.

56 K dispozici jsou však volně šiřitelná rozšíření (např. http://addons.nette.org/#toc-locali-

zation).

Page 83: Bachelor Thesis

4 Porovnání PHP frameworků 75

4.11.3 Phalcon

Phalcon jako jediný žádné lokalizační prostředky (třídy/rozhraní) nenabízí. Bylo-li by tomu

opačně, pak by tato skutečnost dle (Phalcon Team and contributors, 2014) vedla k pouhé

reduplikaci existujícího kódu. Nicméně na stejném místě je alespoň uvedena (ba přímo do-

poručena) alternativa v podobě specializované knihovny intl57, kterou koneckonců interně

využívá i Zend.

4.12 Využití cache

4.12.1 Zend

Systém umožňující používat cache je v Zend, jako je tomu i v mnoha jiných případech, re-

lativně nejsložitější58 a skládá se z následujících komponent:

Úložiště – rozhraní Zend\Cache\Storage\StorageInterface – třídy vycházející z to-

hoto rozhraní „jsou obálkami nad jejich skutečnými zdroji, které reprezentují (např.

souborový systém, paměť apod.)“ (Zend Technologies Ltd., 2014), konkrétní úlo-

žiště lze díky celkově dodávanému počtu typů poměrně jednoduše zaměnit za jiný,

Omezení/možnosti úložiště – třída Zend\Cache\Storage\Capabilities (např. mini-

mální, resp. maximální doba životnosti jednotlivých položek uložených v cache),

Rozšíření - Zend\Cache\Storage\Plugin\PluginInterface – jsou to „objekty,

za pomoci kterých lze ovlivnit chování konkrétního úložiště“ (Zend Technologies

Ltd., 2014),

Cache vzory – rozhraní Zend\Cache\Pattern\PatternInterface – představují

„konfigurovatelné objekty mající za cíl řešení častých výkonnostních problémů“

(Zend Technologies Ltd., 2014).

Jak je možné zpozorovat, Zend abstrahuje od existence jakéhosi „globálního“ správce ca-

che, nýbrž veškerá logika cache je zakomponována přímo v konkrétních adaptérech. Cache

vzory poskytují možnosti, jak cache využít v určitých specifických situacích (např. pro uklá-

dání návratových hodnot callbacků nebo za účelem zachycení výstupu PHP skriptu do ca-

che).

57 http://www.php.net/manual/en/intro.intl.php

58 Nejsložitější ve smyslu počtu komponent, které s cache souvisí.

Page 84: Bachelor Thesis

4 Porovnání PHP frameworků 76

Základní princip práce s cache úložištěm znázorňuje Výpis 37. Vícenásobné přidání položky

pod stejným klíčem původní hodnotu nepřepíše, pro přepsání je nutné použít zvláštní metodu

StorageInterface::replaceItem($key, $value), resp. její alternativu pro přepsání několika

položek najednou StorageInterface::replaceItems(array $keyValuePairs).

Výpis 37: Příklad použití cache úložiště (Zdroj: autor)

use Zend\Cache\Storage\StorageInterface, Zend\Cache\Storage\Adapter\Filesystem, Zend\Cache\Storage\Adapter\FilesystemOptions; $options = new FilesystemOptions(); $options->setCacheDir('C:\temp'); $cache = new Filesystem($options); $cacheKey = 'myCacheKey'; if (!$cache->hasItem($cacheKey)) { $cache->addItem($cacheKey, 'some cached value'); } $value = $cache->getItem($cacheKey); var_dump($value); // vypíše // string(17) "some cached value" // Pro specifické případy, kdy chceme k hodnotě položky přičíst, resp. odečíst // určitou hodnotu slouží metoda StorageInterface::incrementItem($key, $value), // resp. StorageInterface::decrementItem($key, $value), přičemž položka nemusí // v cache existovat (bude automaticky vytvořena s hodnotou $value).

Zend v rámci jednoho úložiště neumožňuje ovlivnit parametry cache na úrovni jednotlivých

položek. Samostatné položce proto nelze nastavit např. dobu její životnosti. Možné je pouze

resetování její životnosti pomocí metody StorageInterface::touchItem($key), resp. Sto-

rageInterface::touchItems(array $keys). Zneplatnění položky lze dosáhnout jejím odstra-

něním z úložiště pomocí StorageInterface::removeItem($key),

resp. StorageInterface::removeItems(array $keys).

Výpis 38: Příklad použití cache vzoru Zend\Cache\Pattern\CallbackCache (Zdroj: autor)

use Zend\Cache\Pattern\CallbackCache, Zend\Cache\Pattern\PatternOptions; function myFunction() { // náročná operace ... } $cache = new CallbackCache();

Page 85: Bachelor Thesis

4 Porovnání PHP frameworků 77

$cache->setOptions(new PatternOptions(array( 'storage' => 'memory', // nutné specifikovat typ úložiště ))); $cache->call(‘myFunction’); /////////////////////////////////////////////////////////// // anonymní funkce použít nelze (týká se všech frameworků), // dojde k vyvolání výjimky vyplívající z vlastností PHP $cache->call(function () { // náročná operace ... });

4.12.2 Nette

Struktura cache systému Nette se skládá z dvou částí:

1. Cache - třída Nette\Caching\Cache - zapouzdřující základní logiku cache voláním

příslušných metod úložiště (viz dále),

2. Úložiště - rozhraní Nette\Caching\IStorage – podobně jako v ostatní frameworky,

Nette podporuje vícero typů (součástí distribuce – jmenný prostor

Nette\Caching\Storages – je několik standardních typů: např. MemoryStorage,

FileStorage, atd.).

Třída Cache má v porovnání se svými ekvivalenty v jiných frameworcích, svá specifika,

protože podporuje přizpůsobení/změnu určitého chování na úrovni jednotlivých položek.

Rovněž je abstrahováno od rozdílu jejich přidávání a následného přepisování, pro obě akce

slouží jediná metoda Cache::save($key, $data, array $dependencies = NULL).

Výpis 39: Příklad použití Nette\Caching\Cache (Zdroj: autor)

use Nette\Caching\Cache, Nette\Caching\Storages\FileStorage; $fileStorage = new FileStorage('C:\temp'); $cache = new Cache($fileStorage); $cacheKey = 'myCacheKey'; // callback daný druhým parametrem metody Cache::load // slouží k prvotní inicializaci položky v případě, že neexistuje $value = $cache->load($cacheKey, function (&$dependencies) { // nastavení parametrů cache položky $dependencies = array( // automatická expirace za 30 minut Cache::EXPIRE => '+30 minutes',

Page 86: Bachelor Thesis

4 Porovnání PHP frameworků 78

// automatický reset životnosti při nahrání položky Cache::SLIDING => TRUE, ); return 'my cached value'; }); var_dump($value); // vypíše: // string(15) "my cached value"

Manuální invalidace položky spočívá v jejím smazání metodou Cache::remove($key).

Nette podobně jako Zend umožňuje ukládat do cache i výsledky callback funkcí a ukládání

výstupu PHP, odlišuje se však tím, že pro tuto funkcionalitu nevymezuje žádnou další vrstvu

(obdobu Zend\Cache\Pattern\PatternInterface) a je součástí API třídy Cache, která navíc

kromě již zmíněných konfiguračních parametrů podporuje další reprezentované těmito kon-

stantami (Nette Foundation, 2014):

Cache::FILES – platnost položky může být odvislá na změně jednoho nebo více sou-

borů,

Cache::ITEMS – určuje závislost na platnosti jiných položek (v případě, že se zneplatní

jedna z nich, dojde k zneplatnění i této položky),

Cache::TAGS – přiřadí položce tag(y), usnadňující hromadnou invalidaci položek,

Cache::PRIORITY – slouží k hromadnému zneplatnění položek na základě jejich prio-

rity.

Nette poskytuje jednoduchou možnost, jak ovlivnit konkurenční chování související s uklá-

dáním položek do cache v případě několika souběžně běžících skriptů. V případě, že získání

zdrojových dat, resp. jejich uložení má být umožněno jedinému vláknu, pak lze jako hodnotu

položky uvést callback či anonymní funkci, jak ukazuje Výpis 40.

Výpis 40: Konkurenční chování ukládání cache položky (Zdroj: (Nette Foundation, 2014))

$result = $cache->save($key, function() { // nebo callback(...) return buildData(); // náročná operace });

4.12.3 Phalcon

Pojetí cache v frameworku Phalcon je vymezeno podobně jako u frameworku Nette dvěma

samostatnými částmi (Phalcon Team and contributors, 2014):

Page 87: Bachelor Thesis

4 Porovnání PHP frameworků 79

1. Tzv. frontend – rozhraní Phalcon\Cache\FrontendInterface – konkrétní typy po-

dávají de facto informaci o původu dat, které mají být uloženy do cache a zároveň

definují způsob jejich případné modifikace, těsně před tím než má proběhnout fak-

tické uložení (stejně tak obráceně při čtení dat z tzv. backendu mohou být zdrojová

data transformována do konečné původní podoby),

2. Tzv. backend – rozhraní Phalcon\Cache\BackendInterface – jeho význam je

de facto totožný s tím, jaký mají cache úložiště v Zend a Nette.

Následující Výpis 41 demonstruje princip použití Phalcon cache. Stejně jako v systému

Nette lze položce nastavit max. dobu její životnosti. Avšak žádné další možnosti Phalcon již

nepodporuje.

Výpis 41: Příklad použití cache systému Phalcon (Zdroj: autor)

use Phalcon\Cache\Frontend\Data, Phalcon\Cache\Backend\File; $frontend = new Data(); $backend = new File($frontend, array( // cesta musí končit lomítkem, jinak dojde k chybné intepretaci cesty 'cacheDir' => 'C:\temp\\', )); $cacheKey = 'myCacheKey'; if (NULL === ($value = $backend->get($cacheKey))) { $value = 'my cached value'; $lifetime = 1800; // nastavení životnosti položky v sekundách $backend->save($cacheKey, $value, $lifetime); } var_dump($value); // invalidace položky $backend->delete($cacheKey); var_dump($backend->exists($cacheKey)); // script vypíše: // string(15) "my cached value" // bool(false)

Page 88: Bachelor Thesis

4 Porovnání PHP frameworků 80

4.13 Ladění a zpracování chyb

4.13.1 Zend

Pro vizualizaci výjimek nabízí Zend možnost definovat samostatnou šablonu. Pomocí kon-

figurace pohledového manažera (třída Zend\Mvc\View\Http\ViewManager) lze nastavit cestu

k této šabloně. Chybové stavy související s nenalezením určité stránky je možné prezentovat

na samostatné šabloně. Standardizovaný způsob zobrazení chyb a s nimi souvisejících infor-

mací framework nenabízí. Bohužel, dojde-li k chybám, framework je ve výchozím stavu

sám nezachytí a patřičnou chybovou stránku nezobrazí (rozdíl mezi chybami a výjimkami).

Výpis 42: Příklad nastavení chybových šablon (Zdroj: autor)

$config = array( ‘view_manager’ => array( ‘exception_template’ => ‘error/index.phtml’, ‘not_found_template’ => ‘error/404.phtml’, ), );

Pro podporu ladění nabízí Zend samostatný balíček ZendDeveloperTools59, který však není

součástí standardní distribuce. Nástroj poskytuje základní informace mj. o době vykonání

skriptu (včetně rozlišení jednotlivých událostí), alokované paměti a informace o aktuálním

požadavku (řadič, akce a použitá šablona). Panel je složen z tzv. kolektorů (angl. collectors)

– tříd implementujících rozhraní ZendDeveloperTools\Collector\CollectorInterface.

Speciální pomůckou pro účely ladění je metoda Zend\Debug\Debug::dump($var, $label =

NULL, $echo = NULL), kterou lze vypisovat obsah dané proměnné. Framework ve srovnání

s použitím nativní funkce var_dump přináší přidanou hodnotu tím, že výpis je přehledněji

formátován a lze jej doplnit o volitelný popisek.

Není velkým překvapením, že Zend nabízí vlastní nástroj i pro logování. Jedná se o třídu

Zend\Log\Logger (dále jen logger) implementující rozhraní Zend\Log\LoggerInterface. Log-

ger pro svoji činnost vyžaduje přiřazení alespoň jednoho zapisovače (třída implementující

rozhraní Zend\Log\Writer\WriterInterface), jinak dojde při použití jedné z logovacích me-

tod k vyvolání výjimky (způsobeno „neprůhlednou“ definicí konstruktoru, které přijímá

jako jediný parametr konfigurační pole – ostatně jako četná řada dalších tříd frameworku).

Výpis 43: Příklad použití třídy Logger (Zdroj: autor)

use Zend\Log\Logger, Zend\Log\Writer\Stream;

59 https://github.com/zendframework/ZendDeveloperTools

Page 89: Bachelor Thesis

4 Porovnání PHP frameworků 81

$var = array( 'foo' => 'bar', ); $writer = new Stream('C:\my_log.txt'); $logger = new Logger(); $logger->addWriter($writer); $logger->debug($var); $logger->info('some info message'); // obsah souboru C:\my_log.txt // 2014-04-26T17:05:43+02:00 DEBUG (7): array ('foo' => 'bar', ) // 2014-04-26T17:05:43+02:00 INFO (6): some info message

Možnosti loggeru jsou dále rozšířeny o tyto části (Zend Technologies Ltd., 2014):

filtry (rozhraní Zend\Log\Filter\FilterInterface) – zamezují logování určitých

hodnot (v závislosti na konkrétním použitém filtru),

formátovače (rozhraní Zend\Log\Formatter\FormatterInterface) – jejich úlohou je

provést volitelnou konverzi vstupní hodnoty do konečné podoby, která bude zalogo-

vána.

4.13.2 Nette

Uživatelsky definované zpracování výjimek ovlivňuje zejména třídní proměnná

Nette\Application::catchExceptions, jejíž hodnota by měla být typu boolean. Pokud je na-

stavena na hodnotu TRUE a dojde k vyvolání výjimky, která není zachycena, aplikační třída

automaticky přesměruje aplikační požadavek na tzv. chybový presenter (angl. Error Presen-

ter). Název presenteru, resp. jeho třídy je dán nastavením v konfiguračním souboru aplikace.

Ve výchozí akci presenteru, resp. vykreslovací části (metoda actionDefault($exception),

resp. renderDefault($exception)), probíhá zpracování samotné výjimky (typicky vykreslení

pohledu, kde šablony lze samozřejmě přizpůsobit různých typům výjimek).

Obdobou ZendDeveloperTools je nástroj Nette\Diagnostics\Debugger, který se však liší

svojí podporou pro vizualizaci výjimek i chyb (třída Nette\Diagnostics\BlueScreen). Jeho

aktivace se standardně projeví v zobrazení podobného ladícího panelu (reprezentován třídou

Nette\Diagnostics\Bar) a základní údaje, které poskytuje, se příliš neliší od jeho konkurenta

v podobě Zend. Z rozdílů lze jmenovat např. ten, že doba vykonání skriptu není rozdělena

dle jednotlivých událostí.

Page 90: Bachelor Thesis

4 Porovnání PHP frameworků 82

Ladící panel jako celek se skládá z dalších samostatných panelů, které lze volitelně registro-

vat pomocí metody Bar::addPanel(Nette\Diagnostics\IBarPanel $panel, $id = NULL). Pří-

kladem, takového panelu budiž Nette\Application\Diagnostics\RoutingPanel, který

zobrazuje tabulkový výpis pravidel routování.

Třída Nette\Diagnostics\Dumper slouží k získání strukturovaného výpisu obsahu dané pro-

měnné (metoda Dumper::toHtml($var, array $options = NULL)). Pokud však je požadováno

informaci o proměnné rovnou vypsat na výstup, je možné použít buď statickou metodu

Debugger::dump($var, $return = FALSE) nebo využít její předdefinované zkratky formou

globální funkce dump($var).

Nejjednodušší způsob logování nabízí statická metoda Debugger::log($message, $priority

= self::INFO). Metoda je v podstatě zkratkou60 pro použití třídy Nette\Diagnostics\Dumper,

která nerozlišuje různé datové zapisovače (tak jak tomu bylo u frameworku Zend), ale výstup

je vždy reprezentován fyzickými soubory. Platí, že určením priority dojde k zalogování hod-

noty do souboru, jehož název je stejný jako hodnota tohoto parametru. Přípona .log logova-

cího souboru je přidána automaticky (např. info.log).

4.13.3 Phalcon

Phalcon nativně žádné zpracování výjimek např. pomocí definice zvláštních řadičů pro zpra-

cování chyby nepodporuje. Framework proces nijak neřeší a je na vývojáři, jakou cestu zvolí

(problém se týká i zpracování chyb).

Výpis 44: Příklad obsloužení výjimek v prostředí Phalcon pomocí události třídy Dispatcher

(Zdroj: (Thomas, 2014))

use Phalcon\Mvc\Dispatcher; $di = new \Phalcon\DI\FactoryDefault(); $di->set('dispatcher', function() use ($di) { $eventsManager = $di->getShared('eventsManager'); $eventsManager->attach( 'dispatch:beforeException', function($event, $dispatcher, $exception) { switch ($exception->getCode()) { case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND: case Dispatcher::EXCEPTION_ACTION_NOT_FOUND: $dispatcher->forward(

60 Třídu by jinak bylo nutné při každém použití instanciovat (bez použití service locatoru/DI)

a nastavovat ji samostatně parametry. Takto je logger s globálními parametry nakonfi-

gurován s automaticky.

Page 91: Bachelor Thesis

4 Porovnání PHP frameworků 83

array( 'controller' => 'error', 'action' => 'notFound', ) ); return false; default: $dispatcher->forward( array( 'controller' => 'error', 'action' => 'uncaughtException', ) ); return false; } } ); ... return $dispatcher; });

Phalcon\Debug je pomocným nástrojem pro vizualizaci nezachycených výjimek. Jeho akti-

vaci lze provést metodou Debug::listen($exceptions = NULL, $lowSeverity = NULL). Na roz-

díl od vizualizačního nástroje Nette, není výsledek zobrazen ve „full-screen“ podobě. Názvy

tříd frameworku vygenerovaného stacktrace jsou definovány jako odkazy přímo do doku-

mentace Phalcon, což může usnadnit vyhledání chyby (jejich konkrétní metody však již

„klikatelné“ nejsou).

Logovací mechanismus je podobný tomu z frameworku Zend, protože dochází k abstrakci

od konkrétního typu zapisovače dat. Skládá se z následujících dvou součástí (Phalcon Team

and contributors, 2014):

Adaptéry – rozhraní Phalcon\Logger\AdapterInterface – reprezentují typ zapiso-

vače dat,

Formátovače – rozhraní Phalcon\Logger\FormatterInterface – jejich smyslem je

umožnit korekci výsledného formátu logované zprávy.

Page 92: Bachelor Thesis

4 Porovnání PHP frameworků 84

4.14 Rychlost

4.14.1 Celkové zpracování požadavku

Souhrnné výsledky rychlostního měření rozdělených do dvou fází představuje Tabulka 4,

Tabulka 5 a Tabulka 6. Jednotlivé údaje jsou rozděleny do dvou řádků, kde hodnoty

v řádku prvním vychází z nastavení PHP prostředí bez aktivovaného Zend OPcache (akce-

lerátor). V řádku druhém jsou naopak údaje, které byly zachyceny po aktivaci zmíněného

akcelerátoru. Kompletní zdrojová data jsou k nalezení v příloze.

Následuje stručná interpretace výsledků:

Výsledky potvrdili premisu, že Phalcon by měl být díky své architektuře rychlejší

než frameworky ostatní, a to dokonce několikanásobně při zachování celkově nej-

menší průměrné maximální paměťové náročnosti.

Phalcon rovněž dosahuje nejlepších výsledků v porovnání průměrného množství ma-

ximální alokované paměti, a to u obou fází napříč všemi třemi stránkami.

Nette dosahuje v důsledku inicializace cache v 1. fázi cca 1,2 – 1,5x horších výsledků

než Zend.

Markantního rozdílu bylo dosaženo v rámci měření 2. fáze rychlosti domovské

stránky Phalcon x Zend (Phalcon cca 50x rychlejší), resp. Phalcon x Nette (Phalcon

cca 25x rychlejší), viz Obrázek 2,

Měření navíc potvrdilo kladný účinek nasazení akcelerátoru, díky kterému došlo

u frameworků ke znatelnému navýšení rychlosti včetně snížení průměrné paměťové

náročnosti.

Page 93: Bachelor Thesis

4 Porovnání PHP frameworků 85

Obrázek 2:

Graf porovnání rychlosti frameworků – domovská stránka – 2. fáze (bez použití akcelerátoru)

(Zdroj: autor)

Tabulka 4: Výsledky rychlostního měření – domovská stránka (Zdroj: autor)

Údaj Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

Průměrný

čas (ms)

x 219,88592 283,90365 113,33969 12,45232 4,30794

x 90,74519 175,80032 35,69744 14,28862 5,48899

Medián (ms) x 212,8886 278,71251 111,87804 11,15143 3,96204

x 79,20659 170,36295 35,49695 12,82942 5,70107

Směrodatná

odchylka

(ms)

x 26,85273 12,41409 5,35318 4,86426 1,20702

x 36,73862 15,28356 4,40114 4,43499 0,98182

Průměrná

alokovaná

paměť (MB)

x 3,79124 4,60024 2,9734 0,33914 0,3242

x 1,46605 1,58213 0,94095 0,215 0,19688

Medián

(MB)

x 3,79124 4,58135 2,9734 0,33916 0,3242

x 1,46605 1,58211 0,94052 0,21609 0,19661

Směrodatná

odchylka

(MB)

x 0 0,03041 0 0,00007 0

x 0,0002 0,00006 0,00135 0,00348 0,00086

0

50

100

150

200

250

300

1 2 3 4 5 6 7 8 9 10

Mili

seku

nd

y

Porovnání rychlosti - domovská stránka - 2. fáze(bez akcelerátoru)

Zend Nette Phalcon

Page 94: Bachelor Thesis

4 Porovnání PHP frameworků 86

Tabulka 5: Výsledky rychlostního měření – seznam knih (Zdroj: autor)

Údaj Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

Průměrný

čas (ms)

x 211,23343 316,06431 118,22479 16,65163 9,38601

x 92,2147 206,88562 41,294 12,06989 12,25724

Medián (ms) x 206,25508 306,83649 118,88194 14,93192 9,07302

x 102,61011 200,80709 40,06934 11,68954 12,53903

Směrodatná

odchylka

(ms)

x 11,91252 42,6116 3,92038 4,41988 1,29622

x 19,73644 22,21896 6,26086 2,52908 1,05847

Průměrná

alokovaná

paměť (MB)

x 3,88046 4,66547 3,05564 0,38733 0,35126

x 1,49945 1,65449 1,00548 0,25081 0,21027

Medián

(MB)

x 3,88052 4,64574 3,05564 0,38735 0,35128

x 1,4995 1,64265 1,00536 0,25073 0,21002

Směrodatná

odchylka

(MB)

x 0,00019 0,03178 0,00001 0,00007 0,00007

x 0,00023 0,01906 0,00038 0,00025 0,00078

Tabulka 6: Výsledky rychlostního měření – detail knihy (Zdroj: autor)

Údaj Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

Průměrný

čas (ms)

x 213,0404 273,62309 118,22047 15,76769 8,62234

x 85,99448 336,04679 50,46511 18,20281 11,64963

Medián (ms) x 205,26004 273,68796 118,19494 15,93041 8,37886

x 86,94792 182,5316 48,28346 17,84301 11,307

Směrodatná

odchylka

(ms)

x 20,12999 5,41818 7,19631 2,96085 0,77037

x 16,99322 398,83537 9,48553 3,31359 1,62999

Průměrná

alokovaná

paměť (MB)

x 3,87743 4,60772 3,00503 0,37941 0,35125

x 1,49321 1,60245 0,95533 0,24096 0,20838

x 3,87752 4,60776 3,00503 0,37941 0,35127

Page 95: Bachelor Thesis

4 Porovnání PHP frameworků 87

Údaj Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

Medián

(MB)

x 1,49317 1,60247 0,95501 0,24083 0,20814

Směrodatná

odchylka

(MB)

x 0,00026 0,00012 0 0 0,00008

x 0,00022 0,00007 0,00101 0,0004 0,00078

4.14.2 Výkonnost databázové vrstvy

Výsledky měření výkonnosti databázových vrstev poukázali na skutečnost, že rozdíl v pou-

žití 1. způsobu se znatelněji projevuje pouze v porovnání Zend a ostatních dvou frameworků.

Phalcon i Nette totiž dosahují téměř shodných průměrných výsledků, jak znázorňuje Obrá-

zek 3.

Výsledky (uvedené v tabulkách níže) potvrzují i nevyřčený předpoklad, že mezi použitím

1. a 2. způsobu (v rámci jednoho frameworku) existuje znatelný a dokonce několikanásobný

rozdíl.

Tabulka 7: Výsledky výkonnostního srovnání databázových vrstev – získání seznamu všech

knih (Zdroj: autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

Průměrný

čas (ms)

3,19853 15,28952 0,47038 12,58233 0,51193 23,89722

2,18172 6,47812 0,5249 3,27494 0,46475 24,41533

Medián (ms) 3,04842 14,23597 0,48447 12,62581 0,45657 23,19491

1,99759 6,28543 0,46897 3,35896 0,45097 24,04845

Směrodatná

odchylka

(ms)

0,33308 3,47677 0,04761 0,65967 0,15851 3,08323

0,44669 1,37453 0,14624 0,7386 0,05581 2,08445

Průměrná

alokovaná

paměť (MB)

4,02845 4,37919 2,75611 3,03149 0,35807 0,39423

1,48848 1,58971 0,85832 0,89954 0,2173 0,2525

Medián

(MB)

4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,58959 0,85835 0,89935 0,21735 0,25217

Page 96: Bachelor Thesis

4 Porovnání PHP frameworků 88

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

Směrodatná

odchylka

(MB)

0,00033 0,00031 0,00014 0,00018 0,00009 0,00006

0,00029 0,00034 0,00016 0,00074 0,0001 0,00079

Tabulka 8: Výsledky výkonnostního srovnání databázových vrstev – získání jedné knihy (Zdroj:

autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

Průměrný

čas (ms)

3,2578 15,07232 0,58215 11,78305 0,47679 23,3047

1,9635 7,23839 0,49081 2,89552 0,52748 24,07799

Medián (ms) 3,23963 15,203 0,56005 11,54006 0,46647 23,73493

1,96397 7,05647 0,48351 2,94459 0,43941 24,36805

Směrodatná

odchylka

(ms)

0,22029 0,86419 0,12979 1,29797 0,04376 2,51639

0,12979 0,81238 0,06502 0,64249 0,16183 1,64055

Průměrná

alokovaná

paměť (MB)

4,02995 4,40865 2,7466 3,03223 0,35835 0,39839

1,48974 1,60344 0,84771 0,89668 0,21423 0,25535

Medián

(MB)

4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60329 0,8477 0,89672 0,21426 0,25537

Směrodatná

odchylka

(MB)

0,00025 0,00028 0,0001 0,00005 0,00007 0,00007

0,00026 0,00045 0,00008 0,00012 0,00007 0,00007

Page 97: Bachelor Thesis

4 Porovnání PHP frameworků 89

Obrázek 3:

Výsledky výkonnostního měření databázové vrstvy – získání seznamu všech knih 1. způsobem

(bez akcelerátoru) Zdroj: autor)

Obrázek 4:

Výsledky rychlostního měření databázové vrstvy – získání seznamu všech knih 2. způsobem

(bez akcelerátoru) (Zdroj: autor)

0

0.5

1

1.5

2

2.5

3

3.5

4

1 2 3 4 5 6 7 8 9 10

Mili

seku

nd

y

Získání seznamu všech knih 1. způsobem(bez akcelerátoru)

Zend Nette Phalcon

0

5

10

15

20

25

30

35

1 2 3 4 5 6 7 8 9 10

Mili

seku

nd

y

Získání seznamu všech knih 2. způsobem(bez akcelerátoru)

Zend Nette Phalcon

Page 98: Bachelor Thesis

4 Porovnání PHP frameworků 90

Obrázek 5:

Výsledky rychlostního měření databázové vrstvy – získání seznamu všech knih 2. způsobem

(se zapnutým akcelerátorem) (Zdroj: autor)

Na první pohled je zřejmé, že Phalcon je na tom z rychlostního pohledu (pravděpodobně

kvůli vlastnímu „vysoko-úrovňovému“ dotazovacímu jazyku, který je vnitřně komplikova-

nější a náročnější než ostatní) relativně nejhůře. Na druhou stranu, jeho průměrná maximální

paměťová náročnost zůstává opět nejnižší.

Mediánové i průměrné hodnoty zjištěné bez zapnutého akcelerátoru popisující 2. způsob

získání seznamu všech knih z databáze (dále se má na mysli srovnání Zend a Nette) jsou si

relativně blízké (viz Obrázek 4), což naznačuje, že mezi nimi není znatelného výkonnostního

(rychlostního) rozdílu. Naopak v případě aktivovaného akcelerátoru (Obrázek 5) se tyto hod-

noty již liší poměrně více (Nette cca 2x rychlejší než Zend), což nasvědčuje tomu, že efekt

optimalizace se u frameworků projevil různou měrou. Za předpokladu, že se oba soubory

hodnot řídí normálním rozdělením a rozptyly obou základních souborů nejsou známy, mů-

žeme tyto dvě hypotézy ověřit statistickým t-testem61:

1. Získání všech knih 2. způsobem bez akcelerátoru:

a. Nulová hypotéza H0: 𝜇1. 𝑧𝑝ů𝑠𝑜𝑏 = 𝜇2. 𝑧𝑝ů𝑠𝑜𝑏 … výkonnost 2. způsobu reali-

zovaného ve frameworcích Zend a Nette se neliší,

b. Alternativní hypotéza H1: 𝜇1. 𝑧𝑝ů𝑠𝑜𝑏 ≠ 𝜇2. 𝑧𝑝ů𝑠𝑜𝑏 … výkonnostně se imple-

mentace v obou frameworcích významně liší,

61 Postup vychází z (Hindls, 2007), resp. (Studentův t-test a F-test, 2010).

0

5

10

15

20

25

30

1 2 3 4 5 6 7 8 9 10

Mili

seku

nd

y

Získání seznamu všech knih 2. způsobem(se zapnutým akcelerátorem)

Zend Nette Phalcon

Page 99: Bachelor Thesis

4 Porovnání PHP frameworků 91

c. Testové kritérium: 𝑡 =𝑥1̅̅̅̅ −𝑥2̅̅̅̅

√𝑠1

2

𝑛1+

𝑠22

𝑛2

=15,28952−12,58233

√3,476772

10+

0,659672

10

≅ −2,419,

d. Kritický obor:

i. Rozdělení t s v stupni volnosti,

ii. Počet stupňů volnosti: 𝑣 =(

𝑠12

𝑛1+

𝑠22

𝑛2)

2

(𝑠1

2

𝑛1)

21

𝑛1+1+(

𝑠22

𝑛2)

21

𝑛2+1

− 2 =

(3,476772

10+

0,659672

10)

2

(3,476772

10)

21

10+1+(

0,659672

10)

21

10+1

− 2 ≅ 9,771 ≅ 10

iii. 𝑊 = {|𝑡| ≥ 𝑡1−𝛼2⁄ (10)}, hladina významnosti … α = 0,05 =>

𝑊 = {|𝑡| ≥ 2,228},

e. |−2,419| ≥ 2,228 => na zvolené 5% hladině významnosti zamítáme nulo-

vou hypotézu, u frameworků Zend a Nette byl prokázán statisticky významný

výkonnostní rozdíl v použití objektově orientovaného způsobu tvorby,

resp. položení databázového dotazu při vypnutém akcelerátoru.

2. Získání všech knih 2. způsobem se zapnutým akcelerátorem:

a. Nulová hypotéza H0: 𝜇1. 𝑧𝑝ů𝑠𝑜𝑏 = 𝜇2. 𝑧𝑝ů𝑠𝑜𝑏 … výkonnost 2. způsobu reali-

zovaného ve frameworcích Zend a Nette se zapnutým akcelerátorem se neliší,

b. Alternativní hypotéza H1: 𝜇1. 𝑧𝑝ů𝑠𝑜𝑏 ≠ 𝜇2. 𝑧𝑝ů𝑠𝑜𝑏 … výkonnostně se imple-

mentace v obou frameworcích při zapnutém akcelerátoru významně liší,

c. Testové kritérium: 𝑡 =𝑥1̅̅̅̅ −𝑥2̅̅̅̅

√𝑠1

2

𝑛1+

𝑠22

𝑛2

=6,47812−3,27494

√1,374532

10+

0,73862

10

≅ 7,168,

d. Kritický obor:

i. Rozdělení t s v stupni volnosti,

ii. Počet stupňů volnosti: 𝑣 =(

𝑠12

𝑛1+

𝑠22

𝑛2)

2

(𝑠1

2

𝑛1)

21

𝑛1+1+(

𝑠22

𝑛2)

21

𝑛2+1

− 2 =

(1,374532

10+

0,73862

10)

2

(1,374532

10)

21

10+1+(

0,73862

10)

21

10+1

− 2 ≅ 14,863 ≅ 15

iii. 𝑊 = {|𝑡| ≥ 𝑡1−𝛼2⁄ (15)}, hladina významnosti … α = 0,05 =>

𝑊 = {|𝑡| ≥ 2,131},

Page 100: Bachelor Thesis

4 Porovnání PHP frameworků 92

e. |7,168| ≥ 2,131 => na zvolené 5% hladině významnosti zamítáme nulovou

hypotézu, při zapnutém akcelerátoru byl u frameworků Zend a Nette proká-

zán statisticky významný výkonnostní rozdíl použití objektově orientova-

ného způsobu tvorby a položení databázového dotazu.

Na základě obou dvou statistických testů bylo s 5% mírou pravděpodobnosti chyby zjištěno,

že mezi použitím 2. způsobu ve frameworcích Zend a Nette je statisticky významný výkon-

ností rozdíl. Ukázalo se tak, že prvotní interpretace srovnání mediánových, resp. průměrných

hodnot (bez zapnutého akcelerátoru) byla mylná. Podobně by se dalo postupovat i ve srov-

nání ostatních údajů.

4.15 Ostatní

Následující část shrnuje další faktory související s potenciálním výběrem a použitím zvole-

ných frameworků.

4.15.1 Licenční omezení

Všechny frameworky jsou k dispozici pod tzv. New BSD License62. Software vydaný

pod touto licencí je při zachování určitých podmínek volně šiřitelný (The Open Source

Initiative, nedatováno):

1. Redistribuovaný zdrojový kód musí obsahovat znění licenčního omezení.

2. Redistribuce v binární podobě musí rovněž obsahovat znění licenčního omezení.

3. Jména vlastníků autorských práv (včetně ostatních přispěvatelů) nesmí být bez spe-

ciálního souhlasu použita za účelem reklamy produktu odvozeného z tohoto soft-

waru.

Jedinou výjimkou je Nette, které nabízí možnost zvolit si z dvou možností licencování.

Tabulka 9: Licenční omezení frameworků (Zdroj: (Zend Technologies Ltd., 2014), (Nette

Foundation, 2014), (Phalcon Framework Team, 2014))

Zend Nette Phalcon

Licence New BSD License New BSD License New BSD License

62 Šablona licenčního ujednání je k dispozici na http://opensource.org/licenses/BSD-3-

Clause.

Page 101: Bachelor Thesis

4 Porovnání PHP frameworků 93

GNU General Public

License (verze 2/3)

4.15.2 Dokumentace

Dokumentace všech tří frameworků je k dispozici online (v anglickém jazyce) na oficiálních

stránkách a obsahuje i část věnující se API. Součástí dokumentace je alespoň jedna ukázka

jednoduché aplikace. V případě Zend a Nette lze pak přímo na oficiálních stránkách nalézt

i tzv. video-tutoriály. Dokumentace Nette je jako jediná k dispozici i v češtině.

Každý framework nabízí možnost stažení oficiální API dokumentace pro tzv. offline63 pou-

žití. Při srovnání těchto verzí lze za relativně nejméně pohodlnou označit variantu Phalcon,

protože kompletní dokumentace není rozdělena na samostatné stránky, nýbrž vše je součástí

jediné a poměrně dlouhé HTML stránky, jejíž načtení určitou chvíli trvá. Podobně je na tom

i Zend, který však v základním přehledu neuvádí i jednotlivé metody rozhraní a tříd (tyto

údaje jsou zobrazovány až v detailu dané položky).

Existence knižních publikací věnujících se danému frameworku pravděpodobně nepatří

mezi ty nejdůležitější faktory. Dokumentace aktivně vyvíjeného frameworku má tendenci

rychle zastarávat, přesto existují příklady frameworků, o kterých byly vydány knižní publi-

kace. Jmenovitě se jedná o frameworky Zend a Phalcon64.

Tabulka 10: Porovnání dalších faktorů spojených s dokumentací frameworků (Zdroj: autor)

Zend Nette Phalcon

CZ dokumentace Ne Ano Ne

Offline API Ano Ano Ano

Knižní publikace Ano Ne Ano

4.15.3 Komunita spojená s frameworkem

Vyjdeme-li z veřejně dostupných dat znázorněných v tabulce níže, pak komunita spojená

s frameworkem Zend je v absolutním měřítku jednoznačně nejširší. Jako referenční komu-

nitní servery byly stanoveny:

63 Myšleno bez nutnosti internetového připojení – dokumentaci je možné používat z lokál-

ního disku.

64 V době psaní práce byl pravděpodobně jediným vydaným titulem Getting Started with

Phalcon (Stephan A. Miller, 2014).

Page 102: Bachelor Thesis

4 Porovnání PHP frameworků 94

1. GitHub (http://www.github.com),

2. StackOverflow (www.stackoverflow.com).

V případě GitHub byly agregované hodnoty pro snížení vlivu faktoru času upraveny dle

vzorce: 𝑢𝑝𝑟𝑎𝑣𝑒𝑛ý ú𝑑𝑎𝑗 =ℎ𝑜𝑑𝑛𝑜𝑡𝑎 𝑠𝑙𝑒𝑑𝑜𝑣𝑎𝑛éℎ𝑜 ú𝑑𝑎𝑗𝑒

𝑠𝑡áří 𝑟𝑒𝑝𝑜𝑠𝑖𝑡ář𝑒 𝑣𝑒 𝑑𝑛𝑒𝑐ℎ. V tabulce jsou upravené hodnoty uve-

dené v závorce za původním údajem. Intepretace těchto údajů má samozřejmě celou řadu

omezení, neboť není brána v potaz doba, po kterou byl framework k dispozici např. z jiného

zdroje.

Interpretovat upravené hodnoty můžeme např. takto:

Ačkoliv absolutní hodnoty Zend hovoří o jeho dominanci, z upravených hodnot tý-

kajících se počtu sledování změn repositáře dosahuje relativně horšího výsledku než

Phalcon.

Poměr tzv. pull repositářových požadavků frameworků Nette i Phalcon je přibližně

stejný i přesto, že repositář Phalcon je cca 3,5x mladší, což naznačuje relativně vyšší

zájem o tento framework.

Zájem o tvorbu vlastních repositářů založených na původních (angl. forks) je nej-

vyšší v případě Zend, nejnižší je naopak u Nette (cca 15x nižší v porovnání s Zend),

u Phalcon je pak přibližně 3x nižší a zároveň asi 6x vyšší než u Nette.

Tabulka 11: Absolutní srovnání v rámci komunitních serverů ke dni 28. 4. 2014 (Zdroj: autor)

Zend Nette Phalcon

GitHub – stáří repositáře (ve dnech) 1829 3019 842

GitHub Forks 2731 (1,49) 271 (0,09) 444 (0,53)

GitHub Pull Requests 78 (0,04) 55 (0,02) 13 (0,02)

GitHub Watches 557 (0,30) 118 (0,04) 391 (0,46)

StackOverflow – otagované otázky 35 638 / 713465 x66 358

StackOverflow – počet výsledků dle

vyhledávání

17 326 / 450367 161 834

65 Údaj před lomítkem udává počet výsledků na základě obecně zadaného tagu zend, údaj

za pak zend-framework-2.

66 Tag pro Nette neexistuje.

67 Údaj před lomítkem udává počet výsledků na základě obecně zadaného tagu zend, údaj

za pak zend 2.

Page 103: Bachelor Thesis

4 Porovnání PHP frameworků 95

4.15.4 Počet pracovních nabídek

Tabulka 12 ukazuje aktuální počet pracovních nabídek několika vybraných online pracov-

ních portálů z řad českých i zahraničních zástupců, vyhledaných na základě odpovídajícího

klíčového slova. Platí-li předpoklad, že lze z výsledků usuzovat na relativní známost frame-

worku, pak lze konstatovat, že Nette je v zahraničí prakticky neznámý. Nepatrně lépe je

na tom Phalcon, který ačkoliv je daleko mladší, na jednom z portálů bylo nalezeno několik

relevantních nabídek. V absolutním měřítku Zend zůstává jednoznačně na přední pozici jako

nejznámější framework vůbec.

Výsledky mohou podpořit názor, že velkou měrou se na míře jejich oblíbenosti podílí to, zda

se jedná o tuzemský nebo zahraniční framework, resp. pracovní portál.

Klíčová slova zastupující jednotlivé frameworky byly zvoleny následovně (u všech je abs-

trahováno od požadované verze):

Zend – zend,

Nette – nette,

Phalcon – phalcon.

Tabulka 12: Aktuální počet nabídek na pracovních portálech – stav ke dni 3. 5. 2014 (Zdroj:

autor)

Pracovní portál Zend Nette Phalcon

www.jobs.cz (CZ) 17 22 0

www.prace.cz (CZ) 11 10 0

www.monster.com (US) 11 0 0

www.indeed.com (US) 964 068 15

www.elance.com (US) 1342 8 14

4.15.5 Existující rozšíření

Kvalitu a oblíbenost frameworku ovlivňují i možnosti jeho rozšíření. Existence oficiální da-

tabáze uživatelsky definovaných rozšíření znázorňuje Tabulka 13. Jejich největší počet lze

nalézt pro framework Zend. Phalcon naopak žádnou oficiální databázi volně dostupných

68 Ve skutečnosti vyhledávač zobrazil výsledky 4, ale všechny byly očividně nerelevantní.

Page 104: Bachelor Thesis

4 Porovnání PHP frameworků 96

rozšíření nenabízí. Položka kategorizace znamená, zdali jsou rozšíření v rámci databáze roz-

dělena do kategorií (např. na vizuální/nevizuální komponenty apod.).

Tabulka 13: Dostupnost rozšíření (Zdroj: autor)

Zend Nette Phalcon

Databáze rozšíření Ano Ano Ne

Kategorizace Ne Ano x

Page 105: Bachelor Thesis

5 Závěr 97

5 Závěr Náplní této práce bylo porovnání tří vybraných PHP frameworků na základě předem stano-

vených kritérií. V první části byly nejprve vymezeny nejdůležitější obecné pojmy související

s vývojem webových aplikací za pomocí frameworků. Vzhledem k tomu, že se této proble-

matice věnovalo již několik autorů, další související termíny byly zmíněny až v průběhu

práce. Okrajově byly zmíněny způsoby hodnocení oblíbenosti jednotlivých frameworků

např. za pomocí statistik vyhledávanosti v různých komunitních serverech a internetových

vyhledávačích. Některých přístupů bylo pak posléze využito v druhé stěžejní části práce.

Jednotlivé problémové oblasti, které sloužily jako podklad pro porovnání frameworků byly

popsány v kapitole 3.3. Snahou bylo vyjmenovat jednotlivá kritéria tak, aby na sebe pokud

možno logicky navazovala. Ne vždy se podařilo tomuto ohledu dostát, protože problematika

je velmi komplexního charakteru. Pro porovnání v některých oblastech byly definovány vý-

zkumné otázky, na které bylo později v průběhu textu odpovězeno (ne nutně vždy expli-

citně).

V kapitole 4 byly frameworky již charakterizovány vždy v rámci jedné vybrané oblasti

a každý zvlášť v pořadí Zend, Nette, Phalcon. Výjimkou z tohoto pravidla byla zejména

podkapitola 4.14 věnující se rychlosti frameworků a podkapitola poslední (4.15) shrnující

některé ostatní faktory související s frameworkem, jako je jejich relativní popularita na zná-

mých komunitních serverech GitHub a StackOverflow a stejně tak i podmínky licencování

atd.

Teoreticko-praktická část byla koncipována tak, aby pokud možno vynikly zásadní rozdíly

v pojetí zmíněných problémových oblastí napříč všemi frameworky. Toho by mělo být do-

saženo tím, že kromě popisu API je text doprovázen i ukázkami kódu, z nichž část je čerpána

z oficiální dokumentace a část z vlastních příkladů autora. Samozřejmě, že nebylo vždy

možné v rámci výkladu postihnout všechny možné případy, filozofie frameworků, které jsou

v práci představeny, by ale měla být zřejmá (např. Zend razící pravidlo „obšírné“ konfigu-

race, Nette kladoucí důraz na jednoduchost a Phalcon, který díky své architektuře vyniká

svoji rychlostí).

Má-li být závěrem opětovně zmíněn cíl práce stanovený v úvodu práce – představení frame-

worků a popis jejich použitelnosti z pohledu vývojáře – pak se domnívám, že tohoto primár-

ního cíle bylo dosaženo a práce tak může čtenáři být onou počáteční motivací pro další

studium alespoň některého z nich (případně naopak).

Z návrhů na rozšíření prohlubující poznatky o frameworcích je možné uvést např. práce po-

pisující určitý nadstavbový framework, který vychází z některého z uvedených frameworků

s doprovodným popisem jeho nasazení v praxi. Jako hodnotné by se mohlo ukázat i hlubší

porovnání databázových vrstev s knihovnami 3. stran, které nejsou součástí žádného frame-

worku. V souvislosti s frameworkem Phalcon by pak mohlo být rovněž zajímavé jeho srov-

nání s jinými platformami (jmenovitě ASP. NET), zejména za účelem porovnání rychlosti.

Page 106: Bachelor Thesis

Terminologický slovník 98

Terminologický slovník Termín Zkratka Význam [zdroj]

Access Control List ACL Systém řízení přístupu na základě definovaných rolí a pra-

videl. (Zdroj: autor)

Aplikační rozhraní API Sada veřejné dostupných funkcí a tříd, resp. jejich metod.

(Zdroj: autor)

Autoloading x Mechanismus PHP umožňující dodatečné nahrávání zdro-

jových souborů obsahující deklarace požadovaných tříd

a rozhraní. (Zdroj: autor)

Cache x Speciální typ datového úložiště relativně krátkodobého

charakteru určený k ukládání relativně stálých neměnných

dat za účelem navýšení rychlosti aplikace. (Zdroj: autor)

Callback x Schéma používané v událostně-řízených programech, kde

program registruje určité procedury (obslužné funkce)

k obsloužení určité události. Program takovou funkci ne-

volá přímo, nýbrž je volána systémem za běhu a obvykle

jsou jí předány dodatečné argumenty popisující událost.

(Zdroj: (Howe, 2003))

Composer x Nástroj pro správu externích závislostí pro jazyk PHP.

(Zdroj: (Adermann & Boggiano, 2011))

Dependency Injection DI Paradigma OOP návrhu, jehož cílem je odstranění skry-

tých závislostí zavedením tzv. principu obráceného řízení.

(Zdroj: autor)

Dependency Injection

Container

DI

Container

Místo (objekt), který slouží k centralizované správě vytvá-

řených instancí. (Zdroj: autor)

Data Definition

Language

DDL Podmnožina jazyka SQL určená k definici/popisu struk-

tury dat. (Zdroj: autor)

Data Manipulation

Language

DML Podmnožina jazyka SQL určená k manipulaci s daty (vy-

tváření, úprava, mazání, výběr). (Zdroj: autor)

Extensible Markup

Language

XML Sémantický značkovací jazyk určený převážně k přenosu

dat v textové podobě. (Zdroj: (Refsnes Data, 2014))

Fasáda (angl. facade) x Druh „vysoko-úrovňového“ API mající za cíl zjednodušit

práci s několika dalšími podsystémy (zjednodušující

obálka nad relativně složitým API). (Zdroj:

(SourceMaking, nedatováno))

First In First Out FIFO Zpracování požadavků od nejstaršího po nejnovější.

(Zdroj: (Rouse, 2005))

Page 107: Bachelor Thesis

Terminologický slovník 99

Termín Zkratka Význam [zdroj]

GET x Typ HTTP požadavku, při kterém jsou odesílaná data pře-

nášena prostřednictvím URL. (Zdroj: (Refsnes Data,

2014))

Helper x Označení pro pomocnou funkci/třídu/metodu. (Zdroj: au-

tor)

Hešování x Technika konverze vstupního řetězce za pomocí speciál-

ního algoritmu do takové podoby, která je z bezpečnost-

ních důvodů vhodnější k zaznamenávání. (Zdroj: autor)

The Hypertext Transfer

Protocol

HTTP Bezestavový aplikační protokol umožňující komunikaci

mezi klientem a serverem. (Zdroj: (Refsnes Data, 2014))

HyperText Markup

Language

HTML Značkovací jazyk určený primárně pro popis (tvorbu) we-

bových stránek. (Zdroj: (Refsnes Data, 2014))

Kolace (angl. collation) x Způsob porovnávání textových řetězců v databází,

resp. tabulkových sloupcích, který ovlivňuje řazení hodnot

v nich obsažených. (Zdroj: autor)

Last In First Out LIFO Způsob zpracování požadavků, při kterém jsou zpracová-

vány zprvu požadavky nejaktuálnější (od posledně přida-

ného) až postupně po požadavek nejstarší (nejdříve

přidaný). (Zdroj: (Rouse, 2005))

Logování x Technika zaznamenávání určitých dat typicky za účelem

jejich pozdější analýzy nebo ladění. (Zdroj: autor)

Magic methods x Magické metody představují druh nativních třídních me-

tod se speciálním významem. (Zdroj: autor)

Model View Controller MVC Obecný architektonický návrhový vzor, ve kterém dochází

k rozdělení aplikace na tři relativně nezávislé části (pro-

blémové oblasti): model, pohled a řadič. (Zdroj: autor)

Návrhový vzor x Jistý druh „osvědčeného“ způsobu řešení určitého rela-

tivně často se opakujícího se problému. (Zdroj: autor)

PHP: Hypertext

Preprocessor

PHP Dynamický interpretovaný skriptovací jazyk, který je ur-

čen obzvláště k vývoji webových stránek a aplikací. (The

PHP Group, 2014)

POST x Typ HTTP požadavku, při kterém jsou odesílaná data sou-

částí jeho těla. (Zdroj: (Refsnes Data, 2014))

PSR-0 x Standard pro použití autoloadingu zahrnující pravidla

pro mapování tříd a rozhraní, resp. umístění souborů obsa-

hující jejich deklaraci v návaznosti na souborový systém.

(Zdroj: autor)

Page 108: Bachelor Thesis

Terminologický slovník 100

Termín Zkratka Význam [zdroj]

Service locator x Objekt, jenž má umožnit lokalizaci (získání) externích zá-

vislosti. (Zdroj: (Grudl, DI versus Service Locator, 2012))

Session hijacking x Bezpečnostní hrozba spočívající v odcizení uživatelské

session úspěšným získáním/vygenerováním existující ses-

sion ID. (Zdroj: (Imperva, 2014))

Structured Query

Language

SQL Strukturovaný dotazovací jazyk určený k dotazování se do

databází na něm postavených. (Zdroj: autor)

Type Hinting x Vlastnost přidaná v PHP 5, díky které argumenty funkce

musí být specifikovaných typů (instance třídy a instance

třídy implementující určité rozhraní, pole a od verze PHP

5.4 i tzv. callable typ (callback)). (Zdroj: (The PHP

Group, nedatováno))

Uniform Resource

Identifier

URI Řetězec znaků identifikující názvy a zdroje v prostředí In-

ternetu. (Zdroj: (Janalta Interactive Inc., 2014))

Page 109: Bachelor Thesis

Seznam literatury 101

Seznam literatury [1] Adermann, N., & Boggiano, J. (2011). Getting Started. Získáno 3. 5 2014, z

Composer: https://getcomposer.org/doc/00-intro.md

[2] Application Framework. (2014). Získáno 15. 3 2014, z Techopedia - Where IT and

Business Meet: http://www.techopedia.com/definition/6005/application-framework

[3] Bose, D. (nedatováno). COMPONENT BASED DEVELOPMENT. Získáno 16. 3 2014,

z APPLICATION IN SOFTWARE ENGINEERING:

http://arxiv.org/ftp/arxiv/papers/1011/1011.2163.pdf

[4] Design Patterns. (2014). Získáno 15. 3 2014, z MSDN – the Microsoft Developer

Network: http://msdn.microsoft.com/en-us/library/ff649977.aspx

[5] Dictionary.com. (nedatováno). database. Získáno 7. 5 2014, z Dictionary.com - Free

Online English Dictionary: http://dictionary.reference.com/browse/database

[6] Dispatching Controllers. (2014). Získáno 5. 4 2014, z Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/dispatching.html

[7] Eini, O. (11 2006). Inversion of Control and Dependency Injection: Working with

Windsor Container. Získáno 16. 3 2014, z MSDN – the Microsoft Developer

Network: http://msdn.microsoft.com/en-us/library/aa973811.aspx

[8] Fowler, M. (23. 1 2004). Inversion of Control Containers and the Dependency

Injection pattern. Získáno 16. 3 2014, z Martin Fowler:

http://martinfowler.com/articles/injection.html

[9] Fowler, M., Rice, D., Foemmel, M., Hieatt, E., Mee, R., & Staffort, R. (2002). Model

View Controller. V Patterns of Enterprise Application Architecture (str. 286).

Addison Wesley.

[10] framework - definition of framework by Macmillan Dictionary. (2014). Získáno 15. 3

2014, z Macmillan Dictionary and Thesaurus: Free English Dictionary Online:

http://www.macmillandictionary.com/dictionary/british/framework

[11] Frank, J. (2013). Porovnání frameworků Grails(Groovy) a Nette(PHP) pro rychlý

vývoj webových aplikaci.

[12] Freeman, E., Freeman, E., Sierra, K., & Bates, B. (2004). The power of Loose

Coupling. V Head First Design Patterns (str. 72). Sebastopol: O'Reilly Media, Inc.

[13] Grudl, D. (7. 5 2012). DI a předávání závislostí. Získáno 16. 3 2014, z phpFashion:

http://phpfashion.com/di-a-predavani-zavislosti#toc-konstruktor-hell

[14] Grudl, D. (14. 3 2012). DI versus Service Locator. Získáno 2. 5 2014, z phpFashion:

http://phpfashion.com/di-versus-service-locator

[15] Hindls, R. (2007). V R. Hindls, S. Hronová, J. Seger, & J. Fischer, Statistika pro

ekonomy (8. vydání. vyd., stránky 146-148). Praha: Professional Publishing. Získáno

10. 5 2014

[16] Howe, D. (13. 7 2003). callback. Získáno 3. 5 2014, z Dictionary.com:

http://dictionary.reference.com/browse/callback

Page 110: Bachelor Thesis

Seznam literatury 102

[17] IBM Corporation. (2010). Compiled versus interpreted languages. Získáno 9. 3 2014,

z IBM:

http://publib.boulder.ibm.com/infocenter/zos/basics/index.jsp?topic=/com.ibm.zos.zap

pldev/zappldev_85.htm

[18] Imperva. (2014). Session Hijacking. Získáno 2. 5 2014, z Imperva - Data Center

Security Solutions:

http://www.imperva.com/Resources/Glossary?term=session_hijacking

[19] Internet Engineering Task Force. (4 2011). HTTP State Management Mechanism.

Získáno 7. 5 2014, z IETF Tools: http://tools.ietf.org/html/rfc6265

[20] Introduction to the MVC Layer. (2014). Získáno 30. 3 2014, z Zend Framework 2

2.3.0 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.mvc.intro.html

[21] Janalta Interactive Inc. (2014). Uniform Resource Identifier (URI). Získáno 2. 5 2014,

z Techopedia - Where IT and Business Meet:

http://www.techopedia.com/definition/25550/uniform-resource-identifier-uri

[22] Korop, P. (20. 11 2013). TOP 6 most popular PHP frameworks of 2013. Získáno 15. 3

2014, z WebCoderPro - web-development, PHP, Wordpress:

http://webcoderpro.com/blog/top-6-most-popular-php-frameworks-of-2013/

[23] Koščo, J. (2013). Porovnanie PHP frameworkov Symfony 2 a Zend Framework 2.

[24] Kosek, J. (1999). Formuláře. V PHP Tvorba interaktivních internetových aplikací (str.

93). Grada Publishing, spol. s r.o.

[25] Křižan, O. (2010). Vybrané frameworky pro vývoj aplikací v PHP a jejich srovnání.

Načteno z ISIS:

https://isis.vse.cz/auth/zp/portal_zp.pl?prehled=vyhledavani;podrobnosti=78307;down

load_prace=1;lang=cz

[26] Kutišová, M. (2013). Zend Framework.

[27] Lecky-Thompson, E., Nowicki, S. D., & Myer, T. (2009). Logging and Debugging -

Creating a Logging Mechanism. V Professional PHP6 (str. 201). Indianapolis: Wiley

Publishing, Inc.

[28] Microsoft. (2014). Localization. Získáno 22. 3 2014, z MSDN Developer Network:

http://msdn.microsoft.com/en-us/library/5839we2z%28v=vs.110%29.aspx

[29] Nette Foundation. (2014). Auto-loading tříd. Získáno 29. 4 2014, z Nette Framework:

http://doc.nette.org/cs/2.1/auto-loading

[30] Nette Foundation. (2014). Cache. Získáno 25. 4 2014, z Nette Framework:

http://doc.nette.org/cs/2.1/caching

[31] Nette Foundation. (2014). Class CliRouter. Získáno 5. 4 2014, z Nette Framework

2.1.2 API: http://api.nette.org/2.1.2/Nette.Application.Routers.CliRouter.html

[32] Nette Foundation. (2014). File Application/UI/Presenter.php. Získáno 5. 4 2014, z

Nette Framework 2.1.2 API: http://api.nette.org/2.1.2/source-

Application.UI.Presenter.php.html

[33] Nette Foundation. (2014). Licenční politika. Získáno 6. 5 2014, z Nette Framework:

http://nette.org/cs/license

Page 111: Bachelor Thesis

Seznam literatury 103

[34] Nette Foundation. (2014). MVC aplikace & presentery. Získáno 18. 4 2014, z Nette

Framework: http://doc.nette.org/cs/2.1/presenters

[35] Nette Foundation. (2014). Píšeme komponenty. Získáno 18. 4 2014, z Nette

Framework: http://doc.nette.org/cs/2.1/components

[36] Nette Foundation. (2014). Požadavky Nette Framework. Získáno 29. 3 2014, z Nette

Framework: http://doc.nette.org/cs/2.1/requirements

[37] Nette Foundation. (2014). Routování URL. Získáno 5. 4 2014, z Rychlý a pohodlný

vývoj webových aplikací v PHP | Nette Framework: http://doc.nette.org/cs/2.1/routing

[38] Nette Foundation. (2014). Rozšíření jazyka PHP. Získáno 18. 4 2014, z Nette

Framework: http://doc.nette.org/cs/2.1/php-language-enhancements

[39] Nette Foundation. (2014). Slovníček pojmů. Získáno 5. 4 2014, z Nette Framework:

http://nette.org/cs/glossary#toc-presenter

[40] Phalcon Framework Team. (6. 1 2014). cphalcon/docs/LICENSE.md at master ·

phalcon/cphalcon. Získáno 6. 5 2014, z GitHub:

https://github.com/phalcon/cphalcon/blob/master/docs/LICENSE.md

[41] Phalcon Team and contributors. (3. 4 2014). Class Phalcon\Mvc\Application. Získáno

5. 4 2014, z Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_Application.html

[42] Phalcon Team and contributors. (2014). Cookies Management. Získáno 23. 4 2014, z

Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/cookies.html#encryption-decryption-

of-cookies

[43] Phalcon Team and contributors. (2014). Dependency Injection/Service Location.

Získáno 16. 4 2014, z Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/di.html#complex-registration

[44] Phalcon Team and contributors. (2014). Improving Performance with Cache. Získáno

25. 4 2014, z Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/cache.html

[45] Phalcon Team and contributors. (2014). Installation. Získáno 2. 5 2014, z Phalcon

1.3.0 documentation: http://docs.phalconphp.com/en/latest/reference/install.html

[46] Phalcon Team and contributors. (2014). Internationalization. Získáno 24. 4 2014, z

Phalcon 1.3.0 documentation: http://docs.phalconphp.com/en/latest/reference/intl.html

[47] Phalcon Team and contributors. (2014). Logging. Získáno 28. 4 2014, z Phalcon 1.3.0

documentation: http://docs.phalconphp.com/en/latest/reference/logging.html

[48] Phalcon Team and contributors. (2014). Phalcon Query Language (PHQL). Získáno

11. 5 2014, z Phalcon 1.3.0 documentation: http://phalcon-php-framework-

documentation.readthedocs.org/en/latest/reference/phql.html#creating-queries-using-

the-query-builder

[49] Phalcon Team and contributors. (2014). Routing. Získáno 5. 4 2014, z Phalcon 1.3.0

documentation: http://docs.phalconphp.com/en/latest/reference/routing.html#http-

method-restrictions

Page 112: Bachelor Thesis

Seznam literatury 104

[50] Phalcon Team and contributors. (2014). Universal Class Loader. Získáno 29. 4 2014,

z Phalcon 1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/loader.html

[51] Phalcon Team and contributors. (2014). Using Views. Získáno 20. 4 2014, z Phalcon

1.3.0 documentation:

http://docs.phalconphp.com/en/latest/reference/views.html#disabling-the-view

[52] Phalcon Team and contributors. (2014). User Components. Získáno 18. 4 2014, z

Phalcon 1.3.0 documentation: http://docs.phalconphp.com/en/latest/reference/tutorial-

invo.html#user-components

[53] PHP 5 Tutorial. (2014). Získáno 2014, z W3Schools Online Web Tutorials:

http://www.w3schools.com/php/default.asp

[54] PHP Framework Interoperability Group. (16. 10 2013). Autoloading Standard.

Získáno 29. 4 2014, z GitHub: https://github.com/php-fig/fig-

standards/blob/master/accepted/PSR-0.md

[55] PHP: Introduction - Manual. (2014). Získáno 15. 3 2014, z PHP:

http://www.php.net/manual/en/oop5.intro.php

[56] Q-Success. (7. 5 2014). Usage of server-side programming languages for websites.

Získáno 7. 5 2014, z W3Techs - extensive and reliable web technology surveys:

http://w3techs.com/technologies/overview/programming_language/all

[57] Refsnes Data. (2014). HTML Introduction. Získáno 2. 5 2014, z W3Schools Online

Web Tutorials: http://www.w3schools.com/html/html_intro.asp

[58] Refsnes Data. (2014). HTTP Methods: GET vs. POST. Získáno 8. 5 2014, z

W3Schools Online Web Tutorials:

http://www.w3schools.com/tags/ref_httpmethods.asp

[59] Refsnes Data. (2014). Introduction to XML. Získáno 2. 5 2014, z W3Schools Online

Web Tutorials: http://www.w3schools.com/xml/xml_whatis.asp

[60] Rouse, M. (4 2005). FIFO (first-in, first-out). Získáno 4. 5 2014, z The Tech

Dictionary and IT Encyclopedia: http://whatis.techtarget.com/definition/FIFO-first-in-

first-out

[61] Seemann, M. (2012). A Dependency Injection tasting menu. V Dependency Injection

in .NET (str. 4). Manning Publications Co.

[62] Seemann, M. (2012). DI patterns. V Dependency Injection in .NET (stránky 95-132).

Manning Publications Co.

[63] Seemann, M. (2012). Putting Dependency Injection on the map. V Dependency

Injection in .NET (str. 1). Manning Publications Co.

[64] Shafik, D., & Ramsey, B. (2007). Sessions. V Zend PHP 5 Certification Study Guide

2nd Edition (str. 109). Toronto: Marco Tabini & Associates, Inc.

[65] Skvorc, B. (28. 12 2013). Best PHP Frameworks for 2014. Získáno 15. 3 2014, z

SitePoint – Learn HTML, CSS, JavaScript, PHP, Ruby & Responsive Design:

http://www.sitepoint.com/best-php-frameworks-2014/

Page 113: Bachelor Thesis

Seznam literatury 105

[66] Sluiman, J. (12 2012). Using Zend Framework service managers in your application.

Získáno 16. 4 2014, z Jurian Sluiman: https://juriansluiman.nl/article/120/using-zend-

framework-service-managers-in-your-application

[67] SourceMaking. (nedatováno). Facade Design Pattern. Získáno 6. 5 2014, z

SourceMaking: http://sourcemaking.com/design_patterns/facade

[68] Studentův t-test a F-test. (21. 10 2010). Získáno 10. 5 2014, z sofe2 wiki:

http://sofe2.pepiino.cz/wiki/doku.php?id=studentuv_t-test_a_f-test

[69] The Open Source Initiative. (nedatováno). The BSD 3-Clause License. Získáno 28. 4

2014, z Open Source Initiative: http://opensource.org/licenses/BSD-3-Clause

[70] The PHP Group. (2014). PHP: General Information - Manual. Získáno 9. 3 2014, z

PHP: Hypertext Preprocessor: http://cz2.php.net/manual/en/faq.general.php

[71] The PHP Group. (2014). Runtime Configuration. Získáno 6. 5 2014, z PHP: Hypertext

Preprocessor:

http://www.php.net/manual/en/opcache.configuration.php#ini.opcache.enable

[72] The PHP Group. (2014). ZendOpcache. Získáno 6. 5 2014, z PECL:

http://pecl.php.net/package/ZendOpcache

[73] The PHP Group. (nedatováno). Passing the Session ID. Získáno 7. 5 2014, z PHP:

Hypertext Preprocessor: http://www.php.net/manual/en/session.idpassing.php

[74] The PHP Group. (nedatováno). Type Hinting. Získáno 4. 5 2014, z PHP: Hypertext

Preprocessor: http://www.php.net/manual/en/language.oop5.typehinting.php

[75] Thomas, R. (16. 2 2014). Handling 404 and 500 error pages in the Phalcon PHP

Framework. Získáno 28. 4 2014, z Roger E Thomas | Web Application Developer:

http://www.rogerethomas.com/blog/handling-404-and-500-error-pages-in-the-

phalcon-php-framework

[76] Tölg, J. (2012). Framework Nette.

[77] Vanguard Software Corporation. (2013). Compiled vs. Interpreted Languages.

Získáno 9. 3 2014, z Vanguard Software Corporation - Forecasting &amp; Planning:

http://www.vanguardsw.com/dphelp4/dph00296.htm

[78] Weier O'Phinney, M. (12. 3 2014). Zend Framework 2.3.0 Released! - Zend

Framework - Zend Framework. Získáno 29. 3 2014, z Zend Framework:

http://framework.zend.com/blog/zend-framework-2-3-0-released.html

[79] Zend Technologies Ltd. (2014). Advanced usage of helpers. Získáno 19. 4 2014, z

Zend Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.view.helpers.advanced-

usage.html

[80] Zend Technologies Ltd. (2014). Available Controllers. Získáno 30. 3 2014, z Zend

Framework 2 2.3.0 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.mvc.controllers.html

[81] Zend Technologies Ltd. (2014). Console routes and routing. Získáno 30. 3 2014, z

Zend Framework 2 2.3.0 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.console.routes.html#zend-

console-routes

Page 114: Bachelor Thesis

Seznam literatury 106

[82] Zend Technologies Ltd. (2014). Controller Plugins. Získáno 30. 3 2014, z Zend

Framework 2 2.3.0 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.mvc.plugins.html#zend-mvc-

controller-plugins-redirect

[83] Zend Technologies Ltd. (2014). Introduction to the MVC Layer. Získáno 18. 4 2014, z

Zend Framework 2 2.3.1 documentation:

http://framework.zend.com/manual/2.3/en/modules/zend.mvc.intro.html

[84] Zend Technologies Ltd. (2014). Learning Dependency Injection. Získáno 16. 4 2014, z

Zend Framework 2 2.3.1 documentation:

http://framework.zend.com/manual/2.3/en/tutorials/quickstart.di.html

[85] Zend Technologies Ltd. (2014). New BSD License. Získáno 6. 5 2014, z Zend

Framework: http://framework.zend.com/license

[86] Zend Technologies Ltd. (2014). Password. Získáno 23. 4 2014, z Zend Framework 2

2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.crypt.password.html

[87] Zend Technologies Ltd. (2014). Quick Start. Získáno 20. 4 2014, z Zend Framework 2

2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.form.quick-start.html

[88] Zend Technologies Ltd. (2014). Routing. Získáno 30. 3 2014, z Zend Framework 2

2.3.0 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.mvc.routing.html

[89] Zend Technologies Ltd. (2014). Session Container. Získáno 23. 4 2014, z Zend

Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.session.container.html

[90] Zend Technologies Ltd. (2014). Session Validators. Získáno 23. 4 2014, z Zend

Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.session.validator.html

[91] Zend Technologies Ltd. (2014). The ModuleAutoloader. Získáno 29. 4 2014, z Zend

Framework 2 2.3.1 documentation:

http://framework.zend.com/manual/2.3/en/modules/zend.loader.module-

autoloader.html

[92] Zend Technologies Ltd. (2014). Zend\Cache\Pattern. Získáno 25. 4 2014, z Zend

Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.cache.pattern.html

[93] Zend Technologies Ltd. (2014). Zend\Cache\Storage\Adapter. Získáno 25. 4 2014, z

Zend Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.cache.storage.adapter.html

[94] Zend Technologies Ltd. (2014). Zend\Cache\Storage\Plugin. Získáno 25. 4 2014, z

Zend Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.cache.storage.plugin.html

[95] Zend Technologies Ltd. (2014). Zend\Log. Získáno 26. 4 2014, z Zend Framework 2

2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.log.overview.html

Page 115: Bachelor Thesis

Seznam literatury 107

[96] Zend Technologies Ltd. (2014). Zend\Stdlib\Hydrator. Získáno 20. 4 2014, z Zend

Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.stdlib.hydrator.html#zend-

stdlib-hydrator

[97] Zend Technologies Ltd. (2014). Zend\View Quick Start. Získáno 19. 4 2014, z Zend

Framework 2 2.3.1 documentation - Zend Framework:

http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html

[98] Žižka, M. (28. 1 2008). Vícekriteriální rozhodování. Získáno 1. 5 2014, z MultiEdu:

http://multiedu.tul.cz/~miroslav.zizka/multiedu/Vicekriterialni_rozhodovani.pdf

Page 116: Bachelor Thesis

Seznam obrázků a tabulek 108

Seznam obrázků a tabulek

Základní text

Seznam obrázků Obrázek 1: ......................................................................................................................... 32 Obrázek 2: ......................................................................................................................... 85 Obrázek 3: ......................................................................................................................... 89 Obrázek 4: ......................................................................................................................... 89 Obrázek 5: ......................................................................................................................... 90

Seznam tabulek Tabulka 1: Běhové prostředí pro porovnání frameworků (Zdroj: autor) ............................. 20 Tabulka 2: Nastavení Zend OPcache rozšíření (Zdroj: autor) ........................................... 21 Tabulka 3: Výchozí předpoklady pro porovnání frameworků (Zdroj: autor) ....................... 23 Tabulka 4: Výsledky rychlostního měření – domovská stránka (Zdroj: autor) ................... 85 Tabulka 5: Výsledky rychlostního měření – seznam knih (Zdroj: autor) ............................ 86 Tabulka 6: Výsledky rychlostního měření – detail knihy (Zdroj: autor) .............................. 86 Tabulka 7: Výsledky výkonnostního srovnání databázových vrstev – získání seznamu všech knih (Zdroj: autor) .................................................................................................... 87 Tabulka 8: Výsledky výkonnostního srovnání databázových vrstev – získání jedné knihy (Zdroj: autor) ............................................................................................................ 88 Tabulka 9: Licenční omezení frameworků (Zdroj: (Zend Technologies Ltd., 2014), (Nette Foundation, 2014), (Phalcon Framework Team, 2014)) .......................................... 92 Tabulka 10: Porovnání dalších faktorů spojených s dokumentací frameworků (Zdroj: autor) ............................................................................................................ 93 Tabulka 11: Absolutní srovnání v rámci komunitních serverů ke dni 28. 4. 2014 (Zdroj: autor) ............................................................................................................ 94 Tabulka 12: Aktuální počet nabídek na pracovních portálech – stav ke dni 3. 5. 2014 (Zdroj: autor) ............................................................................................................ 95 Tabulka 13: Dostupnost rozšíření (Zdroj: autor) ................................................................ 96

Page 117: Bachelor Thesis

Seznam obrázků a tabulek 109

Přílohy

Seznam tabulek Tabulka 14: Identifikace typu stránky pro účely analýzy logu – 1. fáze (Zdroj: autor) ..... 110 Tabulka 15: Identifikace typu stránky pro účely analýzy logu – 2. fáze (Zdroj: autor) ..... 110 Tabulka 16: Výsledky rychlostního měření – domovská stránka (Zdroj: autor) ............... 111 Tabulka 17: Výsledky rychlostního měření – seznam knih (Zdroj: autor) ........................ 111 Tabulka 18: Výsledky rychlostního měření – detail knihy (Zdroj: autor) .......................... 112 Tabulka 19: Výsledky rychlostního měření se zapnutým akcelerátorem – domovská stránka (Zdroj: autor) ....................................................................................................... 113 Tabulka 20: Výsledky rychlostního měření se zapnutým akcelerátorem – seznam knih (Zdroj: autor) .......................................................................................................... 113 Tabulka 21: Výsledky rychlostního měření se zapnutým akcelerátorem – detail knihy (Zdroj: autor) .......................................................................................................... 114 Tabulka 22: Průměrná maximální paměťová náročnost – domovská stránka (Zdroj: autor) .......................................................................................................... 115 Tabulka 23: Průměrná maximální paměťová náročnost – seznam knih (Zdroj: autor) .... 115 Tabulka 24: Průměrná maximální paměťová náročnost – detail knihy (Zdroj: autor) ...... 116 Tabulka 25: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – domovská stránka (Zdroj: autor) ............................................................ 117 Tabulka 26: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – seznam knih (Zdroj: autor)..................................................................... 117 Tabulka 27: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – detail knihy (Zdroj: autor) ....................................................................... 118 Tabulka 28: Identifikace typu dotazu pro porovnání databázových vrstev frameworků pro účely analýzy logu – 1. způsob tvorby dotazu (Zdroj: autor) ...................................... 119 Tabulka 29: Identifikace typu dotazu pro porovnání databázových vrstev frameworků pro účely analýzy logu – 2. způsob tvorby dotazu (Zdroj: autor) ...................................... 119 Tabulka 30: Výsledky rychlostního měření databázových vrstev – získání seznamu všech knih, údaje jsou v milisekundách zaokrouhlených na 5 desetinných míst (Zdroj: autor) .. 119 Tabulka 31: Výsledky rychlostního měření databázových vrstev – získání jedné knihy, údaje jsou v milisekundách zaokrouhlených na 5 desetinných míst (Zdroj: autor) ........... 120 Tabulka 32: Průměrná maximální paměťová náročnost zjištěná při měření výkonnosti databázových vrstev – získání seznamu všech knih, údaje jsou v megabytech zaokrouhlených na 5 desetinných míst (Zdroj: autor) ...................................................... 122 Tabulka 33: Průměrná maximální paměťová náročnost zjištěná při měření výkonnosti databázových vrstev – získání jedné knihy, údaje jsou v megabytech zaokrouhlených na 5 desetinných míst (Zdroj: autor) ................................................................................ 123

Page 118: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 110

Příloha A: Výsledky rychlostního měření

A.1 Celkové zpracování požadavku

Zdrojové kódy aplikací, na kterých bylo prováděno měření, jsou součástí přiloženého ZIP

archivu. Hlavní rozcestník (soubor index.php) obsahuje odkazy do jednotlivých typů aplikací.

Pro účely jednoduché vizualizace naměřených hodnot tabulkovou formou byl vytvořen

skript results.php, který předně zobrazuje souhrnné výsledky měření včetně paměťové nároč-

nosti. Vstupní data jsou zobrazeny níže a je možné se na ně přesunout pomocí hypertexto-

vého odkazu ze souhrnné tabulky.

Jak již bylo zmíněno v kapitole 3.3.14, pro účely logování byla vytvořena pomocná třída

JR\FrameworkComparison\Utils\Logger, která rozlišuje jednotlivé typy stránek na základě de-

finovaných konstant, konkrétní hodnoty jsou uvedeny v tabulkách níže.

Tabulka 14: Identifikace typu stránky pro účely analýzy logu – 1. fáze (Zdroj: autor)

Typ stránky Zend Nette Phalcon

Domovská stránka x nette_homepage_caching phalcon_homepage_caching

Seznam knih x nette_books_caching phalcon_books_caching

Detail knihy x nette_book_caching phalcon_book_caching

Tabulka 15: Identifikace typu stránky pro účely analýzy logu – 2. fáze (Zdroj: autor)

Typ stránky Zend Nette Phalcon

Domovská stránka zend_homepage nette_homepage phalcon_homepage

Seznam knih zend_books nette_books phalcon_books

Detail knihy zend_book nette_book phalcon_book

V tabulce 16, 17 a 18 jsou zaznamenány výsledky měření v jednotlivých fázích bez aktivo-

vaného akcelerátoru rozdělených dle typu stránky. Zdrojem dat je soubor

JR\FrameworkComparison\_results\timelog.csv, který byl následně zpracován pomocí skriptu

results.php, který je rovněž součástí doprovodné aplikace. Tabulky 19, 20 a 21 zobrazují data

ze zdrojového souboru JR\FrameworkComparison\_results\opcache\timelog.csv, který obsahuje

hodnoty naměřené v prostředí se zapnutým akcelerátorem. Veškeré hodnoty jsou uvedeny

v milisekundách se zaokrouhlením na 5 desetinných míst. Průměrné hodnoty, hodnoty me-

diánu a velikost směrodatné odchylky (SO) jsou uvedeny vždy v posledních třech řádcích

tabulky.

Page 119: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 111

Tabulka 16: Výsledky rychlostního měření – domovská stránka (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 202,02518 306,41508 109,64394 26,01719 3,78513

2. x 210,00409 288,29789 106,72402 10,16903 3,76701

3. x 196,10596 298,33412 110,25906 11,45887 4,05312

4. x 217,93008 272,83311 113,49702 10,99896 4,13895

5. x 277,70591 278,11503 109,26604 9,70507 4,09293

6. x 258,111 274,03021 121,70696 10,67996 3,75605

7. x 217,91697 279,30999 122,10393 11,3039 3,77607

8. x 204,19097 295,50409 116,79983 12,55393 4,12607

9. x 199,09596 275,32887 113,95502 9,53913 7,71308

10. x 215,77311 270,86806 109,44104 12,09712 3,87096

Průměr x 219,88592 283,90365 113,33969 12,45232 4,30794

Medián x 212,8886 278,71251 111,87804 11,15143 3,96204

SO x 26,85273 12,41409 5,35318 4,86426 1,20702

Tabulka 17: Výsledky rychlostního měření – seznam knih (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 217,11302 323,11106 121,65713 27,25005 9,40299

2. x 198,98796 302,43707 121,21797 12,87317 8,78906

3. x 197,16311 308,599 119,08889 14,08219 12,98213

4. x 206,141 311,25593 118,26587 16,29996 9,14097

5. x 206,36916 387,97402 109,10606 15,42091 9,1958

6. x 206,05397 392,90309 116,14394 13,47899 9,30309

7. x 233,96015 280,02596 122,91718 20,64109 8,92401

8. x 203,78494 305,07398 115,80992 18,16988 8,52799

Page 120: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 112

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

9. x 225,87204 267,58099 119,36593 13,85713 9,00507

10. x 216,8889 281,68201 118,67499 14,44292 8,58903

Průměr x 211,23343 316,06431 118,22479 16,65163 9,38601

Medián x 206,25508 306,83649 118,88194 14,93192 9,07302

SO x 11,91252 42,6116 3,92038 4,41988 1,29622

Tabulka 18: Výsledky rychlostního měření – detail knihy (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 264,678 271,95692 127,71797 19,48094 10,02789

2. x 202,11101 281,72302 108,45089 12,36916 8,3518

3. x 213,99307 266,74986 108,52313 18,73684 8,19898

4. x 204,83994 275,06399 114,26282 19,21105 7,93195

5. x 220,98899 273,30494 129,01807 15,53988 8,40592

6. x 205,68013 272,73822 121,876 12,35008 7,84707

7. x 196,00987 264,2231 118,36791 11,43384 8,08287

8. x 201,653 274,07098 113,47699 17,0722 9,91607

9. x 221,17901 280,95388 118,02197 15,16199 8,74686

10. x 199,27096 275,44594 122,48898 16,32094 8,71396

Průměr x 213,0404 273,62309 118,22047 15,76769 8,62234

Medián x 205,26004 273,68796 118,19494 15,93041 8,37886

SO x 20,12999 5,41818 7,19631 2,96085 0,77037

Page 121: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 113

Tabulka 19: Výsledky rychlostního měření se zapnutým akcelerátorem – domovská stránka

(Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 113,2741 169,22998 46,14115 23,53406 5,79619

2. x 65,9678 173,90394 31,64196 20,28179 5,60594

3. x 181,02479 169,56592 36,49402 14,12082 6,3858

4. x 68,17913 204,4692 33,83303 15,72108 5,98407

5. x 90,70897 171,15998 30,21598 12,47001 4,02308

6. x 65,58108 161,5572 36,95011 10,52284 4,91381

7. x 105,84593 198,97699 36,9401 11,56402 4,1039

8. x 63,76696 183,90894 34,49988 9,67884 7,08508

9. x 90,23404 165,75909 37,30416 13,18884 6,03104

10. x 62,86907 159,47199 32,95398 11,80387 4,96101

Průměr x 90,74519 175,80032 35,69744 14,28862 5,48899

Medián x 79,20659 170,36295 35,49695 12,82942 5,70107

SO x 36,73862 15,28356 4,40114 4,43499 0,98182

Tabulka 20: Výsledky rychlostního měření se zapnutým akcelerátorem – seznam knih (Zdroj:

autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 120,11909 236,56392 46,15498 16,28613 12,95519

2. x 103,92308 243,56985 41,65483 11,33704 12,63714

3. x 68,08591 229,31004 34,04403 9,12595 12,743

4. x 104,05302 200,35505 47,67799 12,04205 11,19995

5. x 68,69888 191,57314 38,48386 10,41293 10,40983

6. x 107,54704 180,06086 36,17311 12,64095 12,44092

7. x 70,41478 206,79808 44,30604 12,29191 13,28111

Page 122: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 114

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

8. x 101,29714 196,522 34,68513 9,11093 12,28118

9. x 73,17305 201,25914 37,03403 11,15394 10,97107

10. x 104,83503 182,84416 52,72603 16,2971 13,65304

Průměr x 92,2147 206,88562 41,294 12,06989 12,25724

Medián x 102,61011 200,80709 40,06934 11,68954 12,53903

SO x 19,73644 22,21896 6,26086 2,52908 1,05847

Tabulka 21: Výsledky rychlostního měření se zapnutým akcelerátorem – detail knihy (Zdroj: au-

tor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 104,35605 174,88289 59,71098 24,67203 11,78122

2. x 67,83199 182,3051 42,61518 18,45813 11,19995

3. x 99,06101 238,95502 41,95714 15,06805 11,41405

4. x 66,63609 405,60412 55,54509 17,94195 11,10005

5. x 104,24304 182,75809 46,88597 17,53688 14,22596

6. x 74,83482 178,68495 41,29601 18,677 9,76396

7. x 100,92402 180,63188 60,33683 15,589 11,76

8. x 72,67594 198,07887 40,01999 17,74406 10,22506

9. x 100,89588 1452,86584 49,68095 22,60303 10,32114

10. x 68,48598 165,70115 66,60295 13,73792 14,70494

Průměr x 85,99448 336,04679 50,46511 18,20281 11,64963

Medián x 86,94792 182,5316 48,28346 17,84301 11,307

SO x 16,99322 398,83537 9,48553 3,31359 1,62999

Tabulky níže shrnují výsledky porovnání průměrné maximální paměťové náročnosti. Rozli-

šena jsou měření s vypnutým a povoleným akcelerátorem. Hodnoty jsou uvedeny v mega-

bytech a jsou zaokrouhlené na 5 desetinných míst.

Page 123: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 115

Tabulka 22: Průměrná maximální paměťová náročnost – domovská stránka (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 3,79124 4,64431 2,9734 0,33894 0,3242

2. x 3,79124 4,64431 2,9734 0,33916 0,3242

3. x 3,79124 4,64431 2,9734 0,33916 0,3242

4. x 3,79124 4,58135 2,9734 0,33916 0,3242

5. x 3,79124 4,58135 2,9734 0,33916 0,3242

6. x 3,79124 4,58135 2,9734 0,33916 0,3242

7. x 3,79124 4,58135 2,9734 0,33916 0,3242

8. x 3,79124 4,58135 2,9734 0,33916 0,3242

9. x 3,79124 4,58135 2,9734 0,33916 0,3242

10. x 3,79124 4,58135 2,9734 0,33916 0,3242

Průměr x 3,79124 4,60024 2,9734 0,33914 0,3242

Medián x 3,79124 4,58135 2,9734 0,33916 0,3242

SO x 0 0,03041 0 0,00007 0

Jelikož během měření bylo sledováno i množství maximální alokované paměti, jsou tyto

údaje zaznamenány v tabulkách uvedených níže. Veškeré hodnoty jsou uváděny v megaby-

tech se zaokrouhlením na 5 desetinných míst.

Tabulka 23: Průměrná maximální paměťová náročnost – seznam knih (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 3,87991 4,71152 3,05567 0,38714 0,35107

2. x 3,88052 4,71152 3,05564 0,38735 0,35128

3. x 3,88052 4,71152 3,05564 0,38735 0,35128

4. x 3,88052 4,64574 3,05564 0,38735 0,35128

5. x 3,88052 4,64574 3,05564 0,38735 0,35128

6. x 3,88052 4,64574 3,05564 0,38735 0,35128

Page 124: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 116

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

7. x 3,88052 4,64574 3,05564 0,38735 0,35128

8. x 3,88052 4,64574 3,05564 0,38735 0,35128

9. x 3,88052 4,64574 3,05564 0,38735 0,35128

10. x 3,88052 4,64574 3,05564 0,38735 0,35128

Průměr x 3,88046 4,66547 3,05564 0,38733 0,35126

Medián x 3,88052 4,64574 3,05564 0,38735 0,35128

SO x 0,00019 0,03178 0,00001 0,00007 0,00007

Tabulka 24: Průměrná maximální paměťová náročnost – detail knihy (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 3,87669 4,60738 3,00503 0,37941 0,35103

2. x 3,87752 4,60776 3,00503 0,37941 0,35127

3. x 3,87752 4,60776 3,00503 0,37941 0,35127

4. x 3,87752 4,60776 3,00503 0,37941 0,35127

5. x 3,87752 4,60776 3,00503 0,37941 0,35127

6. x 3,87752 4,60776 3,00503 0,37941 0,35127

7. x 3,87752 4,60776 3,00503 0,37941 0,35127

8. x 3,87752 4,60776 3,00503 0,37941 0,35127

9. x 3,87752 4,60776 3,00503 0,37941 0,35127

10. x 3,87752 4,60776 3,00503 0,37941 0,35127

Průměr x 3,87743 4,60772 3,00503 0,37941 0,35125

Medián x 3,87752 4,60776 3,00503 0,37941 0,35127

SO x 0,00026 0,00012 0 0 0,00008

Page 125: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 117

Tabulka 25: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – domovská

stránka (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 1,46624 1,58229 0,94479 0,2051 0,19934

2. x 1,46587 1,58211 0,94052 0,21609 0,19661

3. x 1,46624 1,58211 0,94052 0,21609 0,19661

4. x 1,46587 1,58211 0,94052 0,21609 0,19661

5. x 1,46624 1,58211 0,94052 0,21609 0,19661

6. x 1,46587 1,58211 0,94052 0,21609 0,19661

7. x 1,46624 1,58211 0,94052 0,21609 0,19661

8. x 1,46587 1,58211 0,94052 0,21609 0,19661

9. x 1,46624 1,58211 0,94052 0,21609 0,19661

10. x 1,46587 1,58211 0,94052 0,21609 0,19661

Průměr x 1,46605 1,58213 0,94095 0,215 0,19688

Medián x 1,46605 1,58211 0,94052 0,21609 0,19661

SO x 0,0002 0,00006 0,00135 0,00348 0,00086

Tabulka 26: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – seznam

knih (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 1,49998 1,68223 1,00656 0,25151 0,21249

2. x 1,4995 1,68205 1,00536 0,25073 0,21002

3. x 1,49924 1,68205 1,00536 0,25073 0,21002

4. x 1,4995 1,64265 1,00536 0,25073 0,21002

5. x 1,49924 1,64265 1,00536 0,25073 0,21002

6. x 1,4995 1,64265 1,00536 0,25073 0,21002

7. x 1,49924 1,64265 1,00536 0,25073 0,21002

Page 126: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 118

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

8. x 1,4995 1,64265 1,00536 0,25073 0,21002

9. x 1,49924 1,64265 1,00536 0,25073 0,21002

10. x 1,4995 1,64265 1,00536 0,25073 0,21002

Průměr x 1,49945 1,65449 1,00548 0,25081 0,21027

Medián x 1,4995 1,64265 1,00536 0,25073 0,21002

SO x 0,00023 0,01906 0,00038 0,00025 0,00078

Tabulka 27: Průměrná maximální paměťová náročnost se zapnutým akcelerátorem – detail

knihy (Zdroj: autor)

Měření Zend Nette Phalcon

1. fáze 2. fáze 1. fáze 2. fáze 1. fáze 2. fáze

1. x 1,49373 1,60226 0,9582 0,2421 0,2106

2. x 1,49305 1,60247 0,95501 0,24083 0,20814

3. x 1,49329 1,60247 0,95501 0,24083 0,20814

4. x 1,49305 1,60247 0,95501 0,24083 0,20814

5. x 1,49329 1,60247 0,95501 0,24083 0,20814

6. x 1,49305 1,60247 0,95501 0,24083 0,20814

7. x 1,49329 1,60247 0,95501 0,24083 0,20814

8. x 1,49305 1,60247 0,95501 0,24083 0,20814

9. x 1,49329 1,60247 0,95501 0,24083 0,20814

10. x 1,49305 1,60247 0,95501 0,24083 0,20814

Průměr x 1,49321 1,60245 0,95533 0,24096 0,20838

Medián x 1,49317 1,60247 0,95501 0,24083 0,20814

SO x 0,00022 0,00007 0,00101 0,0004 0,00078

Page 127: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 119

A.2 Výkonnost databázové vrstvy

Princip logování je stejný jako u měření celkové rychlosti zpracování požadavku, liší se

pouze identifikátory daných typů. Rozlišeny jsou oba dva způsoby konstrukce dotazů.

Pro každé měření (označeného číselným pořadím) jsou uvedeny hodnoty ve dvou řádcích.

V prvním z nich leží hodnoty naměřené bez aktivovaného akcelerátoru, v druhém jsou nao-

pak hodnoty naměřené se zapnutým akcelerátorem.

Tabulka 28: Identifikace typu dotazu pro porovnání databázových vrstev frameworků pro účely

analýzy logu – 1. způsob tvorby dotazu (Zdroj: autor)

Zend Nette Phalcon

Získání seznamu

všech knih

zend_db_books nette_db_books phalcon_db_books

Získání jedné knihy zend_db_book nette_db_book phalcon_db_book

Tabulka 29: Identifikace typu dotazu pro porovnání databázových vrstev frameworků pro účely

analýzy logu – 2. způsob tvorby dotazu (Zdroj: autor)

Zend Nette Phalcon

Získání seznamu

všech knih

zend_db_oop_books nette_db_oop_books x

Získání jedné knihy zend_db_oop_book nette_db_oop_book x

Následující sada tabulek shrnuje všechny naměřené hodnoty.

Tabulka 30: Výsledky rychlostního měření databázových vrstev – získání seznamu všech knih,

údaje jsou v milisekundách zaokrouhlených na 5 desetinných míst (Zdroj: autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1. 3,59201 24,30606 0,53716 12,85505 0,40603 29,76203

3,25394 7,27081 0,45109 3,92389 0,48614 28,09715

2. 3,721 12,86197 0,53883 12,41493 0,57507 26,016

2,01511 8,45098 0,86498 4,33803 0,42582 23,43392

3. 2,98381 14,87494 0,4859 11,338 0,45395 25,39611

1,86801 5,58686 0,494 2,69294 0,40603 23,51403

4. 2,94781 13,05914 0,48494 12,66479 0,916 18,21303

Page 128: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 120

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1,92499 7,31492 0,40197 3,33095 0,48089 20,83015

5. 3,03292 14,72116 0,44394 12,90798 0,45419 22,93897

1,98007 5,20992 0,60892 2,75493 0,59199 24,98698

6. 2,94089 14,3981 0,48399 12,19082 0,38218 22,4402

1,87802 5,07689 0,65899 3,98684 0,453 27,38714

7. 2,882 13,07511 0,4189 13,00812 0,46301 22,52293

2,65098 6,984 0,46301 2,11501 0,44894 23,84281

8. 3,6931 14,07385 0,48614 12,0399 0,45896 22,25995

2,07305 5,18489 0,47493 3,38697 0,44203 24,56808

9. 3,06392 13,70001 0,40197 12,58683 0,60201 23,45085

1,89805 5,23686 0,41914 2,46692 0,40579 23,2389

10. 3,12781 17,82489 0,422 13,81683 0,40793 25,97213

2,27499 8,46505 0,41199 3,75295 0,50688 24,25408

Průměr 3,19853 15,28952 0,47038 12,58233 0,51193 23,89722

2,18172 6,47812 0,5249 3,27494 0,46475 24,41533

Medián 3,04842 14,23597 0,48447 12,62581 0,45657 23,19491

1,99759 6,28543 0,46897 3,35896 0,45097 24,04845

SO 0,33308 3,47677 0,04761 0,65967 0,15851 3,08323

0,44669 1,37453 0,14624 0,7386 0,05581 2,08445

Tabulka 31: Výsledky rychlostního měření databázových vrstev – získání jedné knihy, údaje jsou

v milisekundách zaokrouhlených na 5 desetinných míst (Zdroj: autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1. 3,443 16,44707 0,458 10,16903 0,44298 28,04804

2,11692 6,75392 0,50402 2,91705 0,47398 24,32704

Page 129: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 121

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

2. 3,49998 15,31911 0,52619 11,3771 0,54193 22,81499

1,88112 7,72595 0,44799 2,21491 0,422 25,6269

3. 3,17907 14,75406 0,63896 14,21809 0,52118 25,04611

2,06494 6,85 0,56791 2,46096 0,40483 22,54081

4. 2,97499 13,7589 0,48518 11,05499 0,46802 24,38617

1,76311 6,12497 0,61607 3,53312 0,41103 23,97895

5. 3,03698 15,53011 0,48399 12,17508 0,48304 19,81187

1,81508 7,52902 0,41199 2,97213 0,79703 24,88589

6. 3,30019 16,02602 0,5939 12,42709 0,46492 23,99898

2,02394 6,43206 0,44394 2,02298 0,44489 26,20912

7. 3,11995 14,32109 0,71001 10,39219 0,43797 22,10903

1,90401 8,89993 0,47708 3,03006 0,41699 20,49804

8. 3,31402 15,46097 0,458 10,90312 0,42892 19,36197

1,88088 7,02882 0,48995 3,65019 0,79203 23,35906

9. 3,64304 14,01901 0,86212 13,41081 0,54193 23,83995

2,06494 7,08413 0,42319 3,86286 0,67806 24,40906

10. 3,06678 15,08689 0,60511 11,70301 0,43702 23,6299

2,12002 7,95507 0,52595 2,29096 0,43392 24,94502

Průměr 3,2578 15,07232 0,58215 11,78305 0,47679 23,3047

1,9635 7,23839 0,49081 2,89552 0,52748 24,07799

Medián 3,23963 15,203 0,56005 11,54006 0,46647 23,73493

1,96397 7,05647 0,48351 2,94459 0,43941 24,36805

SO 0,22029 0,86419 0,12979 1,29797 0,04376 2,51639

0,12979 0,81238 0,06502 0,64249 0,16183 1,64055

Page 130: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 122

Tabulka 32: Průměrná maximální paměťová náročnost zjištěná při měření výkonnosti

databázových vrstev – získání seznamu všech knih, údaje jsou v megabytech zao-

krouhlených na 5 desetinných míst (Zdroj: autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1. 4,02785 4,37864 2,75584 3,03114 0.39423 0,39423

1,48797 1,58929 0,85804 0,90162 0,2171 0,25397

2. 4,02779 4,37856 2,75584 3,03117 0,35792 0,39405

1,48799 1,58932 0,858 0,89898 0,21712 0,25185

3. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,58959 0,85844 0,89936 0,21735 0,25217

4. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,59016 0,85835 0,89935 0,21735 0,25217

5. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48883 1,58959 0,85835 0,89936 0,21735 0,25217

6. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,58959 0,85844 0,89935 0,21735 0,25217

7. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,59016 0,85835 0,89935 0,21735 0,25217

8. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,58959 0,85835 0,89936 0,21735 0,25217

9. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48883 1,58959 0,85844 0,89935 0,21735 0,25217

10. 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

1,48853 1,59016 0,85844 0,89936 0,21735 0,25398

Průměr 4,02845 4,37919 2,75611 3,03149 0,35807 0,39423

1,48848 1,58971 0,85832 0,89954 0,2173 0,2525

Medián 4,02861 4,37934 2,75617 3,03157 0,35811 0,39425

Page 131: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 123

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1,48853 1,58959 0,85835 0,89935 0,21735 0,25217

SO 0,00033 0,00031 0,00014 0,00018 0,00009 0,00006

0,00029 0,00034 0,00016 0,00074 0,0001 0,00079

Tabulka 33: Průměrná maximální paměťová náročnost zjištěná při měření výkonnosti

databázových vrstev – získání jedné knihy, údaje jsou v megabytech zaokrouhle-

ných na 5 desetinných míst (Zdroj: autor)

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

1. 4,02923 4,40786 2,74632 3,03209 0,35815 0,3982

1,48914 1,60245 0,84751 0,89633 0,21403 0,25514

2. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60387 0,8477 0,89672 0,21426 0,25537

3. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48997 1,60329 0,84779 0,89672 0,21426 0,25537

4. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60329 0,8477 0,89672 0,21426 0,25537

5. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60387 0,8477 0,89672 0,21426 0,25537

6. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48997 1,60329 0,84779 0,89672 0,21426 0,25537

7. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60387 0,8477 0,89672 0,21426 0,25537

8. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60329 0,8477 0,89672 0,21426 0,25537

9. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48997 1,60387 0,84779 0,89672 0,21426 0,25537

Page 132: Bachelor Thesis

Příloha A: Výsledky rychlostního měření 124

Měření Zend Nette Phalcon

1. způsob 2. způsob 1. způsob 2. způsob 1. způsob 2. způsob

10. 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48997 1,60329 0,8477 0,89672 0,21426 0,25537

Průměr 4,02995 4,40865 2,7466 3,03223 0,35835 0,39839

1,48974 1,60344 0,84771 0,89668 0,21423 0,25535

Medián 4,03003 4,40874 2,74663 3,03224 0,35837 0,39841

1,48968 1,60329 0,8477 0,89672 0,21426 0,25537

SO 0,00025 0,00028 0,0001 0,00005 0,00007 0,00007

0,00026 0,00045 0,00008 0,00012 0,00007 0,00007