Doctrine 2: úvod do systému

Doctrine perex logo

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.

Seriál: Doctrine 2 (12 dílů)

  1. Doctrine 2: úvod do systému 21.7.2010
  2. Doctrine 2: základní definice entit 4.8.2010
  3. Doctrine 2: pokročilá definice entit 11.8.2010
  4. Doctrine 2: načítání, ukládání a mazání 26.8.2010
  5. Doctrine 2:stavy entit a transakce 9.9.2010
  6. Doctrine 2: asociace 23.9.2010
  7. Doctrine 2: práce s asociacemi 14.10.2010
  8. Doctrine 2: DQL 3.11.2010
  9. Doctrine 2: Query Builder a nativní SQL 18.11.2010
  10. Doctrine 2: události 9.12.2010
  11. Doctrine 2: událostní handlery 13.1.2011
  12. Architektura aplikace nad Doctrine 2 23.2.2012

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.

Provozuje vývojářskou firmu Medio Interactive. Vystudoval informační a znalostní inženýrství na VŠE, kde stále příležitostně přednáší o tvorbě webů.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 11

Přehled komentářů

Robert1234 Chybný odkaz
Martin Malý Re: Chybný odkaz
Nox Perfekt
Ludek Vodicka ORM Designer
andrej Re: ORM Designer
drevolution Re: ORM Designer
Ondřej Mirtes Re: ORM Designer
andrej Re: ORM Designer
blizzy Proxy a metadata
drevolution Re: Proxy a metadata
drevolution Kešování metadat entit
Zdroj: https://www.zdrojak.cz/?p=3279