$30 off During Our Annual Pro Sale. View Details »

Doctrine, Object Persistence, and You

Doctrine, Object Persistence, and You

Presented May 9, 2014 at OpenWest: https://joind.in/talk/view/11190

Presented March 16, 2014 at Midwest PHP: http://joind.in/talk/view/10561

Presented February 8, 2014 at Sunshine PHP: http://joind.in/talk/view/10530

Presented January 17, 2014 at Ski PHP: http://joind.in/talk/view/10427

Presented October 9, 2013 at ZendCon: https://joind.in/talk/view/9085

Reveal.js presentation published at: http://jmikola.github.io/slides/doctrine_object_persistence/

Jeremy Mikola

May 09, 2014
Tweet

More Decks by Jeremy Mikola

Other Decks in Programming

Transcript

  1. DOCTRINE,
    OBJECT PERSISTENCE,
    AND YOU
    Jeremy Mikola
    jmikola

    View Slide

  2. Agenda
    Design Patterns
    Object Persistence
    Behind the Persistence

    View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. PEAR DB Metabase
    PEAR MDB
    PEAR MDB2 Zend_Db
    Doctrine ORM 1.x
    Doctrine ORM 2.x Doctrine DBAL

    View Slide

  7. Design Patterns

    View Slide

  8. View Slide

  9. Who needs design patterns?

    View Slide

  10. Selecting Data from a Table
    $
    c
    o
    n
    =
    m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    (
    "
    e
    x
    a
    m
    p
    l
    e
    .
    c
    o
    m
    "
    ,
    "
    p
    e
    t
    e
    r
    "
    ,
    "
    a
    b
    c
    1
    2
    3
    "
    ,
    "
    m
    y
    _
    d
    b
    "
    )
    ;
    i
    f (
    m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    _
    e
    r
    r
    n
    o
    (
    )
    ) {
    e
    c
    h
    o "
    F
    a
    i
    l
    e
    d t
    o c
    o
    n
    n
    e
    c
    t t
    o M
    y
    S
    Q
    L
    : " . m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    _
    e
    r
    r
    o
    r
    (
    )
    ;
    }
    $
    r
    e
    s
    u
    l
    t = m
    y
    s
    q
    l
    i
    _
    q
    u
    e
    r
    y
    (
    $
    c
    o
    n
    ,
    "
    S
    E
    L
    E
    C
    T * F
    R
    O
    M P
    e
    r
    s
    o
    n
    s
    "
    )
    ;
    w
    h
    i
    l
    e
    (
    $
    r
    o
    w = m
    y
    s
    q
    l
    i
    _
    f
    e
    t
    c
    h
    _
    a
    r
    r
    a
    y
    (
    $
    r
    e
    s
    u
    l
    t
    )
    ) {
    e
    c
    h
    o $
    r
    o
    w
    [
    '
    F
    i
    r
    s
    t
    N
    a
    m
    e
    '
    ] . " " . $
    r
    o
    w
    [
    '
    L
    a
    s
    t
    N
    a
    m
    e
    '
    ]
    ;
    e
    c
    h
    o "
    <
    b
    r
    >
    "
    ;
    }
    m
    y
    s
    q
    l
    i
    _
    c
    l
    o
    s
    e
    (
    $
    c
    o
    n
    )
    ;
    http://www.w3schools.com/php/php_mysql_select.asp

    View Slide

  11. Inserting Form Data into a Database
    $
    c
    o
    n
    =
    m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    (
    "
    e
    x
    a
    m
    p
    l
    e
    .
    c
    o
    m
    "
    ,
    "
    p
    e
    t
    e
    r
    "
    ,
    "
    a
    b
    c
    1
    2
    3
    "
    ,
    "
    m
    y
    _
    d
    b
    "
    )
    ;
    i
    f (
    m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    _
    e
    r
    r
    n
    o
    (
    )
    ) {
    e
    c
    h
    o "
    F
    a
    i
    l
    e
    d t
    o c
    o
    n
    n
    e
    c
    t t
    o M
    y
    S
    Q
    L
    : " . m
    y
    s
    q
    l
    i
    _
    c
    o
    n
    n
    e
    c
    t
    _
    e
    r
    r
    o
    r
    (
    )
    ;
    }
    $
    s
    q
    l
    =
    "
    I
    N
    S
    E
    R
    T I
    N
    T
    O P
    e
    r
    s
    o
    n
    s (
    F
    i
    r
    s
    t
    N
    a
    m
    e
    , L
    a
    s
    t
    N
    a
    m
    e
    , A
    g
    e
    ) V
    A
    L
    U
    E
    S
    (
    '
    $
    _
    P
    O
    S
    T
    [
    f
    i
    r
    s
    t
    n
    a
    m
    e
    ]
    '
    ,
    '
    $
    _
    P
    O
    S
    T
    [
    l
    a
    s
    t
    n
    a
    m
    e
    ]
    '
    ,
    '
    $
    _
    P
    O
    S
    T
    [
    a
    g
    e
    ]
    '
    )
    "
    ;
    i
    f (
    !
    m
    y
    s
    q
    l
    i
    _
    q
    u
    e
    r
    y
    (
    $
    c
    o
    n
    ,
    $
    s
    q
    l
    )
    ) {
    d
    i
    e
    (
    '
    E
    r
    r
    o
    r
    : ' . m
    y
    s
    q
    l
    i
    _
    e
    r
    r
    o
    r
    (
    $
    c
    o
    n
    )
    )
    ;
    }
    m
    y
    s
    q
    l
    i
    _
    c
    l
    o
    s
    e
    (
    $
    c
    o
    n
    )
    ;
    http://www.w3schools.com/php/php_mysql_insert.asp

    View Slide

  12. View Slide

  13. Data Source Architectural Patterns
    Table data gateway
    Row data gateway
    Active record
    Data mapper

    View Slide

  14. Gateway Patterns

    View Slide

  15. An object that encapsulates access to an
    external system or resource.

    — Martin Fowler in PoEAA

    View Slide

  16. Table Data Gateway
    e.g. Zend\Db\TableGateway

    View Slide

  17. An object that acts as a Gateway to a
    database table. One instance handles all the
    rows in the table.

    — Martin Fowler in PoEAA

    View Slide

  18. Table Data Gateway

    View Slide

  19. What this looks like in PHP
    n
    a
    m
    e
    s
    p
    a
    c
    e Z
    e
    n
    d
    \
    D
    b
    \
    T
    a
    b
    l
    e
    G
    a
    t
    e
    w
    a
    y
    ;
    i
    n
    t
    e
    r
    f
    a
    c
    e T
    a
    b
    l
    e
    G
    a
    t
    e
    w
    a
    y
    I
    n
    t
    e
    r
    f
    a
    c
    e
    {
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    T
    a
    b
    l
    e
    (
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    e
    l
    e
    c
    t
    (
    $
    w
    h
    e
    r
    e = n
    u
    l
    l
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n i
    n
    s
    e
    r
    t
    (
    $
    s
    e
    t
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n u
    p
    d
    a
    t
    e
    (
    $
    s
    e
    t
    , $
    w
    h
    e
    r
    e = n
    u
    l
    l
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n d
    e
    l
    e
    t
    e
    (
    $
    w
    h
    e
    r
    e
    )
    ;
    }

    View Slide

  20. Row Data Gateway
    e.g. Zend\Db\RowGateway

    View Slide

  21. Row Data Gateway

    View Slide

  22. What’s the problem?
    Gateways are thin abstractions
    Data model not included
    Hydration and persistence?

    View Slide

  23. Active Record
    e.g. Doctrine ORM 1.x

    View Slide

  24. View Slide

  25. An object that wraps a row in a database
    table or view, encapsulates the database
    access, and adds domain logic on that data.

    — Martin Fowler in PoEAA

    View Slide

  26. Active Record

    View Slide

  27. Active Record
    Sits on top of our domain model
    Row data gateway + business logic

    View Slide

  28. Domain Model
    Data encapsulation
    Business logic
    Relationships
    Validation?

    View Slide

  29. Active Record adds…
    Factory method for new objects
    Hydration for fetched objects
    Persistence logic
    Common queries
    CRUD methods

    View Slide

  30. What this looks like in PHP
    /
    / c
    r
    e
    a
    t
    e T
    i
    t
    o
    $
    u
    s
    e
    r = U
    s
    e
    r
    :
    :
    c
    r
    e
    a
    t
    e
    (
    [
    '
    n
    a
    m
    e
    ' =
    > '
    T
    i
    t
    o
    '
    , '
    s
    t
    a
    t
    e
    ' =
    > '
    V
    A
    '
    ]
    )
    ;
    /
    / r
    e
    a
    d T
    i
    t
    o
    $
    u
    s
    e
    r = U
    s
    e
    r
    :
    :
    f
    i
    n
    d
    _
    b
    y
    _
    n
    a
    m
    e
    (
    '
    T
    i
    t
    o
    '
    )
    ;
    /
    / u
    p
    d
    a
    t
    e T
    i
    t
    o
    $
    u
    s
    e
    r
    -
    >
    n
    a
    m
    e = '
    T
    i
    t
    o J
    r
    '
    ;
    $
    u
    s
    e
    r
    -
    >
    s
    a
    v
    e
    (
    )
    ;
    /
    / d
    e
    l
    e
    t
    e T
    i
    t
    o
    $
    u
    s
    e
    r
    -
    >
    d
    e
    l
    e
    t
    e
    (
    )
    ;
    http://phpactiverecord.org/projects/main/wiki/Quick_Start

    View Slide

  31. What’s the problem?
    Testability
    Single Responsibility Principle

    View Slide

  32. ONE DOES NOT SIMPLY
    MOCK OUT ACTIVERECORD

    View Slide

  33. What’s the problem?
    Testability
    Scalability and performance
    Single Responsibility Principle
    Multitenancy

    View Slide

  34. Scalability and Performance
    Fat models eat memory

    View Slide

  35. An Elephant Never Forgets

    View Slide

  36. Data Mapper
    e.g. Doctrine ORM 2.x, ODMs

    View Slide

  37. A layer of Mappers that moves data between
    objects and a database while keeping them
    independent of each other and the mapper
    itself.

    — Martin Fowler in PoEAA

    View Slide

  38. Data Mapper

    View Slide

  39. Data Mapper
    Complements the domain model,
    instead of augmenting it
    Manages hydration and persistence

    View Slide

  40. The Data Mapper is a layer of software that
    separates the in-memory objects from the
    database.

    — Martin Fowler in PoEAA

    View Slide

  41. ☑ Separation of concerns

    View Slide

  42. With Data Mapper the in-memory objects
    needn’t know even that there’s a database
    present.

    — Martin Fowler in PoEAA

    View Slide

  43. ☑ Testability

    View Slide

  44. View Slide

  45. View Slide

  46. What this looks like in PHP
    /
    / c
    r
    e
    a
    t
    e J
    o
    n
    $
    u
    s
    e
    r = n
    e
    w U
    s
    e
    r
    (
    )
    ;
    $
    u
    s
    e
    r
    -
    >
    s
    e
    t
    N
    a
    m
    e
    (
    '
    J
    o
    n
    '
    )
    ;
    $
    u
    s
    e
    r
    -
    >
    s
    e
    t
    S
    t
    a
    t
    e
    (
    '
    T
    N
    '
    )
    ;
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    p
    e
    r
    s
    i
    s
    t
    (
    $
    u
    s
    e
    r
    )
    ;
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    f
    l
    u
    s
    h
    (
    )
    ;
    /
    / r
    e
    a
    d J
    o
    n
    $
    u
    s
    e
    r = $
    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
    (
    [
    '
    n
    a
    m
    e
    ' =
    > '
    J
    o
    n
    '
    ]
    )
    ;
    /
    / u
    p
    d
    a
    t
    e J
    o
    n
    $
    u
    s
    e
    r
    -
    >
    s
    e
    t
    N
    a
    m
    e
    (
    '
    J
    o
    n W
    a
    g
    e
    '
    )
    ;
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    f
    l
    u
    s
    h
    (
    )
    ;
    /
    / d
    e
    l
    e
    t
    e J
    o
    n
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    r
    e
    m
    o
    v
    e
    (
    $
    u
    s
    e
    r
    )
    ;
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    f
    l
    u
    s
    h
    (
    )
    ;
    http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html

    View Slide

  47. Data Mapper
    Simple models
    Manager handles persistence
    Repository holds queries

    View Slide

  48. ☑ Multitenancy

    View Slide

  49. ☑ Scalability and performance

    View Slide

  50. Object Persistence
    in Doctrine ORM 2.x, ODMs
    Inspired by and
    Hibernate JPA 2.0

    View Slide

  51. Architecture
    EventManager
    Metadata
    Hydrator Persister
    UnitOfWork
    ObjectManager
    Repository Query

    View Slide

  52. Metadata
    /
    *
    *
    * @
    E
    n
    t
    i
    t
    y
    * @
    T
    a
    b
    l
    e
    (
    n
    a
    m
    e
    =
    "
    p
    r
    o
    d
    u
    c
    t
    s
    "
    )
    *
    /
    c
    l
    a
    s
    s P
    r
    o
    d
    u
    c
    t
    {
    /
    *
    *
    * @
    I
    d
    * @
    C
    o
    l
    u
    m
    n
    (
    t
    y
    p
    e
    =
    "
    i
    n
    t
    e
    g
    e
    r
    "
    )
    * @
    G
    e
    n
    e
    r
    a
    t
    e
    d
    V
    a
    l
    u
    e
    *
    /
    p
    r
    o
    t
    e
    c
    t
    e
    d $
    i
    d
    ;
    /
    *
    * @
    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
    ;
    /
    / .
    .
    .
    }

    View Slide

  53. Hydrator

    View Slide

  54. Persister

    View Slide

  55. Unit of Work

    View Slide

  56. A Unit of Work keeps track of everything you
    do during a business transaction that can
    affect the database.

    — Martin Fowler in PoEAA

    View Slide

  57. When you’re done, it figures out everything
    that needs to be done to alter the database
    as a result of your work.

    — Martin Fowler in PoEAA

    View Slide

  58. Unit of Work:
    Object States
    New
    Managed
    Removed
    Detached

    View Slide

  59. What this looks like in PHP
    $
    u
    s
    e
    r = n
    e
    w U
    s
    e
    r
    (
    )
    ;
    $
    u
    s
    e
    r
    -
    >
    s
    e
    t
    N
    a
    m
    e
    (
    '
    J
    o
    n
    '
    )
    ; /
    / $
    u
    s
    e
    r i
    s N
    E
    W
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    p
    e
    r
    s
    i
    s
    t
    (
    $
    u
    s
    e
    r
    )
    ; /
    / $
    u
    s
    e
    r i
    s M
    A
    N
    A
    G
    E
    D
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    f
    l
    u
    s
    h
    (
    )
    ;
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    r
    e
    m
    o
    v
    e
    (
    $
    u
    s
    e
    r
    )
    ; /
    / $
    u
    s
    e
    r i
    s R
    E
    M
    O
    V
    E
    D
    $
    m
    a
    n
    a
    g
    e
    r
    -
    >
    f
    l
    u
    s
    h
    (
    )
    ;

    View Slide

  60. Unit of Work:
    Identity Map

    View Slide

  61. What this looks like in PHP
    $
    u
    s
    e
    r
    A = $
    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
    (
    [
    '
    i
    d
    ' =
    > 1
    ]
    )
    ;
    $
    u
    s
    e
    r
    B = $
    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
    (
    [
    '
    i
    d
    ' =
    > 1
    ]
    )
    ;
    $
    u
    s
    e
    r
    A =
    =
    = $
    u
    s
    e
    r
    B
    ; /
    / t
    r
    u
    e

    View Slide

  62. Doctrine\Common\Persistence\
    ObjectManager
    f
    i
    n
    d
    (
    $
    c
    l
    a
    s
    s
    , $
    i
    d
    )
    p
    e
    r
    s
    i
    s
    t
    (
    $
    o
    b
    j
    e
    c
    t
    )
    r
    e
    m
    o
    v
    e
    (
    $
    o
    b
    j
    e
    c
    t
    )
    f
    l
    u
    s
    h
    (
    )
    c
    l
    e
    a
    r
    (
    )
    d
    e
    t
    a
    c
    h
    (
    $
    o
    b
    j
    e
    c
    t
    )
    m
    e
    r
    g
    e
    (
    $
    o
    b
    j
    e
    c
    t
    )
    r
    e
    f
    r
    e
    s
    h
    (
    $
    o
    b
    j
    e
    c
    t
    )

    View Slide

  63. Lifecycle Events
    Remove
    Persist
    Update
    Load
    Flush
    Clear

    View Slide

  64. Event Notification

    View Slide

  65. Doctrine\Common\
    EventManager
    d
    i
    s
    p
    a
    t
    c
    h
    E
    v
    e
    n
    t
    (
    $
    e
    v
    e
    n
    t
    , $
    a
    r
    g
    s
    )
    g
    e
    t
    L
    i
    s
    t
    e
    n
    e
    r
    s
    (
    $
    e
    v
    e
    n
    t
    )
    h
    a
    s
    L
    i
    s
    t
    e
    n
    e
    r
    s
    (
    $
    e
    v
    e
    n
    t
    )
    a
    d
    d
    E
    v
    e
    n
    t
    L
    i
    s
    t
    e
    n
    e
    r
    (
    $
    e
    v
    e
    n
    t
    , $
    l
    i
    s
    t
    e
    n
    e
    r
    )
    r
    e
    m
    o
    v
    e
    E
    v
    e
    n
    t
    L
    i
    s
    t
    e
    n
    e
    r
    (
    $
    e
    v
    e
    n
    t
    , $
    l
    i
    s
    t
    e
    n
    e
    r
    )
    a
    d
    d
    E
    v
    e
    n
    t
    S
    u
    b
    s
    c
    r
    i
    b
    e
    r
    (
    $
    s
    u
    b
    s
    c
    r
    i
    b
    e
    r
    )
    r
    e
    m
    o
    v
    e
    E
    v
    e
    n
    t
    S
    u
    b
    s
    c
    r
    i
    b
    e
    r
    (
    $
    s
    u
    b
    s
    c
    r
    i
    b
    e
    r
    )

    View Slide

  66. Doctrine\Common\Persistence\
    ObjectRepository
    f
    i
    n
    d
    (
    $
    i
    d
    )
    f
    i
    n
    d
    A
    l
    l
    (
    )
    f
    i
    n
    d
    B
    y
    (
    $
    c
    r
    i
    t
    e
    r
    i
    a
    , …
    )
    f
    i
    n
    d
    O
    n
    e
    B
    y
    (
    $
    c
    r
    i
    t
    e
    r
    i
    a
    )
    g
    e
    t
    C
    l
    a
    s
    s
    N
    a
    m
    e
    (
    )

    View Slide

  67. Query
    Abstracts database query API
    Fluent builder interface
    Filter classes
    ORM/ODM behavior
    e.g. hydration, fetch mode

    View Slide

  68. What this looks like in PHP
    /
    / $
    q
    b i
    s a D
    o
    c
    t
    r
    i
    n
    e
    \
    O
    R
    M
    \
    Q
    u
    e
    r
    y
    B
    u
    i
    l
    d
    e
    r
    $
    q
    b
    -
    >
    s
    e
    l
    e
    c
    t
    (
    '
    u
    '
    )
    -
    >
    f
    r
    o
    m
    (
    '
    U
    s
    e
    r
    '
    , '
    u
    '
    )
    -
    >
    w
    h
    e
    r
    e
    (
    '
    u
    .
    n
    a
    m
    e = :
    n
    a
    m
    e O
    R u
    .
    n
    i
    c
    k
    n
    a
    m
    e = :
    n
    a
    m
    e
    '
    )
    -
    >
    o
    r
    d
    e
    r
    B
    y
    (
    '
    u
    .
    a
    g
    e
    '
    , '
    D
    E
    S
    C
    '
    )
    -
    >
    s
    e
    t
    P
    a
    r
    a
    m
    e
    t
    e
    r
    s
    (
    [
    '
    n
    a
    m
    e
    ' =
    > '
    J
    o
    n
    '
    ]
    )
    -
    >
    g
    e
    t
    Q
    u
    e
    r
    y
    (
    )
    -
    >
    g
    e
    t
    R
    e
    s
    u
    l
    t
    (
    )

    View Slide

  69. What this looks like in PHP
    /
    / $
    q
    b i
    s a D
    o
    c
    t
    r
    i
    n
    e
    \
    O
    R
    M
    \
    Q
    u
    e
    r
    y
    B
    u
    i
    l
    d
    e
    r
    $
    q
    b
    -
    >
    s
    e
    l
    e
    c
    t
    (
    '
    u
    '
    )
    -
    >
    f
    r
    o
    m
    (
    '
    U
    s
    e
    r
    '
    , '
    u
    '
    )
    -
    >
    w
    h
    e
    r
    e
    (
    $
    q
    b
    -
    >
    e
    x
    p
    r
    (
    )
    -
    >
    o
    r
    X
    (
    $
    q
    b
    -
    >
    e
    x
    p
    r
    (
    )
    -
    >
    e
    q
    (
    '
    u
    .
    n
    a
    m
    e
    '
    , '
    :
    n
    a
    m
    e
    '
    )
    ,
    $
    q
    b
    -
    >
    e
    x
    p
    r
    (
    )
    -
    >
    l
    i
    k
    e
    (
    '
    u
    .
    n
    i
    c
    k
    n
    a
    m
    e
    '
    , '
    :
    n
    a
    m
    e
    '
    )
    )
    )
    -
    >
    o
    r
    d
    e
    r
    B
    y
    (
    '
    u
    .
    a
    g
    e
    '
    , '
    D
    E
    S
    C
    '
    )
    -
    >
    s
    e
    t
    P
    a
    r
    a
    m
    e
    t
    e
    r
    s
    (
    [
    '
    n
    a
    m
    e
    ' =
    > '
    J
    o
    n
    '
    ]
    )
    -
    >
    g
    e
    t
    Q
    u
    e
    r
    y
    (
    )
    -
    >
    g
    e
    t
    R
    e
    s
    u
    l
    t
    (
    )
    ;

    View Slide

  70. View Slide

  71. View Slide

  72. Performance and Tunability
    Caching results, queries, etc.
    Change tracking policies
    Proxy objects, fetch modes
    Code generation

    View Slide

  73. Behind the Persistence

    View Slide

  74. Packages
    Cache Annotations Lexer
    Collections Inflector
    Common
    DBAL
    MongoDB CouchDB
    ORM
    MongoDB ODM CouchDB ODM
    PHPCR ODM

    View Slide

  75. packagist.org/packages/doctrine/

    View Slide

  76. Doctrine\Common\
    Cache
    Supports over a dozen backends
    Namespaces and versioning
    Very simple API

    View Slide

  77. Doctrine\Common\
    Annotations
    DocBlock annotation parsing
    Utilizes the lexer component
    Cache integration

    View Slide

  78. Doctrine\Common\
    Collections
    Object-oriented collection interface
    ArrayCollection implementation
    ORM/ODM persistent collections
    Java-inspired Criteria API

    View Slide

  79. Doctrine\
    DBAL
    Thin layer atop PDO
    SQL database abstraction
    Type mapping
    Query builder

    View Slide

  80. Doctrine\
    MongoDB
    MongoDB driver abstraction
    Error handling, recovery
    Syntactic sugar
    Query builder

    View Slide

  81. But wait, there’s more!
    CouchDB client and ODM
    PHP Content Repository ODM
    OrientDB ODM
    Database migrations

    View Slide

  82. Wrapping Up

    View Slide

  83. Essentially the ORM can handle about 80-
    90% of the mapping problems, but that last
    chunk always needs careful work by
    somebody who really understands how a
    relational database works.

    — Martin Fowler in OrmHate

    View Slide

  84. Pertinent Resources
    http://github.com/doctrine
    http://doctrine-project.org/
    http://doctrine-project.org/jira

    View Slide

  85. Freenode IRC
    #doctrine
    #doctrine-dev

    View Slide

  86. THANKS!
    Questions?

    View Slide

  87. Image Credits
    by
    http://xkcd.com/327/
    http://hqwallbase.com/images/big/Trees-Wallpaper-3008x2000.jpg
    http://www.angryarchitect.com/wp-content/uploads/2010/04/FowlerFront.jpg
    https://raw.github.com/paulirish/w3fools/master/images/pity.jpg
    http://b-i.forbesimg.com/danschawbel/files/2013/03/david.heinemeier.hansson.jpg
    http://icons8.com http://www.visualpharm.com/

    View Slide