Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Doctrine 2 ORM and Zend Framework 2 tutorial

Marco Pivetta
February 14, 2013

Doctrine 2 ORM and Zend Framework 2 tutorial

A comprehensive guide to Doctrine 2 ORM combined the MVC of Zend Framework 2. This tutorial is for both newcomers to ZF2 and doctrine2 and for D2 veterans who are stepping into zend framework.

A webinar associated with this presentation can be found at http://ocramius.github.com/blog/doctrine-2-orm-zf2-tutorial/

The slides are also available as html at http://marco-pivetta.com/doctrine-orm-zf2-tutorial and you can clone them from https://github.com/Ocramius/doctrine-orm-zf2-tutorial

Marco Pivetta

February 14, 2013
Tweet

Other Decks in Programming

Transcript

  1. MAIN LIBRARIES , , , , , , , ,

    , , BjyAuthorize AssetManager ZeffMu ZfrRest OcraDiCompiler OcraServiceManager OcraCachedViewResolver DoctrineModule DoctrineORMModule DoctrineMongoODMModule VersionEyeModule
  2. WHAT IS DOCTRINE ORM? Doctrine ORM is an Object Relational

    Mapper It is inspired by Hibernate and the JPA (JSR-317) It is based on a DBAL (DataBase Abstraction Layer) Allows developers to save and load POPO with SQL
  3. An ORM gives you the impression that you are working

    with a "virtual" database (graph) composed by objects
  4. p h p c o m p o s e

    r . p h a r r e q u i r e d o c t r i n e / d o c t r i n e - o r m - m o d u l e : 0 . 7 . *
  5. p h p c o m p o s e

    r . p h a r r e q u i r e z e n d f r a m e w o r k / z e n d - d e v e l o p e r - t o o l s : d e v - m a s t e r
  6. c p v e n d o r / z

    e n d f r a m e w o r k / z e n d - d e v e l o p e r - t o o l s / c o n f i g / z e n d d e v e l o p e r t o o l s . l o c a l . p h p . d i s t c o n f i g / a u t o l o a d / z d t . l o c a l . p h p
  7. ENABLING THE MODULES c o n f i g /

    a p p l i c a t i o n . c o n f i g . p h p r e t u r n a r r a y ( ' m o d u l e s ' = > a r r a y ( ' Z e n d D e v e l o p e r T o o l s ' , ' D o c t r i n e M o d u l e ' , ' D o c t r i n e O R M M o d u l e ' , ' A p p l i c a t i o n ' , ) , / / [ . . . ] ) ;
  8. WRITE YOUR FIRST ENTITY m o d u l e

    / A p p l i c a t i o n / s r c / A p p l i c a t i o n / E n t i t y / U s e r n a m e s p a c e A p p l i c a t i o n \ E n t i t y ; u s e D o c t r i n e \ O R M \ M a p p i n g a s O R M ; / * * @ O R M \ E n t i t y * / c l a s s U s e r { / * * * @ O R M \ I d * @ O R M \ G e n e r a t e d V a l u e ( s t r a t e g y = " A U T O " ) * @ O R M \ C o l u m n ( t y p e = " i n t e g e r " ) * / p r o t e c t e d $ i d ; / * * @ O R M \ C o l u m n ( t y p e = " s t r i n g " ) * / p r o t e c t e d $ f u l l N a m e ; / / g e t t e r s / s e t t e r s }
  9. CONFIGURE MAPPINGS m o d u l e / A

    p p l i c a t i o n / c o n f i g / m o d u l e . c o n f i g . p h p r e t u r n a r r a y ( ' d o c t r i n e ' = > a r r a y ( ' d r i v e r ' = > a r r a y ( ' a p p l i c a t i o n _ e n t i t i e s ' = > a r r a y ( ' c l a s s ' = > ' D o c t r i n e \ O R M \ M a p p i n g \ D r i v e r \ A n n o t a t i o n D r i v e r ' ' c a c h e ' = > ' a r r a y ' ' p a t h s ' = > a r r a y ( _ _ D I R _ _ . ' / . . / s r c / A p p l i c a t i o n / E n t i t y ' ) ) , ' o r m _ d e f a u l t ' = > a r r a y ( ' d r i v e r s ' = > a r r a y ( ' A p p l i c a t i o n \ E n t i t y ' = > ' a p p l i c a t i o n _ e n t i t i e s ' ) ) ) ) , / / [ . . . ]
  10. CONFIGURE THE CONNECTION c o n f i g /

    a u t o l o a d / d o c t r i n e . l o c a l . p h p r e t u r n a r r a y ( ' d o c t r i n e ' = > a r r a y ( ' c o n n e c t i o n ' = > a r r a y ( ' o r m _ d e f a u l t ' = > a r r a y ( ' d r i v e r C l a s s ' = > ' D o c t r i n e \ D B A L \ D r i v e r \ P D O M y S q l \ D r i v e r ' , ' p a r a m s ' = > a r r a y ( ' h o s t ' = > ' l o c a l h o s t ' , ' p o r t ' = > ' 3 3 0 6 ' , ' u s e r ' = > ' u s e r n a m e ' , ' p a s s w o r d ' = > ' p a s s w o r d ' , ' d b n a m e ' = > ' d a t a b a s e ' , ) ) ) ) ) ;
  11. VALIDATE MAPPINGS . / v e n d o r

    / b i n / d o c t r i n e - m o d u l e o r m : v a l i d a t e - s c h e m a
  12. . / v e n d o r / b

    i n / d o c t r i n e - m o d u l e o r m : s c h e m a - t o o l : c r e a t e
  13. TEST IT! m o d u l e / A

    p p l i c a t i o n / s r c / A p p l i c a t i o n / C o n t r o l l e r / I n d e x C o n t r o l l e r . p h p p u b l i c f u n c t i o n i n d e x A c t i o n ( ) { $ o b j e c t M a n a g e r = $ t h i s - > g e t S e r v i c e L o c a t o r ( ) - > g e t ( ' D o c t r i n e \ O R M \ E n t i t y M a n a g e r ' ) ; $ u s e r = n e w \ A p p l i c a t i o n \ E n t i t y \ U s e r ( ) ; $ u s e r - > s e t F u l l N a m e ( ' M a r c o P i v e t t a ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r ) ; $ o b j e c t M a n a g e r - > f l u s h ( ) ; d i e ( v a r _ d u m p ( $ u s e r - > g e t I d ( ) ) ) ; / / y e s , I ' m l a z y }
  14. PERSISTING AN OBJECT $ u s e r = n

    e w U s e r ( ) ; $ u s e r - > s e t F u l l N a m e ( ' M a r c o P i v e t t a ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r ) ; / / $ u s e r 1 i s n o w " m a n a g e d " $ o b j e c t M a n a g e r - > f l u s h ( ) ; / / c o m m i t c h a n g e s t o d b v a r _ d u m p ( $ u s e r 1 - > g e t I d ( ) ) ; / / 1
  15. PERSISTING MULTIPLE OBJECTS $ u s e r 1 =

    n e w U s e r ( ) ; $ u s e r 1 - > s e t F u l l N a m e ( ' M a r c o P i v e t t a ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r 1 ) ; $ u s e r 2 = n e w U s e r ( ) ; $ u s e r 2 - > s e t F u l l N a m e ( ' M i c h a ë l G a l l e g o ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r 2 ) ; $ u s e r 3 = n e w U s e r ( ) ; $ u s e r 3 - > s e t F u l l N a m e ( ' K y l e S p r a g g s ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r 3 ) ; $ o b j e c t M a n a g e r - > f l u s h ( ) ;
  16. RETRIEVING AN OBJECT $ u s e r 1 =

    $ o b j e c t M a n a g e r - > f i n d ( ' U s e r ' , 1 ) ; v a r _ d u m p ( $ u s e r 1 - > g e t F u l l N a m e ( ) ) ; / / M a r c o P i v e t t a $ u s e r 2 = $ o b j e c t M a n a g e r - > g e t R e p o s i t o r y ( ' U s e r ' ) - > f i n d O n e B y ( a r r a y ( ' f u l l N a m e ' = > ' M i c h a ë l G a l l e g o ' ) ) ; v a r _ d u m p ( $ u s e r 2 - > g e t F u l l N a m e ( ) ) ; / / M i c h a ë l G a l l e g o
  17. UPDATING AN OBJECT $ u s e r = $

    o b j e c t M a n a g e r - > f i n d ( ' U s e r ' , 1 ) ; $ u s e r - > s e t F u l l N a m e ( ' G u i l h e r m e B l a n c o ' ) ; $ o b j e c t M a n a g e r - > f l u s h ( ) ;
  18. DELETING AN OBJECT $ u s e r = $

    o b j e c t M a n a g e r - > f i n d ( ' U s e r ' , 1 ) ; $ o b j e c t M a n a g e r - > r e m o v e ( $ u s e r ) ; $ o b j e c t M a n a g e r - > f l u s h ( ) ;
  19. ASSOCIATIONS - USER / * * @ O R M

    \ E n t i t y * / c l a s s U s e r { / / l i k e b e f o r e / * * @ O R M \ M a n y T o O n e ( t a r g e t E n t i t y = " A d d r e s s " ) * / p r o t e c t e d $ a d d r e s s ; / * * @ O R M \ M a n y T o M a n y ( t a r g e t E n t i t y = " P r o j e c t " ) * / p r o t e c t e d $ p r o j e c t s ; p u b l i c f u n c t i o n _ _ c o n s t r u c t ( ) { $ t h i s - > p r o j e c t s = n e w A r r a y C o l l e c t i o n ( ) ; } / / g e t t e r s / s e t t e r s }
  20. ASSOCIATIONS - ADDRESS / * * @ O R M

    \ E n t i t y * / c l a s s A d d r e s s { / * @ O R M \ I d @ O R M \ C o l u m n ( t y p e = " i n t e g e r " ) @ O R M \ G e n e r a t e d V a l u e ( s t r a t e g y = " A U T O " ) * / p r o t e c t e d $ i d ; / * * @ O R M \ C o l u m n ( t y p e = " s t r i n g " ) * / p r o t e c t e d $ c i t y ; / * * @ O R M \ C o l u m n ( t y p e = " s t r i n g " ) * / p r o t e c t e d $ c o u n t r y ; / / g e t t e r s / s e t t e r s e t c . }
  21. ASSOCIATIONS - PROJECTS / * * @ O R M

    \ E n t i t y * / c l a s s P r o j e c t { / * @ O R M \ I d @ O R M \ C o l u m n ( t y p e = " i n t e g e r " ) @ O R M \ G e n e r a t e d V a l u e ( s t r a t e g y = " A U T O " ) * / p r o t e c t e d $ i d ; / * * @ O R M \ C o l u m n ( t y p e = " s t r i n g " ) * / p r o t e c t e d $ n a m e ; / / g e t t e r s / s e t t e r s }
  22. ASSOCIATIONS - PERSISTING ASSOCIATIONS $ u s e r =

    n e w U s e r ( ) ; $ u s e r - > s e t F u l l N a m e ( ' M a r c o P i v e t t a ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ u s e r ) ; $ a d d r e s s = n e w A d d r e s s ( ) ; $ a d d r e s s - > s e t C i t y ( ' F r a n k f u r t ' ) $ a d d r e s s - > s e t C o u n t r y ( ' G e r m a n y ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ a d d r e s s ) ; $ p r o j e c t = n e w P r o j e c t ( ) ; $ p r o j e c t - > s e t N a m e ( ' D o c t r i n e O R M ' ) ; $ o b j e c t M a n a g e r - > p e r s i s t ( $ p r o j e c t ) ; $ u s e r - > s e t A d d r e s s ( $ a d d r e s s ) ; $ u s e r - > g e t P r o j e c t s ( ) - > a d d ( $ p r o j e c t ) ; $ o b j e c t M a n a g e r - > f l u s h ( ) ;
  23. ASSOCIATIONS - RETRIEVING ASSOCIATIONS $ u s e r =

    $ o b j e c t M a n a g e r - > f i n d ( ' U s e r ' , 1 ) ; v a r _ d u m p ( $ u s e r - > g e t A d d r e s s ( ) - > g e t C i t y ( ) ) ; / / F r a n k f u r t v a r _ d u m p ( $ u s e r - > g e t P r o j e c t s ( ) - > f i r s t ( ) - > g e t N a m e ( ) ) / / D o c t r i n e O R M
  24. PAGINATOR ADAPTER u s e D o c t r

    i n e \ C o m m o n \ C o l l e c t i o n s \ A r r a y C o l l e c t i o n ; u s e D o c t r i n e M o d u l e \ P a g i n a t o r \ A d a p t e r \ C o l l e c t i o n a s A d a p t e r ; u s e Z e n d \ P a g i n a t o r \ P a g i n a t o r ; / / C r e a t e a D o c t r i n e C o l l e c t i o n $ c o l l e c t i o n = n e w A r r a y C o l l e c t i o n ( r a n g e ( 1 , 1 0 1 ) ) ; / / C r e a t e t h e p a g i n a t o r i t s e l f $ p a g i n a t o r = n e w P a g i n a t o r ( n e w A d a p t e r ( $ c o l l e c t i o n ) ) ; $ p a g i n a t o r - > s e t C u r r e n t P a g e N u m b e r ( 1 ) - > s e t I t e m C o u n t P e r P a g e ( 5 ) ;
  25. PAGINATOR ADAPTER (ORM) u s e D o c t

    r i n e O R M M o d u l e \ P a g i n a t o r \ A d a p t e r \ D o c t r i n e P a g i n a t o r ; u s e D o c t r i n e \ O R M \ T o o l s \ P a g i n a t i o n \ P a g i n a t o r a s O R M P a g i n a t o r ; u s e Z e n d \ P a g i n a t o r \ P a g i n a t o r ; / / C r e a t e a D o c t r i n e C o l l e c t i o n $ q u e r y = $ e m - > c r e a t e Q u e r y ( ' S E L E C T f F R O M F o o f J O I N f . b a r b ' ) ; / / C r e a t e t h e p a g i n a t o r i t s e l f $ p a g i n a t o r = n e w P a g i n a t o r ( n e w D o c t r i n e P a g i n a t o r ( n e w O R M P a g i n a t o r ( $ q u e r y ) ) ) ; $ p a g i n a t o r - > s e t C u r r e n t P a g e N u m b e r ( 1 ) - > s e t I t e m C o u n t P e r P a g e ( 5 ) ;
  26. OBJECT-EXISTS VALIDATOR $ r e p o s i t

    o r y = $ o b j e c t M a n a g e r - > g e t R e p o s i t o r y ( ' A p p l i c a t i o n \ E n t i t y \ U s e r ' ) ; $ v a l i d a t o r = n e w \ D o c t r i n e M o d u l e \ V a l i d a t o r \ O b j e c t E x i s t s ( a r r a y ( ' o b j e c t _ r e p o s i t o r y ' = > $ r e p o s i t o r y , ' f i e l d s ' = > a r r a y ( ' e m a i l ' ) ) ) ; v a r _ d u m p ( $ v a l i d a t o r - > i s V a l i d ( ' t e s t @ e x a m p l e . c o m ' ) ) ; v a r _ d u m p ( $ v a l i d a t o r - > i s V a l i d ( a r r a y ( ' e m a i l ' = > ' t e s t @ e x a m p l e . c o m ' ) ) ) ;
  27. CACHE ADAPTERS $ z e n d C a c

    h e = n e w \ Z e n d \ C a c h e \ S t o r a g e \ A d a p t e r \ M e m o r y ( ) ; $ c a c h e = n e w \ D o c t r i n e M o d u l e \ C a c h e \ Z e n d S t o r a g e C a c h e ( $ z e n d C a c h e ) ; $ d o c t r i n e C a c h e = n e w \ D o c t r i n e \ C o m m o n \ C a c h e \ A r r a y C a c h e ( ) ; $ o p t i o n s = n e w \ Z e n d \ C a c h e \ S t o r a g e \ A d a p t e r \ A d a p t e r O p t i o n s ( ) ; $ c a c h e = n e w \ D o c t r i n e M o d u l e \ C a c h e \ D o c t r i n e C a c h e S t o r a g e ( $ o p t i o n s , $ d o c t r i n e C a c h e ) ;
  28. HYDRATOR u s e D o c t r i

    n e M o d u l e \ S t d l i b \ H y d r a t o r \ D o c t r i n e O b j e c t ; $ h y d r a t o r = n e w D o c t r i n e O b j e c t ( $ o b j e c t M a n a g e r , ' A p p l i c a t i o n \ E n t i t y \ C i t y ' ) ; $ c i t y = n e w C i t y ( ) ; $ d a t a = a r r a y ( ' n a m e ' = > ' F r a n k f u r t ' ) ; $ c i t y = $ h y d r a t o r - > h y d r a t e ( $ d a t a , $ c i t y ) ; e c h o $ c i t y - > g e t N a m e ( ) ; / / p r i n t s " F r a n k f u r t " $ d a t a A r r a y = $ h y d r a t o r - > e x t r a c t ( $ c i t y ) ; e c h o $ d a t a A r r a y [ ' n a m e ' ] ; / / p r i n t s " F r a n k f u r t "
  29. HYDRATOR (2) u s e D o c t r

    i n e M o d u l e \ S t d l i b \ H y d r a t o r \ D o c t r i n e O b j e c t ; $ h y d r a t o r = n e w D o c t r i n e O b j e c t ( $ o b j e c t M a n a g e r , ' A p p l i c a t i o n \ E n t i t y \ C i t y ' ) ; $ c i t y = n e w C i t y ( ) ; $ d a t a = a r r a y ( ' c o u n t r y ' = > 1 2 3 ) ; $ c i t y = $ h y d r a t o r - > h y d r a t e ( $ d a t a , $ c i t y ) ; v a r _ d u m p ( $ c i t y - > g e t C o u n t r y ( ) ) ; / / p r i n t s c l a s s C o u n t r y # 1 ( 1 ) { / / p r o t e c t e d $ n a m e = > s t r i n g ( 5 ) " G e r m a n y " / / }
  30. FORM ELEMENT $ f o r m - > a

    d d ( a r r a y ( ' t y p e ' = > ' D o c t r i n e M o d u l e \ F o r m \ E l e m e n t \ O b j e c t S e l e c t ' , ' n a m e ' = > ' u s e r ' , ' o p t i o n s ' = > a r r a y ( ' o b j e c t _ m a n a g e r ' = > $ o b j e c t M a n a g e r , ' t a r g e t _ c l a s s ' = > ' M o d u l e \ E n t i t y \ U s e r ' , ' p r o p e r t y ' = > ' f u l l N a m e ' , ' i s _ m e t h o d ' = > t r u e , ' f i n d _ m e t h o d ' = > a r r a y ( ' n a m e ' = > ' f i n d B y ' , ' p a r a m s ' = > a r r a y ( ' c r i t e r i a ' = > a r r a y ( ' a c t i v e ' = > 1 ) , ' o r d e r B y ' = > a r r a y ( ' l a s t N a m e ' = > ' A S C ' ) , ) , ) , ) , ) ) ;
  31. KEEP ENTITIES SIMPLE Think of entities as value-objects Don't add

    logic to entities (hard to change later!) Keep entities aware only of themselves + relations
  32. USE DOCTRINE/COMMON API If you stick with using only doctrine/common

    API, users of your modules can switch between ORM/ MongoDB ODM/CouchDB ODM/ PHPCR ODM/OrientDB ODM
  33. USE DOCTRINE/COMMON API Prefer over D o c t r

    i n e \ C o m m o n \ P e r s i s t e n c e \ O b j e c t M a n a g e r D o c t r i n e \ O R M \ E n t i t y M a n a g e r
  34. USE DOCTRINE/COMMON API Prefer over D o c t r

    i n e \ C o m m o n \ P e r s i s t e n c e \ O b j e c t R e p o s i t o r y D o c t r i n e \ O R M \ E n t i t y R e p o s i t o r y
  35. USE THE CRITERIA API Collections provide a Criteria Allows you

    to filter virtually any kind of data structure API
  36. CRITERIA API EXAMPLE u s e D o c t

    r i n e \ C o m m o n \ C o l l e c t i o n s \ C r i t e r i a ; u s e D o c t r i n e \ C o m m o n \ C o l l e c t i o n s \ A r r a y C o l l e c t i o n ; $ c o l l e c t i o n = n e w A r r a y C o l l e c t i o n ( a r r a y ( $ u s e r 1 , $ u s e r 2 , $ u s e r 3 ) ) ; $ c r i t e r i a = n e w C r i t e r i a ( ) ; $ c r i t e r i a - > a n d W h e r e ( $ c r i t e r i a - > e x p r ( ) - > g t ( ' l a s t L o g i n ' , n e w \ D a t e T i m e ( ' - 1 d a y ' ) ) ) ; $ r e c e n t V i s i t o r s = $ c o l l e c t i o n - > m a t c h i n g ( $ c r i t e r i a ) ; $ r e c e n t V i s i t o r s = $ e m - > g e t R e p o s i t o r y ( ' A p p l i c a t i o n \ E n t i t y \ U s e r s ' ) - > m a t c h i n g ( $ c r i t e r i a ) ;
  37. CRITERIA API ADVANTAGES Works in ORM Repositories, Collections, etc... Abstracts

    the problem of "searching" Same criteria for different storages (ORM, ODM, Memory, ElasticSearch, cache...) Allows you to define your own R e c e n t U s e r s C r i t e r i a or I n a c t i v e U s e r s C r i t e r i a ...
  38. INJECT THE OBJECT MANAGER If you fetch the entity manager

    from within your services, replacing it will become very hard: Inject it instead!
  39. INJECT THE OBJECT MANAGER ' f a c t o

    r i e s ' = > a r r a y ( ' m y _ s e r v i c e ' = > f u n c t i o n ( $ s l ) { $ o b j e c t M a n a g e r = $ s l - > g e t ( ' D o c t r i n e \ O R M \ E n t i t y M a n a g e r ' ) ; r e t u r n n e w M y S e r v i c e ( $ o b j e c t M a n a g e r ) ; } ) , c l a s s M y S e r v i c e { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( O b j e c t M a n a g e r $ o b j e c t M a n a g e r ) { / / [ . . . ] } }
  40. DON'T USE PERSISTENCE TO SOLVE APPLICATION PROBLEMS Filtering data when

    saved to DB Validating data when saved to DB Saving files when records are saved to DB Using DB-level errors to check input validity
  41. KEEP YOUR OBJECT GRAPH CONSISTENT An ObjectManager works under the

    assumption that managed objects are valid! Assign values to your entities only when data is valid!
  42. FORK IT! You can find these slides on GitHub at

    https://github.com/Ocramius/doctrine-orm-zf2- tutorial