Přejít k navigační liště

Zdroják » Databáze » Doctrine 2: úvod do systému

Doctrine 2: úvod do systému

Články Databáze, PHP

Doctrine 2 je nový ORM framework pro jazyk PHP. V porovnání s již existujícími systémy pro mapování objektů na relační databázi přináší zajímavý posun a má velkou šanci stát se v budoucnu převládajícím ORM pro aplikace psané v jazyce PHP. V několika dílech tohoto seriálu si Doctrine 2 postupně představíme.

Co je a co není Doctrine 2

Hned na úvod je potřeba si říct, co můžeme od Doctrine 2 očekávat a co už naopak tento systém neřeší. Doctrine 2 je prostě a jednoduše ORM (Object-Relational Mapping). Zajišťuje tedy mapování objektů na relační databázi. Nic víc a nic méně.

Pokud nevíte, co si vůbec představit pod zkratkou ORM, přečtěte si předtím krátký seriál ORM frameworky pro PHP.

Zmiňuji to proto, že spousta lidí bude určitě při svém prvním setkání z Doctrine 2 velice zklamaná. Budete zde totiž postrádat celou řadu funkcí a vlastností, na které jste byli zvyklí třeba z předchozí verze Doctrine. Úplně zde například chybí behaviours zajišťující snadné verzování, řazení, hieararchizaci, vícejazyčnost a řadu dalších užitečných chování.

Tyto chybějící funkce a vlastnosti jsou sice příjemné a užitečné, ale do ORM vrstvy skutečně nepatří. Jejich mícháním s ORM se navíc celý systém stává složitým a netransparentním. Extrémním příkladem, kam to může dospět, je právě první verze Doctrine, což je jedna velká magie, kde se celá řada věcí děje neprůhledně tak nějak sama.

A vůbec, Doctrine a Doctrine 2 spolu mají společné snad pouze jméno. Jedná se o dva naprosto různé systémy, liší se od základů – filozoficky i implementačně.

Doctrine 2 je tedy už od začátku koncipována jako čisté ORM ořezané o jakoukoliv funkčnost, kterou lze realizovat ve vyšších vrstvách. Vše je v ní zcela transparentní, nikde se neprovádí žádná magie, nikde se nic nedělá samo. Systém vám prostě zajistí namapování objektů na databázi. V porovnání s předchozí verzí je tedy dvojka poměrně nízkoúrovňová. Pokud chcete cokoliv navíc, tak si to musíte udělat sami, nebo využít nějaké již existující nadstavbové řešení.

Právě tohle je ale největší plus celé Doctrine 2. Je průhledná, logická, systémová, konzistentní, čistá. Je to solidní základ pro vše další postavené nad ní.

Zatím jen beta

Určitě je ale nutné upozornit na to, že Doctrine 2 je stále ve vývoji. Aktuálně je uvolněná její druhá beta a vývojáři míří ke třetí. A upřímně řečeno, chyb a nefunkčností je v systému stále více než dost, do stabilní verze ještě nějaká ta práce zbývá.

Vážně míněné projekty na Doctrine 2 začněte vyvíjet jen tehdy, pokud systém opravdu důkladně znáte i se všemi jeho chybami a možnostmi řešení, anebo pokud plánujete ostré spuštění projektu až za několik měsíců.

Stejně tak dosud chybí celá řada výše zmíněných rozšíření, nadstavbových vrstev a vlastností. Programování s Doctrine 2 se tak dnes občas nese v rámci přístupu DIY – Do It Yourself.

Přes všechno řečené jsem ale přesvědčený, že právě teď je už ten správný čas se začít s Doctrine 2 seznamovat. Za pár měsíců z ní bude jedno z nejlepších ORM pro PHP vůbec.

Pár základních údajů

Doctrine 2 pro svůj běh vyžaduje PHP 5.3, na starších verzích ji už nerozběhnete. Využívá totiž nové vlastnosti jazyka, jako jsou namespaces, anonymní funkce nebo vylepšený garbage collector. Co se týká databází, podporuje zatím MySQL, PostgreSQL, Oracle a SQLite.

Celý systém je velmi silně inspirován javovským Hibernate. Bohužel se jeho vývojáři potýkají s několika záludnostmi a nesystémovostmi zakořeněnými v samotném jazyce PHP. V mezních případech tak při používání Doctrine 2 narazíte na pár podivností a omezení, které ale nelze v PHP nijak rozumně řešit. Postupně se na ně podíváme v příštích dílech seriálu.

Doctrine 2 je postavena na návrhovém vzoru Data Mapper, reprezentovaném vůči zbytku aplikace zejména fasádou v podobě Entity Manageru. Podařilo se jí oprostit se od Active Recordu, který využívá většina ostatních ORM.

Pro definici vlastností jednotlivých entit se elegantně využívají komentářové anotace. Není tedy nutné entity dědit od nějakého společného předka a můžeme si hierarchii dědičností udělat zcela dle svých potřeb.

Odstínění aplikace od databáze je dotaženo do dokonalosti. Když nechcete, nemusíte o databázi vůbec zavadit. Struktura databáze i veškeré její změny se generují automaticky z definic entit. Dokonce i klasické SQL dotazy lze nahradit DQL (Doctrine Query Language) notací, kde se místo názvů tabulek a atributů používají výhradně názvy entit a jejich členských proměnných.

Napříč celým systémem je už od základu myšleno na optimalizaci výkonu, což bývá slabinou mnoha ORM. K dispozici je cachování na několika úrovních. Kde to jde, používá se lazy-loading. Pokud chcete, můžete si snadno vynutit vlastní optimalizovaný dotaz do databáze namísto standardního chování.

Tři vrstvy

Doctrine 2 je ve skutečnosti rozdělena do tří vrstev:

Common
Definuje základní obecná rozhraní, třídy a knihovny. Například nástroje pro práci s kolekcemi, anotacemi, cachováním, událostmi apod. Ty jsou pak využívány oběma vyššími vrstvami. Common sám o sobě je ale na zbylých vrstvách nezávislý, takže jej teoreticky můžete používat i samostatně. Všechno, co sem patří, je definováno v namespace  DoctrineCommon.
DBAL (DataBase Abstraction Layer)
Abstrahuje zbytek aplikace od konkrétního typu databáze. Primárně rozšiřuje standardní PDO, ale umí pracovat i s jinými databázovými drivery. Zavádí také již zmíněnou notaci DQL (Doctrine Query Language), kterou si podrobněji představíme v některém z dalších dílů seriálu. DBAL je závislý na Common, ale můžete ho opět teoreticky používat i samostatně bez poslední ORM vrstvy. Všechno, co sem patří, je definováno v namespace  DoctrineDBAL.
ORM (Object-Relational Mapping)
Nejvyšší vrstva, která zajišťuje právě to, o co nám jde, tedy mapování aplikačních objektů na relační databázi, jejich persistování a načítání. ORM je závislá na DBAL i Common. Namespace této vrstvy je  DoctrineORM.

V tomto seriálu se budeme samozřejmě bavit především o ORM vrstvě. Je ale nutné vědět i o ostatních, protože mnoho věcí v Doctrine 2, včetně dokumentace, či downloadů toto rozdělení striktně kopíruje.

Zdroje, dokumentace a podpora

Instalace a konfigurace

Doctrine 2 si můžete stáhnout buď jako .tgz archív, nainstalovat s pomocí PEAR instalátoru, anebo rozbalit z GIT či SVN repozitáře. Jednotlivé odkazy pro stažení jsou uvedeny výše. Většinou stačí stáhnout jen ORM vrstvu, u které je přibaleno i vše ostatní, v některých případech je ale potřeba postahovat postupně všechny tři vrstvy jako tři různé repozitáře.

Pokud si chcete s Doctrine 2 zatím jen nezávazně hrát, stačí využít předpřipravený Sandbox, který také naleznete ve staženém balíčku.

Pro začlenění do své skutečné aplikace umístěte Doctrine 2 ideálně k ostatním knihovnám, například takto:

library
    Doctrine
        Common
        DBAL
        ORM
    Medio
    Nette
    Texy
    Zend

V dalším kroku pak musíte zajistit automatické načítání všech použitých tříd. Buď můžete využít svůj již používaný autoloading, například Nette robot loader, anebo vám Doctrine 2 nabízí možnost registrace svého vlastního autoloaderu:

use DoctrineCommonClassLoader;
// ...
require_once '/path/to/myproject/library/Doctrine/Common/ClassLoader.php';
$classLoader = new ClassLoader('Doctrine', '/path/to/myproject/library/Doctrine');
$classLoader->register();

Nakonec je nutné připravit alespoň základní konfiguraci a vytvořit instanci Entity Manageru. Co to vlastně ten Entity Manager je a co znamenají jednotlivé konfigurační volání, k tomu se dostaneme průběžně v dalších dílech seriálu.

use DoctrineORMConfiguration;
use DoctrineORMEntityManager;
// ...
// připravíme si Doctrine konfiguraci
$config = new Configuration;
// informace o entitách budeme brát z anotací v uvedeném adresáři
$metadata = $config->newDefaultAnnotationDriver('/path/to/myproject/entity');
$config->setMetadataDriverImpl($metadata);
// nastavení namespace a adresáře pro proxy třídy
$config->setProxyNamespace('MyprojectProxy');
$config->setProxyDir('/path/to/myproject/proxy');
// připravíme si konfiguraci databázového připojení
$database = array(
    'driver' => 'pdo_mysql',
    'host' => 'localhost',
    'dbname' => 'foobar',
    'user' => 'lorem',
    'password' => 'ipsum',
);
// vytvoříme instanci entity manageru
$em = EntityManager::create($database, $config);

Nyní už máme vše připraveno k tomu, abychom se v příštím dílu mohli pustit do prvních praktických kroků s Doctrine 2.

Komentáře

Subscribe
Upozornit na
guest
11 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Robert1234

Hned první odkaz v článku není zrovna ideální: file:///C:/DO­CUME%7E1/MARTIN%7E1­.MAL/LOCALS%7E1/Tem­p/_tc/doctrine-01-uvod.html

Martin Malý

Opraveno, díky za upozornění, omlouvám se.

Nox

Čtivý a jednoduše pochopitelný článek, díky! Jen tak dál

Ludek Vodicka

Vsem kdo pracuji s Doctrine2 nebo Doctrine bych doporucil nastroj ORM Designer.
Namisto oddelenho vytvareni modelu a rucniho psani vsech definic umoznuje ORMD cely objektovy model navrhnout visualne a pote jednoduse vyexportovat. Narozdil od MySQL workbench nebo DBDesigneru ma ale podporu vsech vlastnosti (a v pripade Doctrine i vsech behaviours) pro dany ORM framework.

andrej

Toto by malo vediet aj acceleo+emf, ale chcelo by to k tomu dobry tutorial. Nechce sa niekomu napisat?
Dalsia vec – ako zlozite je integrovat nette s doctrine2?

drevolution

Dalsia vec – ako zlozite je integrovat nette s doctrine2?
Je to velice jednoduché. Vzhledem k tomu, že Doctrine2 nevyžaduje žádné dědění nějaké základní třídy, tak můžeme vzít naše stávající entity z modelu (poděděné od NetteObject), oanotovat je a máme hotovo. Od této chvíle s nimi můžeme pracovat přes EntityManager.

Ondřej Mirtes

Nette není potřeba s Doctrine nijak integrovat, protože Nette nepředpisuje žádnou podobu modelů.
Stačí si tedy dát do config.ini přihlašovací údaje k databázi, do bootstrapu nějaké to základní nastavení (předvedené v článku), založit si vlastní Entity (nejlépe asi poděděnou od NetteObject) a zvesela začít psát entitní třídy a libovolně je v presenterech používat.

andrej

OK, pozrem to. Mam v plane prerobit nejake stare stranky a rozhodujem sa medzi yii a nette, pricom by som rad pouzil prave doctrine2.

blizzy

Škoda, že v článku není víc popsaná část toho posledního výstřižku kódu, konkrétně netuším, co si představit pod tou proxy a metadata driverem. Určitě to půjde dohledat v dokumentaci, ale v článku by to mělo být více vysvětleno.

drevolution

Počkej na další díly, jistě to vysvětlí.
Proxy se používají při práci s asociovanými entitami a naplno se využívají při jejich (lazy) načítání.
Metadata driver poskytuje entity manageru informace o entitách. Základní metadata drivery jsou tři: pro práci s Docblock anotacemi, pro práci s XML a pro práci s YAML.

drevolution

Jen doplním, že se zde nekonfiguruje EntityManager s aktivním kešováním metadat entit a DQL dotazů. V dokumentaci se silně doporučuje toto nějakým způsobem kešovat.

Do not use Doctrine without a metadata and query cache! Doctrine is highly optimized for working with caches. The main parts in Doctrine that are optimized for caching are the metadata mapping information with the metadata cache and the DQL to SQL conversions with the query cache. These 2 caches require only an absolute minimum of memory yet they heavily improve the runtime performance of Doctrine. The recommended cache driver to use with Doctrine is APC. APC provides you with an opcode-cache (which is highly recommended anyway) and a very fast in-memory cache storage that you can use for the metadata and query caches as seen in the previous code snippet.

http://www.doctrine-project.org/projects/orm/2.0/docs/reference/configuration/en#bootstrapping:obtaining-an-entitymanager

Nejjednodušší na použití je DoctrineCom­monCacheArra­yCache, která se aktivuje takto:

$cache = new DoctrineCommonCacheArrayCache();
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.