Buenas prácticas oficiales de Symfony

4.3. Utilizando una capa de persistencia

Symfony es un framework HTTP que simplemente se encarga de generar respuestas HTTP a partir de peticiones HTTP. Por eso Symfony no incluye ninguna utilidad para comunicarse con las capas de persistencia, como por ejemplo bases de datos y APIs externas. Así que eres libre de escoger la librería o estrategia que prefieras para solventar esta carencia.

En la práctica la mayoría de aplicaciones Symfony hacen uso del proyecto Doctrine para definir su modelo mediante las entidades y los repositorios. Al igual que con el resto de la lógica de negocio, se recomienda almacenar las entidades de Doctrine dentro del bundle AppBundle.

Las tres entidades definidas en la aplicación del blog son un buen ejemplo de cómo organizar estas clases:

symfony2-project/
├─ ...
└─ src/
   └─ AppBundle/
      └─ Entity/
         ├─ Comment.php
         ├─ Post.php
         └─ User.php

Truco Si tienes la experiencia suficiente, por supuesto puedes almacenar las entidades de Doctrine en cualquier otro directorio dentro de src/.

4.3.1. La información de mapeo de Doctrine

Las entidades de Doctrine son objetos PHP normales y corrientes cuya información se almacena en la base de datos. La única información que tiene Doctrine sobre tus entidades es la información de mapeo (mapping en inglés) que definas para ellas. Doctrine soporta cuatro formatos para definir esta información: YAML, XML, PHP y anotaciones.

Buena Práctica Utiliza anotaciones para definir la información de mapeo de las entidades de Doctrine.

Las anotaciones son con mucha diferencia el formato más cómodo y la manera más ágil de definir la información de mapeo:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 */
class Post
{
    const NUM_ITEMS = 10;

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $title;

    /**
     * @ORM\Column(type="string")
     */
    private $slug;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="string")
     */
    private $authorEmail;

    /**
     * @ORM\Column(type="datetime")
     */
    private $publishedAt;

    /**
     * @ORM\OneToMany(
     *      targetEntity="Comment",
     *      mappedBy="post",
     *      orphanRemoval=true
     * )
     * @ORM\OrderBy({"publishedAt" = "ASC"})
     */
    private $comments;

    public function __construct()
    {
        $this->publishedAt = new \DateTime();
        $this->comments = new ArrayCollection();
    }

    // getters and setters ...
}

Como todos los formatos tienen el mismo rendimiento, de nuevo esta decisión es una cuestión de gusto personal y de elegir el formato con el que tú y tu equipo os encontréis más a gusto.

4.3.2. Datos de prueba

Symfony no incluye por defecto el soporte para crear datos de prueba, por lo que deberías ejecutar el siguiente comando para instalar el bundle para crear datos de prueba de Doctrine:

$ composer require "doctrine/doctrine-fixtures-bundle":"~2"

Después, activa el nuevo bundle en AppKernel.php, pero hazlo solamente en el entorno de desarrollo (dev) y pruebas (test), ya que en producción no se necesita y así evitamos que penalice el rendimiento:

use Symfony\Component\HttpKernel\Kernel;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            // ...
            $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
        }

        return $bundles;
    }

    // ...
}

Por simplicidad, es recomendable crear una única clase para definir los datos de prueba. Si esta clase crece mucho, divide sus contenidos en varias clases más pequeñas.

Suponiendo que se haya definido al menos una clase con archivos de prueba y que el acceso a la base de datos está bien configurado, puedes cargar todos los datos ejecutando el siguiente comando:

$ php app/console doctrine:fixtures:load

Careful, database will be purged. Do you want to continue Y/N ? Y
  > purging database
  > loading AppBundle\DataFixtures\ORM\LoadFixtures