Doctrine ORM para PHP: guía completa con ejemplos

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

¿Qué es Doctrine ORM y para qué sirve?

\n\n

Doctrine ORM (Object-Relational Mapping) es una potente biblioteca para PHP que permite a los desarrolladores trabajar con bases de datos utilizando un enfoque orientado a objetos, en lugar de escribir consultas SQL en bruto. Doctrine ORM es el estándar de facto para Symfony, pero también se puede utilizar en cualquier otro proyecto PHP (Laravel, Yii, PHP puro).

\n\n

El problema principal que resuelve Doctrine: la discrepancia entre el modelo relacional de datos (tablas, filas, columnas) y el modelo de objetos (clases, objetos, propiedades). Doctrine convierte automáticamente los objetos PHP en registros de base de datos y viceversa.

\n\n

Funcionalidades clave:

\n
    \n
  • Creación automática del esquema de BD — basada en anotaciones/atributos en las clases
  • \n
  • Repository Pattern — métodos convenientes para buscar y filtrar datos
  • \n
  • DQL (Doctrine Query Language) — lenguaje de consultas orientado a objetos
  • \n
  • Lazy Loading — carga de datos relacionados solo cuando sea necesario
  • \n
  • Migraciones — gestión de cambios en el esquema de la BD
  • \n
  • Transacciones — soporte completo de ACID
  • \n
  • Caché — de metadatos, consultas, resultados
  • \n
\n\n

Doctrine ORM es adecuado para proyectos de cualquier escala: desde sitios pequeños hasta sistemas empresariales con cientos de tablas.

\n\n

Instalación de Doctrine ORM

\n\n

La instalación se realiza a través de Composer (gestor de paquetes de PHP). Abra la terminal en la raíz de su proyecto y ejecute:

\n\n
composer require doctrine/orm
\n\n

Para trabajar con Symfony, se recomienda instalar el paquete DoctrineBundle:

\n\n
composer require symfony/orm-pack\ncomposer require --dev symfony/maker-bundle  # para generación de código
\n\n

Si usa PHP puro sin framework, también necesitará instalar el controlador para su BD:

\n\n
composer require doctrine/dbal\ncomposer require doctrine/annotations  # para trabajar con anotaciones (PHP 7.4 e inferiores)
\n\n

Para trabajar con atributos de PHP 8+ (método recomendado): no se necesitan anotaciones, Doctrine admite atributos nativos.

\n\n

Inicio rápido: ejemplo de código

\n\n

Veamos un ejemplo sencillo: crear una entidad "Product" y guardarla en la base de datos.

\n\n

1. Creamos la clase entidad (Entity)

\n\n
<?php\n// src/Entity/Product.php\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\n\n#[ORM\\Entity]\n#[ORM\\Table(name: 'products')]\nclass Product\n{\n    #[ORM\\Id]\n    #[ORM\\GeneratedValue]\n    #[ORM\\Column(type: 'integer')]\n    private int $id;\n\n    #[ORM\\Column(type: 'string', length: 255)]\n    private string $name;\n\n    #[ORM\\Column(type: 'float')]\n    private float $price;\n\n    // Getters y setters\n    public function getId(): int\n    {\n        return $this->id;\n    }\n\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public function setName(string $name): self\n    {\n        $this->name = $name;\n        return $this;\n    }\n\n    public function getPrice(): float\n    {\n        return $this->price;\n    }\n\n    public function setPrice(float $price): self\n    {\n        $this->price = $price;\n        return $this;\n    }\n}
\n\n

2. Creamos y guardamos el objeto

\n\n
<?php\n// En un controlador de Symfony o en cualquier otro lugar\nuse App\\Entity\\Product;\nuse Doctrine\\ORM\\EntityManagerInterface;\n\nclass ProductController\n{\n    public function createProduct(EntityManagerInterface $entityManager)\n    {\n        $product = new Product();\n        $product->setName('Portátil');\n        $product->setPrice(49999.99);\n\n        // Le decimos a Doctrine que el objeto debe guardarse\n        $entityManager->persist($product);\n        \n        // Ejecutamos el INSERT                    

Recommendations