Weblog o Zend Frameworku

Vítejte na mém webu!

Tipy pro práci se Zend_Db II.

Protože hokej se Švédy začíná až za 30 minut (update: měl jsem jít raději spát), věnuju ten čas druhému dílu u Zend_Db a konkrétně Zend_Db_Table a souvisejícím třídám Zend_Db_Table_Row a Zend_Db_Table_Rowset.

Zend_Db_Table je obal nad klasickou tabulkou. Každá tabulka musí mít primární klíč, jinak není možné vytvořit potomka. Metody insert(), update() i delete() jsou implementovány podle předpokladů, ale pozor na překrývání metod. Tyhle metody volají jiné třídy zend_Db a pokud změníte signaturu metody, zamává vam fatal error. Instanci adaptéru je možné předat přes statickou metodu Zend_Db_Table::setDefaultAdapter().

Na začátku instance se volá SQL příkaz DESCRIBE TABLE, který načte strukturu tabulky a bude se podle ní chovat. Tenhle příkaz je možné cachovat přímým napojením na Zend_Cache, otázka však je, zda načtení nějakého souboru s definicí tabulky není časově náročnější než jednoduchý příkaz. Navíc musíte dávat pozor na změny struktury.

Zend má také dvě třídy Zend_Db_Table_Rowset, která obaluje výsledek SQL dotazu a Zend_Db_Table_Row, která reprezentuje řádek tabulky.

Zajímavou metodou je find(), která přijímá hodnotu primárního klíče.

 $row = $table->find(1)->current();
$row->status = ‚ujednano‘;
$row->save();

Metoda current() je metodou třídy implementující iterator a vrací jeden řádek v tabulce. Třída má implementovanou magickou metodu __get, takže je možné přistupovat k hodnotám sloupce přes atributy. Má to jednu malou nevýhodu, není možné standardně používat konvence Zendu v takovém přístupu. Pokud máte sloupec „jmeno_jmeno“, pak k němu musíte přistupovat jako

 $row->jmeno_jmeno;

což není moc pěkné a hezčí by bylo převádět atributy podle cammelCase jako

 $row->jmenoJmeno;

Naštěstí je možné snadno zaregistrovat vlastní třídu předka Zend_Db_Table_Row a změnit metodu _transformColumn(). Je otázka, proč tohle standardně Zend nemá implementováno, nicméně je to jen detail.

Krom metody current() je možné volat i fetchRow() pro složitější dotazy a fetchAll() pro navrácení více řádků tabulky. Na těchto metodách je možné volat metodu toArray(), která přesune výsledek do pole. Ale pozor, pokud nebude vrácen žádný výsledek, vyskočí fatální chyba. Počet řádků je možné ověřit přes metodu count() díky implementaci rozhraní Countable.

 if ($row = $table->fetchRow($table->select()->where(‚id = ?‘, 1))) {
$data = $row->toArray();
}

Nový řádek lze vytvořit přes metodu createRow() podobným způsobem jako editace uvedená jako první příklad článku, nebo můžete využít první parametr metody createRow(), což způsobí volání metody $table->setFromArray().

 $table->createRow(array(‚name‘  ⇒ 'jmeno))->save();

Podobně je možné volat metodu delete() pro smazání záznamu. Výsledek metody fetchAll() je samozřejmě možné procházet přes foreach, přičemž při každé iteraci je vrácena instance třídy Zend_Db_Table_Row.

Chcete-li pravidelně provádět nějakou akci před vložením, po vložení, před editací, po editací, před smazáním či po smazání řádku, je možné zdědit třídu Zend_Db_Table_Row a implementovat metody _insert(), postInsert() ap. Tohle v manuálu tuším není.

Poslední díl tohodle miniseriálu bude věnován tomu nejzajímavějšímu, vztahům mezi tabulkami.

Případné reakce posílejte prosím na jakub.mrozek@gmail.com. Díky.

| 12. 5. 2008 Po 05.39 | Zend Framework | 0 komentářů | 75x

Tipy pro práci se Zend_Db I.

O Zend_Db panuje hodně zvěstí o tom, co umí a co ne. Podle mě je to velice dobře použitelný nástroj pro přístup k databázi a protože Zend_Db používám už více než rok, rozhodl jsem se sepsat něco málo o jeho pokročilejších funkcích. Nečekejte žádný tutoriál, bude to jen strohý výpis různých tipů. Dnes první část.

Zend_Db_Select

Zmíněná třída je obal nad čistým SQL dotazem:

 $select = $this->getAdapter()->select();
$select->from($this->name, array(‚id‘, new Zend_Db_Expr(‚NOW()‘)))
->joinLeft(‚tabulka‘,‚podminka‘, ‚vybrany_sloupec‘)
->limit(10);

Třídu Zend_Db_Expr() je nutné použít všeude, kde nechcete sloupce ošetřit data jako identifikátory.

Pokud jste používali Zend_Db_Select dříve a chtěli jste použít klíčové slovo DISTINCT pro vyfiltrování duplicit, byl to problém. Od novějších verzí je dostupná metoda distinct(), která klíčové slovo vloží za vás.

Databaze MySQL obsahuje vychytávku pro získávání celkového počtu řádek, konstantu SQL_CALC_FOUND_ROWS (více na blogu Jakuba Vrány http://php.vrana.cz/…tu-radek.php). Chcete-li ji použít u Zend_Db_Select, pak to udělat třeba takto:

 $select->from(‚tabulka‘, new Zend_Db_Expr(‚SQL_CALC_FOUND_ROWS tabulka.*‘));

Zda používat či nepoužívat Zend_Db_Select je věcí názoru, někomu se tento přístup líbí, někomu ne. Já už Zend_Db_Select používam na všechny dotazy, protože můžu SQL dotaz snadno sestavovat v různých částech třídy a narozdíl od klasického SQL můžu třeba přidat jako první klauzuli LIMIT a až poté WHERE.

Dobře se Zend_Db_Select hodí u filtrování, setřízení a stránkování výsledků. Každý možný sloupec, podle kterého je možné třídit, bude vlastní instance jedné třídy a uvnitř modelu pak tyto třídy budu volat a předávat jim instanci zend_Db_Select a každá třída SQL může pozměnit.

Inicializace stránkování, filtrování a setřízení může vypadat takto:

 //vytvoreni strankovani
$paging = new Ronnie_Paging();
$paging->setMaxItemsOnPage(Setup::maxItemsOnPage());
$paging->setPage;

//init filtrovacího formuláře
//v poli $values je výsledek ze Zend_Form
$filters = array(
new Ronnie_Crud_Int(‚id‘, $values[‚id‘]),
new Ronnie_Crud_Straight(‚status‘, $values[‚status‘]),
new Ronnie_Crud_String(‚headline‘, $values[‚headline‘]),
);

//výsledek setřízení
$order = new Ronnie_Crud_Order(
$this->_request->getQuery(‚order‘),
$this->_request->getQuery(‚by‘)
);
//povolené sloupce setřízení
$order->setAllowed(array(‚id‘, ‚status‘, ‚headline‘));

Metoda modelu, která vrátí všechny výsledky:

 public function fetchAllPaging(Ronnie_Paging $paging, array $filters = array(), Ronnie_Crud_Order $order = null)
{
$select = $this->getAdapter()->select();
$select->from(‚tabulka‘, new Zend_Db_Expr(‚SQL_CALC_FOUND_ROWS tabulka.*‘))
->joinLeft(‚tabulka2‘, ‚tabulka2.sloupec = tabulka1.sloupec‘)
->limit($paging->getDbOffset(), $paging->getDbLimit());

foreach ($filters as $filter) {
$filter->process($select);
}

if ($order) {
$order->process($select);
}

$data = $this->getAdapter()->fetchAll($select);
$paging->setNumRows($this->fetchFoundRows());
return $data;
}

Třídy Ronnie_Crud implementují rozhraní s metodou process(), které se předává instance třídy Zend_Db_Select a metoda této instanci přidává sql podmínky, které určují třídy Ronnie_Crud_*. Např. Ronnie_Crud_Int() umožňuje používat operátory > < =, takže pokud hodnota $values[‚id‘] bude „<5“, pak metoda process() zavolá metodu

 $select->where(‚id < 5‘);

Takový přístup má pro mě velkou výhodu v tom, že metodu fetchAllPaging() je možné implementovat poměrně univerzálně a v 90% případů je potřeba měnit pouze metodu $select->from() či $select->joinLeft(), definice filtrování, setřízení i stránkování je mimo metodu a je to implementováno zcela univerzálně.

Popsané řešení má také výhodu v tom, že všechna data, která jdou na databázi, jsou důkladně ošetřena, což u filtrování a setřízení není zvykem (stačí se podívat i na velmi známe projekt a změnit sloupec filtrování v URL a často na vás vyskočí SQL chyba).

Přidávejte prosím případné komentáře přes email jakub.mrozek@gmail.com, díky.

| 12. 5. 2008 Po 00.04 | Zend Framework | 0 komentářů | 87x

První eshop na Shopiu

Frekvence příspěvku tady na weblogu klesá s blížícím se deadline pro vydání Shopia, řešení pro eshopy. Před několika měsíci jsme si naplánovali první verzi (beta verzi) na dnešní datum, což se podařilo a na adrese market.medievum.cz můžete vidět první eshop.

Konečná verze bude dostupná za dva měsíce od dnešního dne. Za 4 týdny bude dostupná demoverze, kde vás pustíme do administrace, kterou graficky navrhlo Nuvio. Současná verze eshopu se tedy ještě bude výrazně měnit (jiná galerie fotografií, některé ajaxové vychytávky, parametrické vyhledávání, další platební možnosti, …)

Něco málo o Shopiu

Shopio je „krabicové řešení“ pro internetové obchody vytvořené pod hlavičkou W3W. Krom výchozích šablon je možné vytvořit unikátní design, který si můžete nechat udělat od W3W, popř. od jiné firmy (preferujeme špičkové Nuviu). Shopio zatím funguje pouze pro češtinu, nicméně po překladu textových hlášek je možné Shopio provozovat okamžitě v cca 170 různých lokalizačních verzích (např. uzpůsobení formátu data či měny) vč. oblastí jako např. Botswana či Rwanda:-)

Celý systém je tvořen tak, aby bylo možné snadno provádět upgrady na vyšší verze. Např. v první verzi budou jen základní statistiky, pokročilejší modul statistik připravujeme někde na období prázdnin. Pokud si pořídíte obchod dříve, než bude tento modul dostupný, nebude problém provést upgrade na vyšší verzi a statistiky budete mít okamžitě dostupné, a to i v případě, že bude eshop přizpůsoben konkrétním podmínkám, tedy úvodní stránka bude mít třeba ajaxové vyhledávání ap.

Důraz při tvorbě obchodů je kladen na požadavky přístupnosti a použitelnosti. Celý eshop funguje bez javascriptu, CSS, obrázků. Shopio také podporuje standard klávesových zkratek, přičemž zavádí i další možnosti (přechod na košík přes klávesové zkratky). Kdo si zakládá na validitě, tak toho potěšíme, všechny články z WYSIWYG editorů prochází přes HTML Tidy a celý eshop má validní kód. Zájemce o novinky snad potěšíme podporou mikroformátů.

Na Shopiu je možné provozovat různý sortiment zboží, při návrhu jsme vycházeli z nejlepších eshopů u nás i v zahraničí s různým sortimentem (třeba obchody s fotoaparáty, suplementy pro kulturitiku, pc technika, prodej knih, oblečení ap.).

Pro editaci textů je možné používat různé WYSIWYG editory nebo špičkový Texy!, přes který prochází každý vložený komentář. Texy! je mimochodem pevnou součástí eshopu, pro Shopio máme zakoupenou multilicenci, dostanete jej tedy zdarma i pro komerční účely.

Technická stránka

Shopio nemá žádné zvláštní nároky, může běžet na základních variantách hostingu. K provozu stačí 8 MB paměti, doporučeno je 16 MB. Jako hosting doporučujeme partnerský ToJeOno.cz (kvůli větši rychlosti a maximální spokojenosti).

Co se týče rychlosti, aktuální verze Medievum nepoužívá žádné cachování ani optimalizaci databáze, což se změní s vydáním Shopia do světa. Shopio bude obsahovat vlastní způsob cachování dat s php kódem na principu kompilace šablon u Smarty. Tak bude možné cachovat i dynamické stránky, které se mění při každém požadavku a není potřeba generovat cache pro každého návštěvníka zvlášť. Tuhle knihovnu bych pak chtěl tady na weblogu zveřejnit.

Celé řešení je postaveno na Zend Frameworku a javascriptových knihovnách YUI od Yahoo! a JQuery. Ze Zend Frameworku se skutečně hodně těží a nedokážu si už dnes představit jeho absenci a až výjde Shopio do světa, určitě zde zveřejním sposty technických článků o Zend Frameworku. Používáno je maximum ze Zend Frameworku, třeba každé datum je instance Zend_Date, každá měna instance Zend_Currency, používá se plně Zend_Form či Zend_Db. Používáno je 26 ze 41 knihoven, které jsou aktuálně v Zend Frameworku.

Toď vše. Kdo čekáte na tipy k Zend Frameworku, tak bys vás mohl odkázat na Steve.eho blog pro články o Zend Frameworku a Unit testech, k M. Kubelíkovi pro články o Zend_Form a k Matthew Weier O'Phinney na jeho fantastické články o Zendu (Matthew mimochodem patří do „síně slávy PHP“, to jen tak na okraj).

| 28. 4. 2008 Po 23.45 | Obecně | 6 komentářů | 184x

Zend Framework 1.5 oficiálně vydán!

Žádná unstable verze, dnes byl oficiálně vydán Zend Framework 1.5.

Přepracován byl také celý design stránek, který je teď mnohem více přehlednější.

| 17. 3. 2008 Po 14.59 | Zend Framework | 7 komentářů | 428x

Zend_Framework a webhosting ToJeOno.cz: fantastická kombinace!

Generování webů postavených na Zend Frameworku pod 0.1s? Žádný problém. Dnes jsem nahrával aktuální verzi Shopia na náš hosting, který máme u ToJeOno.cz a rychlost mne doslova šokovala. Čekal jsem generování stránky kolem 0.2 – 0.3, jak je běžné u ostatních hostingů a na mém notebooku, ale rychlost byla daleko lepší.

Některé stránky s číselníky se běžně generují v čase kolem 0.07 – 0.09, editační formulář nepřesáhhne 0.1. A to zcela bez ostychu používám Zend_Form, Zend_Db (na každý dotaz Zend_Db_Select), Zend_Locale a další knihovny, u kterých mám z rychlosti obavy.

Jak je to možné? Webhosting ToJeOno používá Zend Optimizer a Zend Accelerator, a to nejspíš stojí za tak radikálním zrychlením. Pro mne to momentálně znamená to, že se vůbec nemusím starat o rychlost Zend Frameworku a můžu naplno používat všech možností, které nabízí.

Webhosting ToJeOno.cz rozhodně doporučuji pro hostování vašich projektů, nedávno jsem přecházel od minulého webhostera kvůli několika dlouhým výpadkům a nikdy jsem lepšího webhostera nezažil (prošel jsem cca 7 hostingů). Konečně je to hosting, kde administrátoři nepředpokládají zákazníkovu nesvéprávnost, když zakazují .htaccess (minimálně kvůli toho jsme se Shopiem odešli od Českého hostingu). Jedinou vadou na kráse je nutnost požádat o nastavení subdomény přes mail, což ale ve třech případech netrvalo ani jednou déle než 15 minut. Rozhodně tedy doporučuji.

| 7. 3. 2008 Pá 19.34 | Obecně | 6 komentářů | 630x

Pokračuj: 1-5 6-7

Upozornění!

Články ze staršího weblogu najdete na adrese history.ronnieweb.net

Nové komentáře

Nevaeh Mathews Ronnie Techi

Zpětné odkazy

209.85.135.104 google.com google.com
Texy!