Doctrine ORM para PHP: guía completa con ejemplos prácticos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Doctrine ORM para PHP: guía completa con ejemplos prácticos

1. ¿Qué es y para qué sirve?

Doctrine ORM (Object-Relational Mapper) es una potente biblioteca para PHP que implementa el patrón Data Mapper. A diferencia de Active Record (usado en Laravel Eloquent), Doctrine separa completamente la lógica de negocio (entidades) de la lógica de base de datos. Las entidades son objetos PHP simples (Plain Old PHP Objects, POPO) que no conocen la existencia de la base de datos. Todo el trabajo con la BD se realiza a través de un repositorio central: el EntityManager.

¿Para qué sirve? Doctrine resuelve el problema fundamental de desajuste entre el modelo orientado a objetos y el modelo relacional de base de datos (Object-Relational Impedance Mismatch). Trabajas con objetos y colecciones, mientras Doctrine traduce automáticamente tus acciones en consultas SQL. Esto permite escribir código más limpio, testeable y mantenible, especialmente en proyectos empresariales grandes.

Ventajas clave: control total sobre SQL (mediante DQL — Doctrine Query Language), carga diferida (Lazy Loading), sistema flexible de eventos (Lifecycle Events), soporte para herencia (Mapped Superclass, Single Table Inheritance, Joined Table Inheritance), Query Builder integrado e hidratadores (Hydration Modes). Doctrine es el estándar de facto para aplicaciones PHP complejas (Symfony, Drupal, Magento).

2. Instalación

La instalación se realiza mediante Composer (equivalente a pip para PHP). Para uso básico bastan dos paquetes:

composer require doctrine/orm
composer require doctrine/dbal
composer require symfony/cache  # Recomendado para caché de metadatos

Para trabajar con anotaciones (método antiguo pero popular) se necesita un paquete adicional:

composer require doctrine/annotations

Para configuración YAML o XML:

composer require symfony/yaml  # Para YAML

Después de instalar, asegúrate de incluir el cargador automático de Composer en tu proyecto:

require_once __DIR__ . '/vendor/autoload.php';

3. Inicio rápido — ejemplo mínimo funcional

Vamos a crear una entidad simple User y guardarla en una base de datos SQLite.

Paso 1: Configuración del EntityManager (bootstrap.php)

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
use Doctrine\DBAL\DriverManager;

require_once __DIR__ . '/vendor/autoload.php';

// Configurar rutas de entidades y modo de desarrollo
$paths = [__DIR__ . '/src/Entity'];
$isDevMode = true;

// Crear configuración ORM
$config = ORMSetup::createAttributeMetadataConfiguration($paths, $isDevMode);

// Configurar conexión a BD (SQLite)
$connectionParams = [
    'driver' => 'pdo_sqlite',
    'path' => __DIR__ . '/data/database.sqlite',
];

$connection = DriverManager::getConnection($connectionParams, $config);

// Crear EntityManager
$entityManager = new EntityManager($connection, $config);

Paso 2: Crear la entidad (src/Entity/User.php)

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private int|null $id = null;

    #[ORM\Column(type: 'string', length: 100)]
    private string $name;

    #[ORM\Column(type: 'string', length: 255, unique: true)]
    private string $email;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;
        return $this;
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function setEmail(string $email): self                    

Recommendations