čtvrtek 21. prosince 2006

PHP vs JSP

Vím, že po internetu existuje spoustu srovnání programovacích jazyků. Já se ani nechci tak moc pouštět do srovnání jako osvětlit některé věci, které mi lezou v poslední době dost krkem.

Zejména se jedná o lži, které hlásají pubertální mladící, kteří si přečetli jeden článek, naprogramovali 100 řádků kódu a provádějí srovnání různých řešení mezi sebou. Často házejí špínu na věci, které neznají ani koncepčně, natož z pohledu vývojáře.

Když jsem začal s programováním, začal jsem na PHP, které se mi zdálo jako nejlepší volba. PHP bylo populární, rychle se rozvíjející jazyk, perspektivní, jednoduchý a dalo se najít spoustu tutoriálů po internetu.

Na začátku jsem byl vlastnostmi tohoto jazyka naprosto uchvácen a směle jsem prohlašoval, že je to geniální dílo :)

Dnes jsem již o mnoho skeptičtější a směle prohlašuji: PHP je bordel, který jsem se raději neměl učit. Důvodů, proč si něco takového myslím je několik a já proberu jen ty nejpalčivější:

  • každá nová verze je často nekompatibilní se starými skripty

  • dodnes neexistuje namespaces a to co jsem viděl v připravované verzi PHP6 mě nijak nenadchlo

  • OOP model je na příšerné urovni a programátor musí dodržovat spousty pravidel, aby se nenechal unést nesmyslnostmi jazyka

  • neexistuje schopný framework pro data (ORM, DAO)

  • php už od základu míchá aplikační a prezentační logiku dohromady

  • funkce v php nedokáží vracet výjimky, jen ty, které si sám napíši

  • znovupoužitelnost vlastních tříd je dost problematické, už z důvodu konceptu celého PHP



Mohl bych takto pokračovat dál a dál, ale to není záměrem mého příspěvku. Spíše než to, chci říci, že PHP nemá cenu tlačit někam, kam nepatří. A nyní bych ho už netlačil asi ani na web.

Našel jsem na: www.jakpsatweb.cz diskuzi o jsp-servletech. Názory o tom, že Java je framework nebo, že jsp je lepší šablonovač mě vážně pobavili. Nejsem žádný expert na jsp-servlety, spíše s nimi začínám, ale tohle už je moc :(

Srovnávat skripovací jazyk PHP s platformou jako je Java, je asi jako srovnávat cukroví s plechem na pečení (přece jen jsou vánoce :)).

Existují mýty o tom, že v JSP nelze napsat, to co v PHP. Je to omyl. Ba co více, je to neznalost konceptu JSP a PHP. JSP už od samého začátku (nepočítaje první verzi) vyzchází z patternu MVC (model-view-controller), který zaručuje oddělení aplikační od prezentační logiky. Navíc řešení webové aplikace v jave umožňuje více možností, jak danou aplikaci programovat (např. JSF).

Nebudu zde zabíhat do detailů, protože nejsem na Javu žádný znalec a primárně v ní "zatím" nevyvíjím, ale co vím jistě, je, že mi java umožňuje programovat nejen webové aplikace. Umožňuje mi použít JPA, umožňuje mi použít skutečně kvalitní IDE ve formě NetBeans či Eclipse. apod. apod.

Dalším mýtem bývá, že se Java nehodí na malé webové aplikace typu e-shop apod. Já v tomto stále nevidím problém. Ale vezmu to z druhé strany. Budu psát v PHP OOP kód. Budu se snažit využívat controllery a budu používat oddělení aplikační logiky od prezentační + použiji vlastní vrstvu na data ve formě jakéhosi paskvilu ORM s DAO. Než toto připravím, pokud nemám připravené vlastní skripty, zabere mi to spoustu času. PHP mi samozřejmě umožňuje danou aplikaci napsat procedurálním způsobem, který bude mixovat všechny vrstvy do sebe. Super, mám vše během chvilky, ale přestanu zvedat telefony ve chvíli, kdy po mě zákazník bude chtít další úpravy a další vylepšení. Raději tedy vše udělám podle MVC a budu dodržovat základní patterny, abych se vyhnul námaze při dalších úpravách. V podstatě to samé mohu udělat pomocí JSP-servletů aniž bych musel pracně dodělávat či mapovat "pofidérní" frameworky na dané vrstvy aplikace. Jak dlouho mi daná aplikace bude trvat v JSP, pokud použiji stávající frameworky, které jsou pro to přímo určené? Jak dlouho mi bude trvat sestavit aplikaci z vlastních tříd, které jsem použil minule?

Jediný důvod, proč se JSP nehodí na malé webové aplikace je ten, že neexistuje tak masivní podpora hostingů jako u PHP. To je nejzásadnější důvod, proč vlastně je JSP hozené pod PHP v oblasti vývoje web. aplikací po internetu. Lidé, kteří tvrdí, že se něco na něco nehodí by měli předem znát daný jazyk, aby mohli toto tvrdit. Já tyto výkřiky slyším pouze od lidí, kteří neumí OOP či neumí JSP.

Ukončím to malým srovnáním: kolik znáte programátorů, kteří přešli z OOP zpět na procedurální programování? Kolik znáte lidí, kteří přešli z Javy na PHP?

Nakonec jen malá ukázka pro PHPčkáře. Za jak dlouho byste byli schopni udělat toto, co Roman Štrobl v NetBeans?

pondělí 11. prosince 2006

HTML Framework 3 - Textarea

Posledním formulářovým políčkem, kterým se chci zabývat je textarea.

Využití tohoto prvku je dobré při uložení delšího textového řetězce s omezenou či neomezenou délkou. Existují i tzv. textarea wysiwyg editory, což je upravená textarea pomocí javascriptu, umožňující psát HTML kód pomocí vizuálních prvků. Je to dost specifická oblast, kterou se ale zabývat nechci. Spíše mi šlo o to, vytvořit si vlastní textareu, která bude míti možnost kontrolu maximálního počtu znaků na klientovi.

Stejně jako v předchozích případech, jsem si vytvořil v adresáří /lib/HTML/Form soubor Textarea.php a soubor Textarea.js. Již podle názvu je jasné, co dané soubory budou obsahovat.

Nebudu zde uvádět ukázku třídy HTML_Form_Textarea, ale nabídnu je rovnou ke stažení: HTML_Form_Textarea (php, js)

Samotné použití je opět velice jednoduché:

$textarea = new HTML_Form_Textarea("textove_pole", $_POST["textove_pole"]);
echo $textarea->getTextArea();


Pokud bych nechtěl použít js kód, nebo změnit jinou vlastnost, není to samozřejmě problém:

// zmeni maximalni pocet znaku
$textarea->setMaxPocetZnaku(500);
echo $textarea->getTextArea();

// vypne js omezeni
$textarea->setPosuvnik(false);


Šťouralové by samozřejmě namítli, že chybí ošetření vloženého textu. Například pomocí htmlspecialchars. Já jsem toto omezení zde vynechal. Záleží totž na tom, jak textareu chci využít, zda povolím některé HTML tagy, či nikoli. A toto by měla míti na starost vlastní definice v Model vrstvě (MVC).

Nyní oblast formulářových prvků opustím a budu se více zabývat tabulkami a způsobu, jakým jsem definoval jejich použití, společně s dalšími vlastnostmi, jako je export do XLS souborů, apod.

HTML_Form_Textarea (php, js)

pátek 8. prosince 2006

Vývojové prostředí pro webové aplikace (IDE)

Nejenom talent a zkušennosti jsou potřeba pro úspěšný vývoj aplikací. Další vlastností je vývojové prostředí IDE.
V dnešní době je možné nalézt spoustu jednoduchých editorů, které jsou schopny zvýrazňování syntaxe popřípadě další zajímavé vlastnosti.

Nejprve udělám malé srovnání nejznámějších editorů a poté si vyberu svého favorita :)

JEdit
Jeden z dobrých editorů je jEdit. Po potřeby úprav jednoduchých skriptíků ideální řešení. Mezi jeho hlavní přednosti jistě patří to, že je multiplatformní. jEdit je napsán v Javě. I přesto je velice rychlý a obsahuje možnost doinstalovat spousty pluginů.

PSPad
Velice populární editor, od českého vývojáře. Mezi jeho hlavní přednosti patří rychlost a jednoduchost. Velkou nevýhodou je, že dokáže pracovat pouze pod Windows. Ano linux verze se nekoná. Je vhodný spíše pro začátečníky a drobné úpravy.

SciTE
Na počátku jednoduchý editor, který ale vyniká svou rychlostí a konfigurovatelností. Je možné ho používat i pod linuxem. Po dobré konfiguraci zvládne i složitější úkony. O dalších informacích se můžete dozvědět např. u Jakuba Vrány.

Vim
Legendární editor textů linuxových nadšenců. Mezi jeho nesporné výhody patří extrémní rychlost a konfigurovatelnost. Velkou nevýhodou ovšem je to, že koncept Vimu je naprosto odlišný od ostatních editorů. Po prvním setkání vězte, že budete dlouho hledat, jak editor vypnout. :)

ZEND Studio
Skutečné IDE pro vývoj webových aplikací. Pokud to s PHP myslí někdo skutečně vážně, jistě výběrem tohoto IDE neprohloupí. Mezi jeho nevýhody patří to, že není zdarma a také, že je primárně určen pouze pro PHP.

Eclipse PHP IDE
Další skutečné IDE pro vývoj aplikací. Mezi jeho přednosti patří to, že je multiplaformní, dokáže se po instalaci patřičných pluginů, chovat jako vývojové prostředí téměř pro cokoli. Mezi jeho nevýhody patří snad jen to, že má náročnější požadavky na hardware a na začátku složitější konfiguraci. Existuje i placená verze ve formě MyEclipse, která obsahuje již nakonfigurovanou sestavu s další podporou.

Existuje samozřejmě nepřeberné množství editorů a IDE pro tvorbu webových aplikací, které lze na internetu dohledat. Mým hlavním záměrem bylo sepsat (z mého pohledu) nejpoužívanější nástroje pro psaní aplikací.

Po několikaletém programování ve SciTE jsem začal hledat něco, co by mi umožnilo editor povýšit na komplexní IDE se spoustou možností. Po testech s jEditem apod. jsem nakonec skončil s Eclipse. Mohu říci, že jsem po několikadenním testování a zkoušení dostal do ruky špičkový nástroj, který je navíc zdarma.

Eclipse je primárně tvořen pro vývoj Java aplikací. Navíc samotné IDE je psané v Jave, což umožňuje jeho použití na více OS. Samotný projekt Eclipse je dotován firmami jako je IBM, Red Hat či SuSE. Obsahuje extrémní množství pluginů jak pro samotné programování, tak i modelování databáze či v UML. Počet podporovaných jazyků lze najít na oficiálních stránkach, společně s pluginy pro jejich spuštění.

Osobně využívám plugin od ZENDu PHP IDE společně se WEB Tools (i z důvodu závislostí), dále plugin QuantumDB pro prohlížení databáze (používám na Oracle a MySQL) a SQL editor. V Eclipse jako platformě se meze nekladou. Je možné nad Eclipse vytvořit jak vlastní projekt, tak použít nějaký již napsaný.

O tom, co všechno Eclipse obsahuje a je možné v něm použít by vydalo na nejednu knihu. Já se zaměřím na podporu PHP přímo od ZENDu, HTML, CSS, JS a MySQL. Na závěr jen malá ukázka toho, co si vlastně pod IDE představuji.

Příště se budu zabývat prvním spuštěním Eclipse (pod Windows i Linuxem) a instalací pluginů.

čtvrtek 7. prosince 2006

Nová verze openSUSE 10.2

Tak nám již vyšla nová verze openSUSE 10.2, stahovat je možné zde.

Doufám, že se nové verzi povede lépe, než předchozí 10.1, kde po uvedení obsahovala závažnou chybu v ZMD pro update.

HTML Framework 2 - Input

Dalším formulářovým políčkem, které chci probírat je input. Možností, jak jej využít je mnoho, stačí se podívat třeba sem.

Opakovaného psaní, stejně definovaného políčka, se opět vyhneme pomocí definování vlastní třídy na tento formulářový prvek. Složitější oproti select-option je zejména v tom, že má mnohem více možností (text, submit, password, checkbox, ...).

V adresáři /lib/HTML/Form jsem si vytvořil soubor Input.php, zde uvádím jeho část:
class HTML_Form_Input
{

/***************************** ATRIBUTY TRIDY *****************************/

/** typ inputu podle ktereho se odviji jeho vlastnosti */
private $type;

/** nazev inputu */
private $name;

/** hodnota inputu value u checkox moznost checked */
private $request;

/** velikost inputu */
private $size;

/** maximalni pocet znaku inputu */
private $maxlength;

/** policko bude sede, nepujde menit */
private $disabled;

/** obsah pole nepujde menit */
private $readOnly;

/** zarovnani jako u obrazku */
private $align;

/** nastaveni class z CSS */
private $classCss;

/** stylovani tlacitka pomoci CSS */
private $style;

/** JS kod inputu */
private $javaScript;

/****************************** METODY TRIDY ******************************/

/**
* konstruktor tridy pro vytvoreni inputu
*
* @param String $name nazev inputu
* @param String $request vkladana hodnota value nebo checked
* @param int $size nepovinny parametr velikost policka
* @param int $maxlength nepovinny parametr maximalni pocet znaku
*
*/
public function __construct($name, $request, $size = null, $maxlength = null)
{
$this->name = $name;
$this->request = $request;
$this->size = $size;
$this->maxlength = $maxlength;

$this->type = "text";

$this->disabled = false;
$this->readOnly = false;

}
}


Kompletní třída ke stažení: HTML_Form_Input

Použití je velmi snadné a opět elegantnější, než psaní HTML kódu:

$test = new HTML_Form_Input("test", $_POST["test"]);
$test->getInput(); // vypise HTML kod input, defaltne typ text


Předefinovat na jiný typ je opět otázka chviličky:

$test->setTypeInput("checkbox"); // tlacitko bude checkox
$test->getInput();

$test->setTypeInput("password"); // tlacitko bude password
$test->getInput();


Možností je opravdu hodně a nemá cenu je zde všechny vypisovat. Opět je otázka, co všechno vývojář potřebuje. Nespornou výhodou, definování těchto malých oblastí, je i fakt, že jsou kdykoli rozšířitelné o vlastnosti, které jsem opomněl definovat při prvním návrhu.

Přístě se podívám na poslední, zajímavý formulářový prvek: textarea a na jeho omezení počtu znaků pomocí javascriptu.

Třída HTML_Form_Input

úterý 21. listopadu 2006

HTML Framework 1 - Select-option

Při programování v PHP se dostanete do fáze, kdy Vás přestane bavit znovu a znovu psát HTML kód pro formulářová políčka. Jedním ze způsobů jak si začít tvořit svou vlastní knihovnu takovýchto HTML komponent, je přejít na OOP kód a v závislosti na zkušennostech si předdefinovat to, co se často opakuje. Tím začnete tvořit svůj malý framework pro HTML výstup vašich webových aplikací.

Je jasné, že existuje spoustu hotových řešení, ale já jsem šel cestou (pro PHPčkáře osobitou) vlastní. Mou snahou je, se odprostit od psaní jakéhokoli HTML kódu při programování základních komponent. Při OOP návrhu tříd je dobré rozvrhnout, které třídy budou znovupoužitelné v jakékoli aplikaci a které nikoli. Jelikož se nyní bavím o HTML výstupu, který je pro PHP jako vzduch pro člověka, je jasné, že se jedná o třídy s vysokou znovupoužitelností.

Vytvořím si adresář /lib ve kterém budu mít třídy, které jsou znovupoužitelné v jakékoli webové aplikaci. Jelikož se jedná o HTML kód a formulářové políčko tak adresářovou strukturu definuji takto: /lib/HTML/Form/

První komponentou bude select-option.

Zkrácená ukázka vlastní třídy v souboru SelectOption.php:

/**
* trida vracejici html select-option
*
* @author Dostal Ales
* @version 1.0
* @date 21.11.2006
* @category lib
* @package HTML
* @subpackage Form
*
*/
class HTML_Form_SelectOption
{

/***************************** ATRIBUTY TRIDY *****************************/

// atribut tridy pro nazev selectu
private $nazev;

// atribut tridy pro data, ktera jsou poslana v poli
private $data;

// atribut tridy pro vybrany radek
private $request;

// atribut tridy pro vytvoreni prazdneho radku v optionu
private $firstNullOption;

// vklada do tagu
*/
public function getSelect()
{
$select = "\n";
return $select;
}


Kompletní třída ke stažení: HTML_Form_SelectOption

Budu nadále předpokládat, že máte vyřešený problém s automatickým nahráváním daných tříd přes __autoload().

Nyní již přichází na řadu malá ukázka, jakým způsobem lze komponentu využívat:

$data = array();
$data = array("ales" => "Aleš", "tomas" => "Tomáš");
$select = new HTML_Form_SelectOption("jmeno", $data, $_GET["jmeno"]);
echo $select->getSelect();


Pokud budu chtít například definovat prázdnou nulovou položku, stačí pred zavoláním o HTML kód přídat:

$select->setFirstNullOption("- jméno -");


Možností je samozřejmě více. Od definování javascriptového kodu do tagu select až po změnu dat, při použití jedné instance. Pokud by daná třída nevyhovovala, není samozřejmě problém přidat jakoukoli novou vlastnost (např. přidání k tagu css třídu, style, apod.).

Definování vlastních HTML komponent programátorovi natolik usnadní práci, že k opakovanému psaní HTML se snad již nikdy nevrátí.

Přístě se podívám na trošku složitější HTML tag: input.

Třída HTML_Form_SelectOption

středa 15. listopadu 2006

Závažná chyba při tvorbě triggerů

Původně jsem chtěl napsat článek o triggerech a jejich využití.
Zjistil jsem ale nepříjemnou chybu, která bez jakýchkoli servítek smaže můj pracně vytvořený trigger, aniž by mi databáze cokoli zdělila.

Jedná se o bug 18153 a jeho duplikace 18816.

Tato nepříjemná chyba mi při provedení dotazu REPAIR/OPTIMIZE/ALTER smaže trigger z information_schema. Problém je o to horší, že použitý název je uložen v souboru *.TRN, který se pro změnu zachová! Takže nyní mám smazaný trigger a navíc nemůžu použít původní název triggeru. Jediné možné řešení je fyzicky smazat soubory *.TRN a vytvořit trigger znovu.

Opět uvedu malý příklad:

CREATE DATABASE stupidni_test;
CREATE TABLE tabulka (
id int NOT NULL auto_increment,
nazev varchar(10) NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE tabulka_zaloha (
id int NOT NULL auto_increment,
nazev varchar(10) NOT NULL,
PRIMARY KEY(id)
);


A nyní si vytvořím trigger.

DELIMITER $$
/* tento prikaz muze vyhodit chybu, pokud trigger existuje, zde totiz existuje dalsi bug s IF EXISTS */
DROP TRIGGER nefungujes$$

CREATE TRIGGER nefungujes
AFTER INSERT ON tabulka
FOR EACH ROW
BEGIN
INSERT INTO tabulka_zaloha (id, nazev) VALUES (new.id, new.nazev);
END$$

DELIMITER ;


Vše se zdá být v pořádku:

SHOW TRIGGERS;


Nyní přidám jeden sloupeček do tabulky tabulka.

ALTER TABLE stupidni_test ADD COLUMN cislo int default '0' AFTER nazev;


A trigger je pryč:

SHOW TRIGGERS;


Vytvořím si ho znovu:

DELIMITER $$
DROP TRIGGER nefungujes$$

CREATE TRIGGER nefungujes
AFTER INSERT ON tabulka
FOR EACH ROW
BEGIN
INSERT INTO tabulka_zaloha (id, nazev) VALUES (new.id, new.nazev);
END$$

DELIMITER ;


Nevytvořím!

Trigger does not exist
Trigger already exists


Jediné možné řešení je nyní smazat soubor *.TRN nebo vytvořit trigger pod jiným názvem.

Tímto apeluji na všechny, kteří triggery používají: zálohujte si je!

Přístě už se budu věnovat těm triggerům a jejich využití. ;)

pondělí 13. listopadu 2006

MySQL 5.0 díl.2

Typ tabulky InnoDB zvládá i další vlastnost a tou je tzv. transakční zpracování. Ve chvíli, kdy Vaše aplikace bude používat akční dotazy nad důležitými daty, jistě budete hledat způsob, jak tyto data co nejlépe ošetřit.

K tomu dobře poslouží transakce. Setkal jsem se i s názory, kteří transakční zpracování odsuzují z toho či onoho důvodu. Já, jako člověk, který tyto věci využívá v praxi mohu jen podotknout, že je to pro mě určitá záchrana při práci s akčními dotazy.

Co to je, to transakční zpracování dat? Jedná se způsob, pomocí kterého mohu své předešlé kroky navrátit zpět nebo je potvrdit. Série příkazu UPDATE, DELETE, INSERT, které jsou spuštěny při transakčním zpracování, se provedou tehdy, když uznám, že po změně nedojde k znehodnocení dat. Fyzicky se dané akce provedou až po úspěšném ukončení, do té doby jsou dočasně uloženy jen jako série příkazů, které čekají na ukončení. To sebou přináší i tu vlastnost, že zpracování může být v polovině přerušeno (např. výpadkem proudu) a přesto je možné dané úkony dokončit. Je jasné, že tuto vlastnost musíme brát s rezervou a neočekávat vždy spásnou pomoc od nedokončených transakcí. Tím mám na mysli, že se daná série příkazů již nikdy neprovede, nikoli, že by znehodnotila data.

Příkazy pro transakční zpracování jsou následující:

  • start transaction – spouští provedení transakčního zpracování

  • rollback – navrací veškeré změny a uvede data zpět do stavu před spuštěnou transakcí

  • commit – potvrzuje příkazy, zapisuje změny a uvolňuje systémové prostředky potřebné při transakci



Použití transakcí
Domnívám se, že je zbytečné zde vypisovat sérii nějakých akčních dotazu, kde na konci provedu commit či rollback. Spíše než to, je lepší malá ukázka v PHP, jak lze transakce smysluplně využít.

Příklad:

class Error
{
private $error = array();

public function __construct() {}

public function addError($err)
{
if (!in_array($err, $this->error)) {
$this->error[] = $err;
}
}

public function isError()
{
return (boolean) count($this->error);
}

}

$mysqli = new mysqli(/* connect */);
$error = new Error();

$mysqli->query("start transaction");

$query = "UPDATE uzivatele SET prijmeni = 'Novák' WHERE login = 'paveln'";
if ($mysqli->query($query) === false) {
$error->addError($mysqli->error);
}

/* dalsi akcni dotazy */

if (!$error->isError()) {
$mysqli->query("commit");
} else {
$mysqli->query("rollback");
}


Použil jsem zde záměrně vlastní jednoduchou třídu na kontrolu chyb. Je jasné, že příklad je pouze ilustrativní, ale potvrzení transakce mohu provést jedině ve chvíli, kdy jsem si jist, že to má data nijak neznehodnotí. Toto považuji za smysluplné použití transakčního zpracování, kdy pomocí nějaké vlastní aplikace budu rozhodovat, zda sérii příkazů zruším, či potvrdím.

Při práci s tabulkami při transakčním zpracování bychom si měli dát pozor zejména na příkaz: TRUNCATE TABLE, který vymaže data z tabulky a nastaví auto_increment na 1. Po provedení takového příkazu totiž není možné pomocí rollback získat data zpět.

Omezení existuje celá řada, k tomu doporučuji manuál a prostudovat samotné transakce tam.

Poslední věcí o které se zmíním je nastavení automatických transakcí. V souboru my.cnf nalezneme direktivu innodb_flush_log_at_trx_commit, která pokud je nastavena na 1, provádí automaticky transakce. Toto chování se mi zdá nežádoucí a jako takové ho pro jistotu vypínám.
Důvod proč něco takového dělám je rychlost aplikace. Pokud například vkládám velké množství dat, které není nijak zásadní pro běh aplikace a data mám zálohována, provedu úkon bez transakčního zpracování. Jednou ohromnou nevýhodou je totiž extrémní nárůst potřebných systémových prostředků.

Transakce byste měli používat s rozvahou, ale také se jich nebát, protože sebou přináší jistý komfort při modifikaci dat.

V příštím díle se budu věnovat triggerům a důvodům, proč něco takového využívat.

pátek 10. listopadu 2006

MySQL 5.0 díl.1

Od verze 5.0 je možné využívat nových vlastností, které nabízí skutečnou správu dat v databázi.

Jednotlivé vlastnosti rozepíši do vlastních dílů.

V prvním díle se budu věnovat referenčním integritám. Referenční integritu bylo možné využívat již dříve. Respektive od doby, kdy MySQL podporovala typ tabulky InnoDB.

Proč vůbec databáze používá tuto vlastnost? Pokud začnu pracovat s daty v databázi, zjistím, že některé se přímo vážou na jiné. Dříve se používal způsob uchování těchto vazeb v aplikační úrovni.
Nevýhody, které to sebou přinášelo je hned několik:

  • programátor musel stále mít v paměti, která data jsou propojena a podle toho provozoval akční dotazy

  • při změně aplikace nad databází se znovu musely tyto vazby naprogramovat

  • při provedení UPDATE se museli projít všechny vazby a upravit hodnoty

  • a tak dále...



Při použití referenčních integrit v MySQL tyto nepříjemnosti odpadnou.

Jak jsem již psal na začátku, pro využití referenčních integrit musíte použít takový typ tabulky, který danou vlastnost podporuje. Osobně jsem volil nejlepší možnou variantu a to InnoDB.

Lepší než další povídání bude malý příklad:

Mám tabulku uživatelů a tabulku návštěvnosti. Dejme tomu, že u návštěvnosti budu uchovávat informace o počtu návštěv za každý den.

CREATE TABLE uzivatele (
login varchar(10) NOT NULL,
heslo varchar(255) NOT NULL,
jmeno varchar(100) NOT NULL,
prijmeni varchar(100) NOT NULL,
PRIMARY KEY(login)
)ENGINE=InnoDB;
CREATE TABLE uzivatele_navstevnost (
uzivatel varchar(10) NOT NULL,
datum date NOT NULL,
pocet int NOT NULL default '0',
PRIMARY KEY(uzivatel, datum)
)ENGINE=InnoDB;


Vše se zdá být v pořádku. Ale co se stane ve chvíli, kdy některý uživatel změní login? Co se stane ve chvíli, kdy některého uživatele smažu?
Nyní mám dvě možnosti, buď v aplikaci budu udržovat vztah uzivatele:login vs. uzivatele_navstevnost:uzivatel nebo použiji referenční integritu.

ALTER TABLE uzivatele_navstevnost
ADD CONSTRAINT fk_uzivatel_uzivatele
FOREIGN KEY(uzivatel) REFERENCES uzivatele(login)
ON UPDATE CASCADE ON DELETE RESTRICT;


Co jsem v podstatě udělal? Vytvořil jsem cizí klíč v tabulce uzivatele_navstevnost s nazvem fk_uzivatel_uzivatele. Nyní, pokud provedu UPDATE loginu v tabulce uzivatele, změní se mi login uživatele i v tabulce uzivatele_navstevnost. Pokud se pokusím smazat uživatele z tabulky uzivatele, dotaz skončí s chybou. Důvodem je definování DELETE RESTRICT. Zde je jasné, že vlastnost pro DELETE přepíši na CASCADE.

Samotný význam referenčních integrit není usnadnit práci vývojářům při manipulaci s daty, ale udržet data ve správné formě.
Vlastnosti pro UPDATE a DELETE pro cizí klíč jsou následující:

  • CASCADE - provede změny ve sloupci podle změny v referenčním sloupci

  • RESTRICT - znemožní upravit či smazat data

  • SET NULL - při nastaveni refenečního sloupce na NULL či smazání, nastaví se sloupec cizího klíče na NULL (zde samozřejmě je třeba, aby cizí klíč měl možnost obsahovat NULL)



Na předchozím příkladu jsem ukázal možnost vytvoření referenční integrity mezi dvěmi tabulkami, ale existuje možnost vytvoření takovéto integrity v zájmu jedné tabulky.

Příklad:

Budu mít tabulku zaměstnanců, která navíc obsahuje vztah nadřízený-podřízený.

CREATE TABLE zamestnanci (
osobni_cislo int NOT NULL,
jmeno varchar(100) NOT NULL,
prijmeni varchar(100) NOT NULL,
nadrizeny int default NULL,
PRIMARY KEY(osobni_cislo),
CONSTRAINT fk_nadrizeny_zamestnanci
FOREIGN KEY(nadrizeny) REFERENCES zamestnanci(osobni_cislo)
ON UPDATE CASCADE ON DELETE SET NULL
)ENGINE=InnoDB;


S definicí referenčních integrit navíc souvisí i správný návrh databáze. K tomuto problému lze říci jen jedno: mít zkušennosti.

V příštím díle se budu věnovat opět typu InnoDB a další vlastnosti a to transakčnímu zpracování.

čtvrtek 9. listopadu 2006

PHP 5.2

Tak nám vyšla nová verze PHP 5.2, která by měla vylepšit rychlost přímo v ZEND Engine.

Koukal jsem se na změny a je pravda, že pár věcí se zde pohlo k lepšímu. Otázkou však zůstává, zda se z toho paskvilu a neuspořádaného vývoje, v kterém se PHP ocitá dokáže ještě vymanit.

Microsoft sám začal mít o PHP zájem alespoň v podpoře .NET, ale jeden nikdy neví, kam to může zajít (InnoDB v MySQL vs. Oracle).
Jsou zde opravené některé věci, jako např. v abstraktní třídě nemůže existovat statická metoda, magická metoda __toString() nemůže vyhazovat výjimku apod.

Ale co mě stále štve na PHP je ta ignorace type hinting, s tím související přetěžování metod či konstruktorů, dále vyhazování výjimek z php funkcí namísto stupidního Boolean, nemožnost smysluplně vytvořit Singleton, apod.

Pokud se podívám na způsob práce s databází, je často zdůrazněna dobrá podpora MySQL, ale k čemu mi je taková vynikající podpora, když zde nemám pořádný nástroj na ORM, DAO, apod. (např. Hibernate v Jave). Je zde sice jakýsi Propel, ale... Jako standard to bráno není a asi ani nikdy nebude. (Ono MySQL by samo potřebovalo opravit pár věcí, kterými se honosí verze 5. Alespoň integrace nějakého smysluplného jazyka pro psaní stored procedure. V tomto nynějším stavu je to na cvokárnu.)
Jsem zvědavý jaké změny nám přinese PHP 6.0. Těším se zejména na věci jako definování návratových hodnot v metodách, přímou integraci s MySQL a s tím spojený jistý nárůst rychlosti.

Ale na druhou stranu zůstávám skeptický v tom, jestli se PHPko někdy pročistí a vzniknou frameworky, které budou standardem pro práci s danou vrstvou. Pokud ovšem PHP bude i nadále ignorovat type hinting, čistý oop model, zastaralé metody, způsob definování názvů metod, balíčkovací systém pro třídy, apod. tak nikdy nevzniknou frameworky, nikdy se nic nestane standardem a nikdy nebude ničím jiným než jazykem pro lamy :(