<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I like PHP</title>
	<atom:link href="http://www.ilikephp.cz/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ilikephp.cz</link>
	<description>Jsem Štěpán Zikmund a píšu o vývoji webových aplikací</description>
	<lastBuildDate>Wed, 30 Dec 2009 23:37:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Zásady EMO-programování</title>
		<link>http://www.ilikephp.cz/blog/157-zasady-emo-programovani</link>
		<comments>http://www.ilikephp.cz/blog/157-zasady-emo-programovani#comments</comments>
		<pubDate>Wed, 30 Dec 2009 23:37:08 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[Zábava]]></category>
		<category><![CDATA[emo]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=157</guid>
		<description><![CDATA[
<p>Napsal jsi kód a jsi na něj hrdý. Máš to za sebou. Je odpoledne a
paprsky světla slavnostně rozpouští obraz tvého monitoru do nečitelnosti.
Nevadí ti to. Proč by taky mělo. Napsal jsi kód, jsi na něj hrdý a od
monitoru můžeš odejít.</p>

<p>Možná jsi to takhle dřív dělal. Možná že i teď ještě máš radost
ze svého kódu. Ale zítra […]</p>
]]></description>
			<content:encoded><![CDATA[
<p>Napsal jsi kód a jsi na něj hrdý. Máš to za sebou. Je odpoledne a
paprsky světla slavnostně rozpouští obraz tvého monitoru do nečitelnosti.
Nevadí ti to. Proč by taky mělo. Napsal jsi kód, jsi na něj hrdý a od
monitoru můžeš odejít.</p>

<p>Možná jsi to takhle dřív dělal. Možná že i teď ještě máš radost
ze svého kódu. Ale zítra už ne. Protože od teď se budeš pevně opírat
o <strong>pravidla EMO-programování</strong>:</p>

<h3>Zatáhni si závěsy, řízni se a nakresli si na tvář slzy</h3>

<p>Nechci tě vidět, jak se raduješ. Nechci vidět, že jsi hrdý. Nechlub se
mi, kolik metod si dnes napsal. Vůbec mě nedojímá to, který framework jsi
zase zkusil. Nechci poslouchat, jak nadšeně dodržuješ principy MVC
architektury. Nezajímá mě, kolik řádků kódu jsi dneska napsal.</p>

<h4>Zatáhni závěsy</h4>

<p>Světlo tě ruší. Ještě stále ti připomíná, jak prozařovalo tvoje
štěstí z odvedené práce. Musíš se ho zbavit. Schovej svůj kód před
světlem. Světlo svítí nejvíce na nejvyšší vrstvy. Vidíš spoustu
doménové logiky ve svém controlleru? Schovej ji do modelů.</p>

<p>Nakonec, až budeš mít v controlleru jen nejnutnější obsluhu, budeš
už mít tolik síly, že se ti podaří zvednout se a zatáhnout si
závěsy.</p>

<h4>Řízni se</h4>

<p>Stejně jako již ze tvé tváře nenávratně zmizela radost, musí zmizet
i tvé algoritmy, které se na tebe ve tvých modelech smějí každý ze tří
stran. Vezmi nůž. Vezmi si ten nejostřejší nůž, který najdeš, a
řízni. Seřízni svůj duplicitní kód, vytvoř pro něj zvláštní funkce a
tam ho natlač.</p>

<p>Přes bolestný šrám cítíš jisté uspokojení. Není to štěstí. Není
to radost. Není to nic z těch pocitů, které jsi do dneška poznal.</p>

<h4>Nakresli si na tvář slzy</h4>

<p>Nyní již píšeš <strong>EMO-kódy</strong>. A tvá duše je již stejně
prázdná jako kamenný pohled tvých očí. Jsi ve finále. Dnes naposledy
vezmeš do rukou klávesnici a na tvář si vytetuješ slzy.</p>

<p>Teprve, až tvůj kolega zítra ráno uvidí tvoje slzy, tvoje slzy
připomínající zavináče – ať už budou vypadat jako
<strong>@param</strong> nebo <strong>@return</strong> nebo ještě jinak –
až tehdy pochopí, že EMO-programování je styl, kterým chce
žít taky.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/157-zasady-emo-programovani/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Doménová logika ve webových aplikacích, díl 0</title>
		<link>http://www.ilikephp.cz/blog/147-domenova-logika-ve-webovych-aplikacich-dil-0</link>
		<comments>http://www.ilikephp.cz/blog/147-domenova-logika-ve-webovych-aplikacich-dil-0#comments</comments>
		<pubDate>Tue, 08 Dec 2009 13:55:59 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[O vývoji]]></category>
		<category><![CDATA[doménová logika]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=147</guid>
		<description><![CDATA[
<p>Aneb Co je to doménová logika v očích klasika i klasické ekonomie</p>

<p>„To je oč tu běží.“</p>

<p>William Shakespeare</p>

<p>Doménová logika je zřejmě tou esencí, díky které aplikace píšeme a
díky které nikdy nebudeme nezaměstnaní. Jde v podstatě o souhrn
veškerých algoritmů, které probíhají v prostoru mezi uživatelským
rozhraním a daty.</p>

<p>Pokud pojem doménová logika neznáte, nebojte se, že o něco
přicházíte. Stejně ji totiž používáte. Doménová logika není žádná
speciální vrstva […]</p>
]]></description>
			<content:encoded><![CDATA[
<h3>Aneb Co je to doménová logika v očích klasika i klasické
ekonomie</h3>

<blockquote>
	<p>„To je oč tu běží.“</p>

	<p>William Shakespeare</p>
</blockquote>

<p>Doménová logika je zřejmě tou esencí, díky které aplikace píšeme a
díky které nikdy nebudeme nezaměstnaní. Jde v podstatě o souhrn
veškerých algoritmů, které probíhají v prostoru mezi uživatelským
rozhraním a daty.</p>

<p>Pokud pojem doménová logika neznáte, nebojte se, že o něco
přicházíte. <strong>Stejně ji totiž používáte</strong>. Doménová
logika není žádná speciální vrstva v aplikaci, na kterou musíte myslet.
Není to ani žádný návrhový vzor, který byste se museli učit.</p>

<p>Ke vzniku doménové logiky stačí nechat se vést <strong>neviditelnou
rukou zadavatele</strong>.</p>

<p>A co když jde jen o takové to domácí programování a sepsaná aplikace
žádnou doménovou logiku nepotřebuje, protože je prostě úplně blbá a jen
ukládá data z formulářů do databáze? Tak to si zas o své aplikaci
nemyslete. Aplikace, ač úplně blbá, obsahuje doménovou logiku snad alespoň
v tom, že data validuje, vybere, kam je uložit, nebo vám v nich hbitě
vyhledává.</p>

<p>Prostě si napište co chcete a tu doménovou logiku tam najdete. Jakto?
Protože ta neviditelná ruka funguje a ne že ne!</p>

<h3>Tak to prostě neřeš!</h3>

<p>Nicméně dobrá otázka je nasnadě. Jaký smysl má o tom spekulovat,
když je to taková přirozená věc? Proč o tom přemýšlet, když všechno
můžu spočítat v akci controlleru?</p>

<p>Čím více je neviditelná ruka zadavatele lačná po možnostech vaší
aplikace, tím se do aplikace dostává doménové logiky více a více. Až
najednou člověk zjistí, že jeho controller je dlouhý jak Bible. A co když
se neviditelná ruka při zadávání utne a chce nějaký výpočet změnit?
<strong>Zkoušeli jste někdy upravovat Bibli?</strong></p>

<p>Proto se slovutný guru lidu programátorského <a
href="http://martinfowler.com/">Martin Fowler</a> uvolil utvořit přístupy
k tomu, jak s doménovou logikou v aplikaci zacházet. Tak vzniklo několik
<a href="http://martinfowler.com/eaaCatalog/">návrhových vzorů</a>, které
nám ukazují, kam se kdy vydat a kdy změnit směr, aby se naše doménová
logika mohla pod neviditelnou rukou zadavatele dennodenně prohýbat.</p>

<p>Zkuste uhodnout, o čem bude několik příštích článku :)</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/147-domenova-logika-ve-webovych-aplikacich-dil-0/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nenuťte programátory přemýšlet</title>
		<link>http://www.ilikephp.cz/blog/131-nenutte-programatory-premyslet</link>
		<comments>http://www.ilikephp.cz/blog/131-nenutte-programatory-premyslet#comments</comments>
		<pubDate>Mon, 02 Nov 2009 21:26:38 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[O vývoji]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=131</guid>
		<description><![CDATA[
<p>Nemáme to lehké. Vývojář by měl při práci stále myslet na to, aby
byl jeho výsledek rychlý, bezpečný, fungoval správně a vůbec. A přitom
stále naráží na problémy, které nejsou zásadní. Zato jsou však
zásadně otravné.</p>

<p>Furt se někam odkazovat</p>

<p>Typickým příkladem takového problému je ve vývoji webové aplikace
vytvoření odkazu. Ubohého vývojáře při psání HTML kódu pro odkaz
napadá spousta otázek. Na […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Nemáme to lehké. Vývojář by měl při práci stále myslet na to, aby
byl jeho výsledek rychlý, bezpečný, fungoval správně a vůbec. A přitom
stále naráží na problémy, které nejsou zásadní. Zato jsou však
zásadně otravné.</p>

<h3>Furt se někam odkazovat</h3>

<p>Typickým příkladem takového problému je ve vývoji webové aplikace
vytvoření odkazu. Ubohého vývojáře při psání HTML kódu pro odkaz
napadá spousta otázek. Na jakou URL přesně se odkazuji? Jaká je absolutní
cesta k aplikaci? A nebude mi stačit relativní? Potřebuji mít na odkazu
nějakou třídu? Má mít id?</p>

<p>A jaký bude text odkazu? A co když odkaz něco maže, nemá nejdřív
vyskočit dialog pro potvrzení akce?</p>

<p>Smůla, zubožený vývojář je již vyčerpán řešením předchozích
otázek natolik, že do odkazu prostě něco napíše. Na přesnou syntax pro
<em>confirm</em> si nevzpomene. Ale co, však to jde i bez té prudy.</p>

<h3>Udělej to líp. Myslím jednoduše</h3>

<p>Takovéto problémy nám většinou vyřeší náš aplikační framework.
Ejhle, v Zend Frameworku jsem však očekávaný helper pro vytvoření odkazu
nenašel. Nu což, tu je jiný:</p>

<pre
class="brush:php">
class Stepiiik_View_Helper_Link
{
  public $view;

  /**
   * @param name text odkazu
   * @param url array (klice controller, action..)
   * @param array s dalsima moznostma: confirm (text), button (boolean), id (text), class (text)
   */
  public function link($name, $url, $params = null)
  {
    $html = '&lt;a href="' . $this-&gt;view-&gt;url($url, null, true, true) . '"';
    if (is_array($params)) {
      if (array_key_exists('confirm', $params)) {
        $html .= ' onclick="return confirm(\''.addslashes($params['confirm']).'\')"';
      }
      if (array_key_exists('id', $params)) {
        $html .= ' id="'.addslashes($params['id']).'"';
      }
      if (array_key_exists('class', $params)) {
        $html .= ' class="'.addslashes($params['class']).'"';
      }
      if (array_key_exists('button', $params)) {
        $html .= ' class="button"';
      }
    }

    $html .= '&gt;'. $name . '';

    return $html;
  }
}
</pre>

<p>A jak vložit odkaz do stránky teď? Stačí mi vědět, jaký bude text
odkazu. Znát název controlleru a akce. Popřípadě vědět, jestli má mít
odkaz nějaký další atribut nebo potvrzovací <em>confirm</em>.</p>

<pre
class="brush:php">
echo $this-&gt;link('Kousnout koně',
  array('controller' =&gt; 'kone', 'action' =&gt; 'kousnout'),
  array('confirm' =&gt; 'Kůň se bude zlobit...'));
</pre>

<h3>Zábava nade vše</h3>

<p>Trapně prosté. Leč ono se s tím opravdu o mnoho zábavněji dělá.
A náhle aplikace se radostně ptá na každé mazání či jiné nebezpečné
kroky. <strong>Halt, když tam ten <em>confirm</em> může vývojář vložit
bez přemýšlení, tak to udělá.</strong> A rád. A vždy.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/131-nenutte-programatory-premyslet/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Přístup k databázím v Zend Frameworku</title>
		<link>http://www.ilikephp.cz/blog/114-pristup-k-databazim-v-zend-frameworku</link>
		<comments>http://www.ilikephp.cz/blog/114-pristup-k-databazim-v-zend-frameworku#comments</comments>
		<pubDate>Sun, 18 Oct 2009 18:13:29 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=114</guid>
		<description><![CDATA[
<p>Přestože jsem svou bakalářskou práci obhájil již letos v lednu,
doposud jsem neměl vhodné medium k jejímu vypuštění do světa. Nyní jej
mám, tak hurá na to.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Přestože jsem svou bakalářskou práci obhájil již letos v lednu,
doposud jsem neměl vhodné medium k jejímu vypuštění do světa. Nyní jej
mám, tak hurá na to.</p>

<p>V práci můžete najít:</p>

<ul>
	<li>Popis Zend Frameworku a MVC architektury</li>

	<li>Návrhové vzory pro objektově-relační vzory podle <a
	href="http://martinfowler.com/">Martina Fowlera</a></li>

	<li>Přístup k objektově-relačnímu mapování v Zend Frameworku</li>

	<li>Možnosti navázání objektů Zend_Db_Table na vrstvu business logiky</li>

	<li>Několik dalších návrhových vzorů týkajících se přístupu
	k databázi</li>
</ul>
<object style="width:500px;height:695px">
<param name="movie"
value="http://static.issuu.com/webembed/viewers/style1/v1/IssuuViewer.swf?mode=embed&amp;viewMode=presentation&amp;layout=http%3A%2F%2Fskin.issuu.com%2Fv%2Fcolor%2Flayout.xml&amp;backgroundColor=000000&amp;showFlipBtn=true&amp;documentId=091018141827-4ad261cadab24058a9d0694c4a3f1ca6&amp;docName=p__stup_k_datab_z_m_v_zend_frameworku&amp;username=stepan.zikmund&amp;loadingInfoText=P%C5%99%C3%ADstup%20k%20datab%C3%A1z%C3%ADm%20v%20Zend%20Frameworku&amp;et=1255876932144&amp;er=12"
/>
<param name="allowfullscreen" value="true" />
<param name="menu" value="false" />
<embed src="http://static.issuu.com/webembed/viewers/style1/v1/IssuuViewer.swf"
type="application/x-shockwave-flash" allowfullscreen="true" menu="false"
style="width:500px;height:354px"
flashvars="mode=embed&amp;viewMode=presentation&amp;layout=http%3A%2F%2Fskin.issuu.com%2Fv%2Fcolor%2Flayout.xml&amp;backgroundColor=000000&amp;showFlipBtn=true&amp;documentId=091018141827-4ad261cadab24058a9d0694c4a3f1ca6&amp;docName=p__stup_k_datab_z_m_v_zend_frameworku&amp;username=stepan.zikmund&amp;loadingInfoText=P%C5%99%C3%ADstup%20k%20datab%C3%A1z%C3%ADm%20v%20Zend%20Frameworku&amp;et=1255876932144&amp;er=12"
/></object>
<p>Práci si můžete také <a
href="http://www.ilikephp.cz/wp-content/uploads/2009/10/zaverecna_prace-2.pdf">stáhnou</a>.
(PDF, 600 kB).</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/114-pristup-k-databazim-v-zend-frameworku/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nesnadné verzování a deployment databáze, 3. díl</title>
		<link>http://www.ilikephp.cz/blog/90-nesnadne-verzovani-a-deployment-databaze-3-dil</link>
		<comments>http://www.ilikephp.cz/blog/90-nesnadne-verzovani-a-deployment-databaze-3-dil#comments</comments>
		<pubDate>Thu, 15 Oct 2009 10:29:38 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[O vývoji]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=90</guid>
		<description><![CDATA[
<p>V předchozích článcích jsem popsal nedostatky různých způsobů, jak
verzovat a aktualizovat strukturu databáze ve vývojářském týmu, a
teoreticky jsem rozjímal nad možnostmi řešení.</p>

<p>Poměrně dlouhou dobu jsem se snažil takovéto řešení najít. Našel
jsem je právě ve chvíli, kdy jsem se smířil s tím, že je vytvořím jako
první a budu slavný.</p>

<p>Jmenuje se PEAR:DbDeploy</p>

<p>Knihovnu DbDeploy si můžete stáhnout z SourceForge. V dokumentaci
tamtéž naleznete popis instalace.</p>

<p>Nástroj […]</p>
]]></description>
			<content:encoded><![CDATA[
<p>V předchozích článcích jsem popsal <a
href="http://www.ilikephp.cz/blog/4-nesnadne-verzovani-a-deployment-databaze">nedostatky
různých způsobů</a>, jak verzovat a aktualizovat strukturu databáze ve
vývojářském týmu, a <a
href="http://www.ilikephp.cz/blog/12-nesnadne-verzovani-a-deployment-databaze-2-dil">teoreticky
jsem rozjímal</a> nad možnostmi řešení.</p>

<p>Poměrně dlouhou dobu jsem se snažil takovéto řešení najít. Našel
jsem je právě ve chvíli, kdy jsem se smířil s tím, že je vytvořím jako
první a budu slavný.</p>

<h3>Jmenuje se PEAR:DbDeploy</h3>

<p>Knihovnu <a href="http://dbdeploy.com">DbDeploy</a> si můžete stáhnout
z <a href="http://sourceforge.net/projects/peardbdeploy/">SourceForge</a>.
V dokumentaci tamtéž naleznete popis instalace.</p>

<p>Nástroj DbDeploy se ovšem zřejmě již nevyvíjí. Ze stránek <a
href="http://pear.php.net/pepr/">PEARu</a> lze zjistit, že se zatím do
oficiálního PEAR balíku nedostal. Poslední verze je asi 700 dní stará a
mírně zabugovaná.</p>

<p>Několik chyb, které mi v použití nástroje bránily, jsem opravil.
Bohužel mi licenční podmínky brání opravenou verzi šířit. Pokud <a
href="mailto:stepan.zikmund&#64;gmail.com">mi napíšete</a>, rád vám pošlu
alespoň informaci o těch chybách.</p>

<h3>Tak se ukaž</h3>

<p>Myšlenka nástroje je opravdu jednoduchá. V projektu existuje složka
obsahující tzv. <strong>delta soubory</strong>. Tedy soubory SQL příkazů,
které strukturu databáze převedou z verze X na verzi X+1. Soubory jsou
pojmenovány podle konvence ve tvaru <em>‚číslo verze – popis verze .
sql‘</em>. Do souboru se zároveň mohou vepsat příkazy, které naopak
změny databáze zruší.</p>

<pre
class="brush:sql">
alter table kone add column pocet_zubu integer;

--//@UNDO

alter table kone drop column pocet_zubu;
</pre>

<p>[Poznámka] Reverzní příkazy se sice napsat pouze <strong>mohou</strong>,
nicméně klíčové slovo <em>UNDO</em> je povinné.</p>

<p>V databázi je vytvořena tabulka, do které se ukládá číslo poslední
nahrané verze.</p>

<p>DbDeploy obsahuje nástroj pro příkazovou řádku, který se připojí
podle parametrů k databázi, načte její aktuální verzi a vytvoří seznam
příkazů, který ji převede na verzi nejnovější. Zároveň se vytvoří
i soubor, který případně změny vrátí.</p>

<pre class="brush:bash">
dbdeploy -c ./DbDeploy/deploy-devel.ini
</pre>

<h3>Jednoduchost vykoupíme pravidly</h3>

<p>DbDeploy je založen na velmi jednoduché myšlence. A proto je potřeba mu
vyjít vstříc zavedením určitého workflow.</p>

<ol>
	<li>Vývojář musí ukládat SQL příkazy podle daných konvencí. Soubor
	musí obsahovat klíčkové slovo <em>undo</em> a reverzní příkazy. Musí
	být umístěn v odpovídající složce a jeho jméno musí začínat číslem
	o jedničku vyšším, než je číslo posledního souboru. Číslo je nutné
	při commitu upravit, pokud se v repository objevily nové soubory.</li>

	<li>Vývojář by měl svou databázi aktualizovat vždy přes DbDeploy, aby se
	struktura a verze databáze nedostaly do nekonzistentní­ho stavu.</li>

	<li>Je potřeba striktně zakázat opravování již commitovaných SQL
	souborů, neboť DbDeploy na již zpracovanou verzi nebude brát znovu
	zřetel.</li>

	<li>Vhodné také je, aby vývojáři commitovali SQL soubory co nejdříve. Tj.
	nejpozději při commitování zdrojových kódů s odpovídající
	funkcionalitou. Jinak může nadále docházet k situaci, kdy zbytek
	vývojářů pracuje delší čas na zastaralé verzi databázové
	struktury.</li>
</ol>

<p>V tomto workflow jsem však narazil na jednu nejasnost. Ve většině
případů měním databázi tak, že příkazy napíšu do souboru, spustím
update přes DbDeploy a, pokud vše funguje, soubor commituji.</p>

<p>Problém nastane, pokud nastane chyba. Je pak třeba buďto ručně opravit
verzi databáze a spustit znovu opravený soubor nebo vytvořit soubor nový.
Protože zřejmě nemá smysl, aby se všem při updatu opakovaly mé chyby,
volím téměř vždy první možnost.</p>

<p>Extrémním případem je pak vytváření databázových procedur nebo
složitějšího view. Tedy úkonů, u kterých není pravděpodobné, že
proběhnou napoprvé správně. Abych při vývoji neztrácel čas neustálím
upravováním verze struktury, pracuji zde bez ohledu na popsané workflow. Až
finální SQL příkaz nahraji do souboru, stejně jako undo příkaz, který
také ručně provedu. Teprve pak soubor commituji a updatuji databázi
standardně dle workflow.</p>

<h3>Rozvíjej se…</h3>

<p>Takto koncipované řešení má pro mě jeden zásadní bonus. V budoucnu
umožní zavedení automatického procesu, který dokáže automaticky zpracovat
všechny kroky nasazování aplikace. Toto téma zde určitě rozvinu.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/90-nesnadne-verzovani-a-deployment-databaze-3-dil/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Píseň] Koně a webové frameworky</title>
		<link>http://www.ilikephp.cz/blog/85-pisen-kone-a-webove-frameworky</link>
		<comments>http://www.ilikephp.cz/blog/85-pisen-kone-a-webove-frameworky#comments</comments>
		<pubDate>Sun, 11 Oct 2009 12:29:51 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[Zábava]]></category>
		<category><![CDATA[frameworky]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=85</guid>
		<description><![CDATA[
<p>Moravská lidová píseň vyprávějící o tom, jak se jednoho krásného
dne koně rozhodly napsat svojí vlastní webovou aplikaci.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Moravská lidová píseň vyprávějící o tom, jak se jednoho krásného
dne koně rozhodly napsat svojí vlastní webovou aplikaci.</p>
<object width="560" height="340">
<param name="movie"
value="http://www.youtube.com/v/fqTjqYv0p8Q&amp;hl=cs&amp;fs=1&amp;" />
<param name="allowFullScreen" value="true" />
<param name="allowscriptaccess" value="always" />
<embed src="http://www.youtube.com/v/fqTjqYv0p8Q&amp;hl=cs&amp;fs=1&amp;"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="560" height="340" /></object>
<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/85-pisen-kone-a-webove-frameworky/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Napiš aplikaci v Zend Frameworku dřív než řekneš CRUD</title>
		<link>http://www.ilikephp.cz/blog/50-jak-napsat-aplikaci-v-zend-frameworku-nez-bys-rekl-crud</link>
		<comments>http://www.ilikephp.cz/blog/50-jak-napsat-aplikaci-v-zend-frameworku-nez-bys-rekl-crud#comments</comments>
		<pubDate>Sat, 10 Oct 2009 23:55:21 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=50</guid>
		<description><![CDATA[
<p>Možná někoho z vás napadlo, že jste se nestali programátory kvůli
tomu, abyste pět dní v týdnu vkládali, editovali, zobrazovali a mazali data
z databáze. Mě to kdysi přestalo bavit a naučil jsem se pracovat se Zend
Frameworkem.</p>

<p>Styl mé práce se tím rapidně zefektivnil. Ovšem stejně jsem znovu psal
spoustu metod pro vkládání, editování, zobrazování a mazání dat
z databáze. A to mě nebavilo.</p>

<p>Tak […]</p>
]]></description>
			<content:encoded><![CDATA[
<p>Možná někoho z vás napadlo, že jste se nestali programátory kvůli
tomu, abyste pět dní v týdnu vkládali, editovali, zobrazovali a mazali data
z databáze. Mě to kdysi přestalo bavit a naučil jsem se pracovat se <a
href="http://framework.zend.com">Zend Frameworkem</a>.</p>

<p>Styl mé práce se tím rapidně zefektivnil. Ovšem stejně jsem znovu psal
spoustu metod pro vkládání, editování, zobrazování a mazání dat
z databáze. A to mě nebavilo.</p>

<p>Tak jsem si napsal abstraktní CRUD controller. Jediné co je nyní potřeba
udělat pro napsání správy tabulky databáze je model, formulář a několik
šablon.</p>

<h3>Chcete to taky dělat rychle?</h3>

<p>Jediné, co potřebujete, je stáhnout si <a
href="http://github.com/stepiiik/CrudController">nejnovější verzi
controlleru</a> z GitHubu. Jedinou třídu, kterou tam naleznete, nahrajete ve
svém projektu do adresáře <em>/library/Stepi­iik/</em>.</p>

<h3>Jak na to, hm?</h3>

<p>Pro názorné vysvětlení práce s CRUD controllerem vytvoříme
jednoduchou aplikaci, která schraňovat data o svých oblíbených
koních.</p>

<p>Vytvoříme tedy jednoduchou tabulku <em>kone</em>:</p>

<pre
class="brush:sql">
create table kone (
    id serial,
    jmeno varchar,
    barva int4,
    constraint kone_pkey primary key (id)
);
</pre>

<p>[Poznámka] Tabulka je vytvořena v SQL dialektu databáze PostgreSQL.</p>

<p>Nejprve vytvoříme model. Klasicky potomka <em>Zend_Db_Table</em>, který
navíc bude umět vrátit číselník barev koní.</p>

<pre
class="brush:php">
class Kone extends Zend_Db_Table
{
        protected $_name = 'kone';

        public static function getBarvy()
        {
                return array(
                        1 =&gt; 'Hnědák',
                        2 =&gt; 'Bělouš',
                );
        }
}
</pre>

<p>Druhým krokem bude vytvoření formuláře.</p>

<pre
class="brush:php">
class KoneForm extends Zend_Form
{
        public function init()
        {
                $this-&gt;setMethod('post');

                $this-&gt;addElement('text','jmeno', array(
                        'label' =&gt; 'Jméno',
                        'required' =&gt; true,
                ));

                $this-&gt;addElement('select','barva', array(
                        'label' =&gt; 'Barva',
                        'required' =&gt; true,
                        'multiOptions' =&gt; Kone::getBarvy(),
                ));

                $this-&gt;addElement('button', 'ulozit', array(
                        'label'  =&gt; 'Uložit',
                        'ignore' =&gt; true,
                        'type'   =&gt; 'submit',
                ));
        }
}
</pre>

<p>Důležité je zde u tlačítka na uložení nastavit atribut
<em>ignore</em> na <em>true</em>. Jinak by se aplikace snažila do databáze
ukládat i sloupeček <em>ulozit</em>.</p>

<p>Nyní už můžeme vytvořit koňský controller:</p>

<pre
class="brush:php">
class KoneController extends Stepiiik_CRUDController
{
        protected function getModel()
        {
                return new Kone();
        }

        protected function getForm()
        {
                return new KoneForm();
        }
}
</pre>

<p>Zdá se vám to jednoduché? No, ono to totiž je jednoduché.</p>

<p>Posledním úkonem, který bude potřeba udělat je vytvořit šablony
<em>kone/edit.phtml</em> a <em>kone/create.phtml</em>, ve kterých vypíšeme
vlastnost <em>$this-&gt;form</em>. Taková šablona může vypadat
například takto:</p>

<pre
class="brush:php">
&lt;h2&gt;Nový kůň&lt;/h2&gt;
&lt;?= $this-&gt;form ?&gt;
</pre>

<p>No a je to! Nyní zbývá už jen vytvořit si <em>index</em> akci a její
šablonu, která bývá většinou specifická a proto jsem se rozhodl ji do
controlleru nezařadit. Avšak její implementaci controller požaduje a
defaultně do ní přesměrovává své akce.</p>

<pre
class="brush:php">
public function indexAction()
{
        $koneTable = new Kone();
        $select = $koneTable-&gt;select()-&gt;order(array('jmeno'));
        $this-&gt;view-&gt;kone = $koneTable-&gt;fetchAll($select);
}
</pre>

<p>A šablona…</p>

<pre
class="brush:php">
&lt;h2&gt;Koně&lt;/h2&gt;
&lt;?php
foreach ($this-&gt;kone as $kun) {
    ?&gt;Výpis koně&lt;?php
}
?&gt;
</pre>

<p>Vidíte, že skutečně nebylo potřeba velké množství kódu k funkční
aplikaci. V budoucnu napíšu o pokročilejších možnostech CRUD
controlleru. Každopádně si již teď nechte s chutí ušetřit čas. A ve
volným času třeba čtěte moje <a
href="http://twitter.com/stepiiik">tweety</a>.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/50-jak-napsat-aplikaci-v-zend-frameworku-nez-bys-rekl-crud/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nesnadné verzování a deployment databáze, 2. díl</title>
		<link>http://www.ilikephp.cz/blog/12-nesnadne-verzovani-a-deployment-databaze-2-dil</link>
		<comments>http://www.ilikephp.cz/blog/12-nesnadne-verzovani-a-deployment-databaze-2-dil#comments</comments>
		<pubDate>Thu, 01 Oct 2009 17:47:03 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[O vývoji]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=12</guid>
		<description><![CDATA[
<p>V minulém článku jsem popisoval způsoby verzování databáze při
vývoji. Oba dva způsoby nefungovaly zrovna optimálně.</p>

<p>Do červnového vydání magazínu PHP Architect napsal Ivo Jansch článek
o deploymentu aplikace, kde byly popsány i možnosti nasazování
aktualizací databáze. Jansch popsal následujících pět úrovní zralosti
úpravy databáze při aktualizaci aplikace.</p>

<p>Změny jsou prováděn ručně.</p>

<p>Během vývoje se změny ukládají v podobě SQL příkazů. Z nich<br />
aktualizace vytváří vývojáři ručně.</p>

<p>Při aktualizaci se vytvoří seznam „undo“ […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>V <a
href="http://www.ilikephp.cz/blog/4-nesnadne-verzovani-a-deployment-databaze&quot;">minulém
článku</a> jsem popisoval způsoby verzování databáze při vývoji. Oba dva
způsoby nefungovaly zrovna optimálně.</p>

<p>Do červnového vydání magazínu <a href="http://www.phparch.com/">PHP
Architect</a> napsal <a href="http://www.jansch.nl/">Ivo Jansch</a> článek
o deploymentu aplikace, kde byly popsány i možnosti nasazování
aktualizací databáze. Jansch popsal následujících pět úrovní zralosti
úpravy databáze při aktualizaci aplikace.</p>

<ol>
	<li>Změny jsou prováděn ručně.</li>

	<li>Během vývoje se změny ukládají v podobě SQL příkazů. Z nich
	aktualizace vytváří vývojáři ručně.</li>

	<li>Při aktualizaci se vytvoří seznam <em>„undo“</em> SQL příkazů,
	které umožní vrátit databázi do stavu před aktualizací.</li>

	<li>Existuje nástroj pro automatický výběr SQL příkazů ze souborů
	vytvořených dle 2. úrovně.</li>

	<li>Při nasazení se produkční databáze automaticky aktualizuje pomocí
	porovnání s vývojovou.</li>
</ol>

<p>Stav naší firmy v minulém článku byl na úrovni 2. A jak jsem se
snažil ukázat, tento stav nebyl zcela optimální.</p>

<p>Při posuzování stavu, do kterého bychom se rádi dostali, jsme
postupovali od nejvyšší úrovně. Vývojáři nemívají problémy se
zaznamenáváním SQL příkazů, takže i 3. a 4. úroveň je
přijatelná.</p>

<p>Na základě tohoto rozhodnutí jsme se sestavili následující požadavky
na výsledné řešení:</p>

<ol>
	<li>SQL příkazy budou ukládány ve stejném repozitory verzovacího systému
	jako zdrojové kódy aplikace</li>

	<li>Musí být zaznamenána informace, které soubory již byly na určité
	databázi provedeny</li>

	<li>Možnost automatického provedení příkazů, které v určité databázi
	ještě provedeny nebyly</li>

	<li>Řešení by mělo dokázat vytvářet <em>„undo“</em> příkazy</li>
</ol>

<p>Poslední otázkou bylo, zda se bude nástroj pro aktualizaci databáze
vyvíjet nebo se podaří najít odpovídající řešení. Odpověď se
dozvíte v příštím článku.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/12-nesnadne-verzovani-a-deployment-databaze-2-dil/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Nesnadné verzování a deployment databáze</title>
		<link>http://www.ilikephp.cz/blog/4-nesnadne-verzovani-a-deployment-databaze</link>
		<comments>http://www.ilikephp.cz/blog/4-nesnadne-verzovani-a-deployment-databaze#comments</comments>
		<pubDate>Sat, 26 Sep 2009 17:06:51 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[O vývoji]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=4</guid>
		<description><![CDATA[
<p>Jedním z problémů při týmové práci více vývojářů je verzování
struktury databáze. Špatné řešení může při práci na projektu
způsobovat komplikace hned na dvou místech.</p>

<p>1. Při vývoji je potřeba, aby měli vývojáři vždy k dispozici
nejnovější verzi databáze. 2.Během nasazování na produkční prostředí
je třeba stávající databázi aktualizovat na novou verzi.</p>

<p>Ve firmě, kde pracuji, jsme při vývoji několika větších projektů
řešili tento problém dvěma […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Jedním z problémů při týmové práci více vývojářů je verzování
struktury databáze. Špatné řešení může při práci na projektu
způsobovat komplikace hned na dvou místech.</p>

<p>1. Při vývoji je potřeba, aby měli vývojáři vždy k dispozici
nejnovější verzi databáze. 2.Během nasazování na produkční prostředí
je třeba stávající databázi aktualizovat na novou verzi.</p>

<p>Ve firmě, kde pracuji, jsme při vývoji několika větších projektů
řešili tento problém dvěma způsoby.</p>

<ol>
	<li>Pro každou novou verzi aplikace byl vytvořen soubor, do kterého se
	ukládaly SQL příkazy měnící předchozí stav databáze. Soubor byl
	verzován stejným způsobem jako zdrojové kódy aplikace. Při nasazení nové
	verze aplikace se provedly všechny SQL příkazy, které soubor obsahoval.</li>

	<li>Ke každé změně aplikace (přidání nové funkce, oprava chyby…) byl
	vytvořen soubor obsahující potřebené SQL dotazy. Ten se také ukládal ve
	stejném úložišti jako zdrojové kódy.Při nasazení nové verze byli
	zavolány SQL příkazy ze všech souborů, které se od posledního nasazení
	změnily.</li>
</ol>

<p>Obě řešení tak nějak fungovali. Jenže pouze tak nějak.</p>

<p>U prvního řešení se naráželo na problém s akutalizací stavu
databáze na vývojových prostředí jednotlivých vývojářů. Při
aktualizaci stavu souboru s SQL příkazy vývojář vždy musel ručně najít
na konci souboru příkazy, které na jeho vývojové databázi ještě nebyly
provedeny. Ano, není to zase tak obtížný úkon. Je to však právě tak
nesnadný úkon, aby se vývojář ve slabé chvíli rozhodl, že databázi
aktualizuje až příště a tím pádem začal pracovat se starou verzí
databáze.</p>

<p>Druhé řešení, které původně mělo tento nedostatek odstranit nakonec
bylo ještě horší. Vývojáři začali rychle ztrácet přehled, který
soubor příkazů již do své vývojové databáze zanesli. Nesnadnost toho
rozhodnutí způsobila, že praktický v žádný okamžik několika
měsíčního vývoje ani jeden vývojář nepracoval se zcela aktuální verzí
databáze.</p>

<p>Jistě si domyslíte, když jeden vývojář odevzdává práci vytvořenou
na starší verzi databáze než jeho kolega, který na projektu pracuje také,
mohou v projektu vzniknout chyby. A to evidentně zbytečné chyby.</p>

<p>Druhé řešení se navíc ukázalo jako neefektivní i během nasazování
nové verze aplikace. Vývojář, který nasazoval novou verzi, musel ručně
projít soubory SQL příkazů a provozní databázi a zavolat příkazy pouze
z těch souborů, které ještě zaznamenány nebyly. Taková práce
vývojáři pak zabrala často celý den. A opět zcela zbytečně.</p>

<p>Jak jsme tento problém řešili dál, napíšu příště. A jak to
řešíte u vás?</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/4-nesnadne-verzovani-a-deployment-databaze/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mám citovou vazbu na svou profesi a nebojím se to říct</title>
		<link>http://www.ilikephp.cz/blog/70-mam-citovou-vazbu-na-svou-profesi-a-nebojim-se-to-rict</link>
		<comments>http://www.ilikephp.cz/blog/70-mam-citovou-vazbu-na-svou-profesi-a-nebojim-se-to-rict#comments</comments>
		<pubDate>Sun, 20 Sep 2009 00:46:22 +0000</pubDate>
		<dc:creator>Štěpán Zikmund</dc:creator>
				<category><![CDATA[Nezařazené]]></category>

		<guid isPermaLink="false">http://www.ilikephp.cz/?p=70</guid>
		<description><![CDATA[
<p>Baví mě programovat. Baví mě si o tom číst. A baví mě o tom
i psát. Takže by bylo super, kdybych mohl mít svůj vlastní blog o to co
naprogramuji a přečtu. Ne? No, já bych si to tak přál.</p>

<p>Takže jsem tu: I LIKE PHP :)</p>

<p>Píšu webové aplikace a intranetová řešení. Píšu je v PHP a je to
dobrý. Za ta léta vývoje jsem došel k určitým […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Baví mě programovat. Baví mě si o tom číst. A baví mě o tom
i psát. Takže by bylo super, kdybych mohl mít svůj vlastní blog o to co
naprogramuji a přečtu. Ne? No, já bych si to tak přál.</p>

<p>Takže jsem tu: <strong>I LIKE PHP</strong> :)</p>

<p>Píšu webové aplikace a intranetová řešení. Píšu je v PHP a je to
dobrý. Za ta léta vývoje jsem došel k určitým pracovním postupům a
znalostem. A o některých z nich vám rád poutavě napíšu.</p>

<p>Rád píšu i javascriptové frontendy, takže se možná zmíním
i o jiných technologiích než je PHP.</p>

<p>Tož se těšte… Hurá!</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://www.ilikephp.cz/blog/70-mam-citovou-vazbu-na-svou-profesi-a-nebojim-se-to-rict/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
