Symfony - vytvorenie a testovanie jendoduchej aplikácie
Framework Symfony je agilný, rýchly a predovšetkým stabilný PHP framework, ktorý sa vyvíja vo Francúzsku. Svoje uplatnenie nájde hlavne pri väčších projektoch, webových portáloch a aplikáciách. Ako väčšina frameworkov vznikol aj Symfony za účelom skrátenia času potrebného na vytvorenie webových stránok a zníženia náročnosti na údržbu.
Symfony je charakteristické mnohými vlastnosťami ako :
-
-
Cache Management na skrátenie doby ukladania údajov, zníženie spotreby prostriedkov
-
Smart URLs optimalizované linky na jednotlivé časti stránky pre internetové vyhľadávače
-
Scaffolding automatické vygenerovanie základnej administrácie podľa modelu databázy
-
Symfony je zriadený multijazyčne a preto je ho možné ľubovolne rozšíriť o ďalší jazyk
-
Ajax support zabezpečuje bezproblémovú integráciu Web 2.0 prvkov
-
Automatizovaný Unit Testing pomáha pri udržaní stability aplikácie tým, že redukuje tvorbu chýb už počas vývoja a programátorovi uľahčuje hľadanie chýb
-
Na vytvorenie testovacej aplikácie vo frameworku Symfony som využil balíček Sandbox, ktorý obsahuj prázdnu aplikáciu a nakonfigurovanú databázu SQLite. Adresárovú štruktúru je ľahké pochopiť:
sf_sandbox
/apps – súbory aplikácie
/batch – dávkové procesné skritpy
/cache – cache súbory
/config – konfiguračné súbory
/data – datové súbory a skripty
/doc – dokumentačné súbory
/lib – knižnice a všeobecne použiteľné skripty
/log – log súbory
/plugins – pluginy
/test – unit a integračné testy
/web – verejný web adresár
Ako prvé je potrebné vytvoriť súbor formátu YAML, ktorý popisuje stĺpce a cudzie kľúče tabuliek v pripravenej databáze. Tento súbor je podobný XML a slúži ako predloha z ktorej budú vygenerované ďalšie časti aplikácie. V tabuľke je vidieť súbor schema.yml s opisom relačnej schémy databázy, pripravený na generovanie základu aplikácie pomocou objektovo-relačného mapovania.
propel:members:
id: ~
name: varchar(255)
treet_number:varchar(255)
street: varchar(255)
town: varchar(255)
ZIP_code: varchar(255)
type: varchar(255)
login: varchar(255)
password: varchar(255)
users:
id: ~
member_id: varchar(255)
name: varchar(255)
surname: varchar(255)
phone: varchar(255)
email: varchar(255)
Pre používanie MySQL DB je potrebné upraviť nadstavenia pripojenia na databázu v súbore databases.yml.
prod:
all:
propel:
class: sfPropelDatabase
param:
dsn: mysql://getfh_5220031:tombo7@sql200.byetcluster.com/getfh_5220031_db
Na vygenerovanie základných tried a súborov potrebných na obsluhu už vytvorenej databázy, použijem príkaz propel-build-all, ktorý spustím v hlavnom adresári aplikácie.
$ php symfony propel-build-all
Po takomto vytvorení tried a ďalších súborov je potrebné spustiť ešte jeden skript, ktorý vyčistí cache pamäť.
$ php symfony clear-cache
Aby sa dalo s uloženými informáciami aj pracovať je ďalším krokom vytvorenie tzv. administratívneho panelu, ktorý na základe relačnej schémy vytvorí rozhrania pre prácu s dátami. Na jeho vytvorenie sa opäť použije skript, ktorý vytvorí správu webu, v aplikácii frontend a module Member.
$ php symfony propel-init-admin frontend members Members
$ php symfony propel-init-admin frontend users Users
Po vygenerovaní potrebných súborov sa nám na stránke objaví zoznam položiek zo zvolenej tabuľky v databáze. Záznamy je možné upravovať ako je nižšie na obrázku ukázané. Taktiež je možné záznamy aj pridávať a zmazať. Všetko pekne v jednoduchom a prehľadnom dizajne. Podobné techniky generovania majú aj iné frameworky, ale nikde to nefunguje tak jednoducho, ako práve v Symfony. Po pár riadkoch kódu a zopár skriptoch je hrubý základ aplikácie na svete a v priebehu niekoľko minút.
Po vygenerovaní potrebných súborov sa nám na stránke objaví zoznam položiek zo zvolenej tabuľky v databáze. Záznamy je možné upravovať ako je nižšie na obrázku ukázané. Taktiež je možné záznamy aj pridávať a zmazať. Všetko pekne v jednoduchom a prehľadnom dizajne. Podobné techniky generovania majú aj iné frameworky, ale nikde to nefunguje tak jednoducho, ako práve v Symfony. Po pár riadkoch kódu a zopár skriptoch je hrubý základ aplikácie na svete a v priebehu niekoľko minút.
<?php
/**
* autoMembers actions.
*
* @package ##PROJECT_NAME##
* @subpackage autoMembers
* @author Fabien Potencier <fabien.potencier@symfony-project.com
* @version SVN: $Id: actions.class.php 9855 2008-06-25 11:26:01Z FabianLange $ */
class autoMembersActions extends sfActions { public function executeIndex() { return $this->forward('members', 'list'); } public function executeList() { $this->processSort(); $this->processFilters(); // pager $this->pager = new sfPropelPager('Members', 20); $c = new Criteria(); $this->addSortCriteria($c); $this->addFiltersCriteria($c); $this->pager->setCriteria($c); $this->pager->setPage($this->getRequestParameter('page', $this->getUser()->getAttribute('page', 1, 'sf_admin/members'))); $this->pager->init(); // save page if ($this->getRequestParameter('page')) { $this->getUser()->setAttribute('page', $this->getRequestParameter('page'), 'sf_admin/members'); } } public function executeCreate() { return $this->forward('members', 'edit'); } public function executeSave() { return $this->forward('members', 'edit'); } public function executeEdit() { $this->members = $this->getMembersOrCreate(); if ($this->getRequest()->getMethod() == sfRequest::POST) { $this->updateMembersFromRequest(); $this->saveMembers($this->members); $this->setFlash('notice', 'Your modifications have been saved'); if ($this->getRequestParameter('save_and_add')) { return $this->redirect('members/create'); } else if ($this->getRequestParameter('save_and_list')) { return $this->redirect('members/list'); } else { return $this->redirect('members/edit?id='.$this->members->getId()); } } else { $this->labels = $this->getLabels(); } } public function executeDelete() { $this->members = MembersPeer::retrieveByPk($this->getRequestParameter('id')); $this->forward404Unless($this->members); try { $this->deleteMembers($this->members); } catch (PropelException $e) { $this->getRequest()->setError('delete', 'Could not delete the selected Members. Make sure it does not have any associated items.'); return $this->forward('members', 'list'); } return $this->redirect('members/list'); } protected function saveMembers($members) { $members->save(); } protected function deleteMembers($members) { $members->delete(); } ?>
Udalosť | Vzorky | Priemer [ms] | Stredná hodnota [ms] | Min [ms] | Max [ms] | Priepustnosť |
Test č. 1 | ||||||
AddUser |
10 |
3834 |
4732 |
1264 |
5000 |
15,6/min |
Users |
10 |
2103 |
2132 |
825 |
3147 |
28,4/min |
Members |
10 |
3125 |
2999 |
1265 |
5037 |
19,2/min |
EditUser |
10 |
3096 |
3029 |
1359 |
5003 |
19,3/min |
Celkovo |
40 |
3040 |
2996 |
825 |
5037 |
19,7/min |
Test č. 2 | ||||||
AddUser |
10 |
4347 |
4994 |
2981 |
5059 |
13,8/min |
Users |
10 |
2404 |
2975 |
1028 |
3010 |
24,9/min |
Members |
10 |
4125 |
5015 |
2353 |
5487 |
14,5/min |
EditUser |
10 |
4443 |
5059 |
2451 |
5518 |
13,5/min |
Celkovo |
40 |
3830 |
4523 |
1028 |
5518 |
15,6/min |
Test č. 3 | ||||||
AddUser |
10 |
2629 |
2217 |
1243 |
4469 |
22,8/min |
Users |
10 |
2257 |
2190 |
789 |
3008 |
26,5/min |
Members |
10 |
2626 |
2844 |
1798 |
3622 |
22,8/min |
EditUser |
10 |
3200 |
3003 |
1962 |
5549 |
18,7/min |
Celkovo |
40 |
2678 |
2500 |
789 |
5549 |
22,3/min |