Doctrine ORM Documentation

repository·3.6.x·Indexed 27 days ago

https://github.com/doctrine/orm

An object-relational mapper for PHP 8.1+ that enables transparent persistence of PHP objects. Built on top of the Doctrine Database Abstraction Layer (DBAL), it features the Doctrine Query Language (DQL) for object-oriented querying. The documentation covers custom mapping types, aggregate field implementation, locking strategies (optimistic and pessimistic), and advanced patterns such as Single Table Inheritance for the Decorator pattern.

Tokens
116.3K
Snippets
289
Records
524
Agent score
94%

What's inside Doctrine ORM

  1. Overview of Doctrine ORM

    3.6.x

    Doctrine ORM is an object-relational mapper for PHP 8.1+ that provides transparent persistence for PHP objects. It is built on top of the Doctrine Database Abstraction Layer (DBAL).

    A key feature is Doctrine Query Language (DQL), a proprietary object-oriented SQL dialect inspired by Hibernate's HQL. DQL allows developers to write queries against the object model rather than the database schema, providing flexibility and reducing code duplication.

  2. Understand Doctrine Query Language (DQL) fundamentals

    3.6.x

    DQL (Doctrine Query Language) is an object-oriented query language used to query your domain model rather than your relational database schema.

    Key concepts:

    • Query the Object Model: Instead of using table and column names (SQL), use your entity class names and their field names.
    • Case Sensitivity: DQL is case-insensitive, except for namespaces, class names, and field names, which must match your entity definitions exactly.
    • Supported Operations: DQL supports SELECT, UPDATE, and DELETE constructs.
    • No INSERT statements: You cannot use INSERT in DQL. To add new data, you must use EntityManager#persist() to ensure the object model and persistence context remain consistent.
  3. License for Doctrine ORM Documentation

    3.6.x

    The Doctrine ORM documentation is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) license.

    Under this license, you are free to:

    • Reproduce the work.
    • Create Adaptations (e.g., translations or modifications).
    • Distribute and Publicly Perform the work or its adaptations.

    However, you must comply with the following restrictions:

    • Attribution: You must give appropriate credit, provide a link to the license, and indicate if changes were made.
    • NonCommercial: You may not use the material for commercial advantage or private monetary compensation.
    • ShareAlike: If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
    • No additional restrictions: You may not apply legal terms or technological measures that restrict others from exercising the rights granted by this license.
  4. Use PHP Attributes for Doctrine ORM mapping

    3.6.x
    As of version 2.9, Doctrine ORM supports using native PHP 8 Attributes for metadata mapping. This replaces the older annotation-based metadata system. The attribute implementation is modeled after the previous annotation system, allowing you to define entities, associations, and column mappings directly within your PHP classes using native syntax.
  5. Understand the Unit of Work and EntityManager lifecycle

    3.6.x

    The EntityManager manages a UnitOfWork, which acts as an object-level transaction. A new UnitOfWork starts when an EntityManager is created or after EntityManager#flush() is called.

    Key behaviors:

    • Write Operations: Only EntityManager#flush() executes write operations against the database. Methods like EntityManager#persist($entity) or EntityManager#remove($entity) only notify the UnitOfWork of intended changes.
    • Committing Changes: Invoking EntityManager#flush() commits the current UnitOfWork and starts a new one.
    • Closing the Manager: Calling EntityManager#close() manually closes the UnitOfWork. Any unpersisted changes in that UnitOfWork will be lost.
    • Reflection: Doctrine uses reflection to access entity data and does not rely on public API methods (getters/setters) or constructors. Code inside your getters/setters may not be executed during database synchronization.
  6. Extend DQL using Custom Tree Walkers

    3.6.x

    You can modify the Doctrine Query Language (DQL) parsing process by hooking into the Abstract Syntax Tree (AST) using Custom Tree Walkers. There are two types of walkers:

    1. Output Walker: Responsible for generating the actual SQL. There is only one output walker per query (the default is SqlWalker). Use this to introduce vendor-specific SQL keywords or to modify the final SQL string (e.g., for debugging or interpolation).
    2. Tree Walker: Can be multiple per query. They cannot generate SQL themselves but can modify the AST nodes before the output walker renders them to SQL. Use this to transform the query structure, such as converting a complex SELECT query into a COUNT query for pagination.

    To register a walker, use the Query::setHint() method with the appropriate constant.

  7. Understand Doctrine ORM Package Dependencies

    3.6.x

    Doctrine ORM is composed of several decoupled packages. The ORM package depends on DBAL, Persistence, and Collections.

    • ORM (Doctrine\ORM): The object-relational mapping toolkit providing transparent relational persistence for plain PHP objects.
    • DBAL (Doctrine\DBAL): An enhanced database abstraction layer on top of PDO that provides a single API to bridge differences between RDBMS vendors.
    • Persistence (Doctrine\Persistence): Contains reusable components for persistence.
    • Collections (Doctrine\Common\Collections): Contains reusable collection components.
    • Event Manager (Doctrine\Common): Contains reusable event management components.
  8. Understand Change Tracking Policies

    3.6.x

    Doctrine uses change tracking policies to determine which managed entities have changed since they were last synchronized with the database. You can define these policies on a per-class or per-hierarchy basis. There are two primary policies:

    1. Deferred Implicit (Default): Doctrine performs a property-by-property comparison of all managed entities during EntityManager#flush(). It also supports "persistence by reachability," meaning it detects changes to entities or new entities referenced by other managed entities. While convenient, it can impact performance in large units of work because every managed entity must be checked.

    2. Deferred Explicit: Similar to the implicit policy, it uses property-by-property comparison at commit time. However, Doctrine only checks entities that have been explicitly marked for change detection via EntityManager#persist(entity) or through a save cascade. This improves performance for large units of work but requires you to manually track and persist entities that have changed.

  9. Understand Doctrine Association Fundamentals

    3.6.x

    Associations in Doctrine are managed using standard PHP object references or collections of objects. Key concepts include:

    • Persistence: Changes to associations are not sent to the database immediately; they are synchronized only when calling EntityManager#flush().
    • Collections: Properties representing a relationship to multiple entities must implement the Doctrine\Common\Collections\Collection interface.
    • Owning vs. Inverse Side: In bidirectional associations, Doctrine only checks the owning side for changes. Updating only the owning side is sufficient for database synchronization, though updating both sides is recommended for in-memory consistency.
    • Removal: Removing an entity from a collection removes the association, not the entity itself.
  10. Migrate from YAML mapping to XML, Attributes, or Annotations

    3.6.x

    The YamlDriver and SimpleYamlDriver have been removed in 3.0. You must migrate your metadata mapping to use attributes, annotations, or XML drivers.

    If you are currently using YAML, you can use the orm:convert-mapping command to convert your metadata to XML before upgrading to 3.0:

    php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
  11. Remove multi-dot/deep-path expressions in DQL (2.0-BETA2)

    3.6.x

    Support for implicit joins via multi-dot/deep path expressions was removed in 2.0-BETA2. You must now use explicit joins.

    Incorrect (Deep Path):

    SELECT u FROM User u WHERE u.group.name = ?1

    Correct (Explicit Join):

    SELECT u FROM User u JOIN u.group g WHERE g.name = ?1
  12. Suspend and restore filters to preserve parameters

    3.6.x

    When you use disable($name), the filter instance is deleted and all previously set parameters are lost. If you re-enable it, it will be a fresh instance without parameters.

    To temporarily disable a filter while keeping its parameters intact, use suspend($name) and restore($name):

    1. suspend($name): Temporarily stops the filter from being applied but preserves its state.
    2. restore($name): Re-activates the suspended filter with its original parameters.
    <?php
    $filter = $em->getFilters()->enable("locale");
    $filter->setParameter('locale', 'en');
    
    // Temporary suspend the filter
    $filter = $em->getFilters()->suspend("locale");
    
    // Do things
    
    // Then restore it, the locale parameter will still be set
    $filter = $em->getFilters()->restore("locale");