ClassMetadataBuilder
if
, des for
etcDans doctrine-bundle 2.12.0,
la configuration du FQCN de PHPDriver
n’est pas bonne : elle indique Doctrine\ORM\Mapping\Driver\PHPDriver
,
mais la classe a été déplacée en 2.3.0
vers Doctrine\Common\Persistence\Mapping\Driver\PHPDriver
.
Vous allez donc avoir cette exception : Attempted to load class "PHPDriver" from namespace "Doctrine\ORM\Mapping\Driver". Did you forget a "use" statement for "Doctrine\Persistence\Mapping\Driver\PHPDriver"?
Il faut donc changer la configuration comme suit :
# config/packages/doctrine.php
use Doctrine\Persistence\Mapping\Driver\PHPDriver;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator
->parameters()
->set('doctrine.orm.metadata.php.class', PHPDriver::class);
}
Pour indiquer à Doctrine que le mapping sera fait en PHP dans config/doctrine
:
# config/packages/doctrine.php
use Symfony\Config\DoctrineConfig;
return static function (DoctrineConfig $config): void {
$config
->orm()
->entityManager('default')
->mapping('App')
->type('php')
->isBundle(false)
->dir('%kernel.project_dir%/config/doctrine/mapping')
->prefix('App\\Entity')
->alias('App');
}
Comme pour les autres fichiers de mapping, le nom du fichier doit avoir ce format :
\
sont remplacés par des .
.php
Exemple pour l’entité App\Entity\Foo
: config/doctrine/App.Entity.Foo.php
.
Doctrine est assez gentil : il nous envoie une variable $metadata
quand il inclut notre fichier de configuration,
qui est déjà configurée pour notre entité.
Pour que PHPStorm (et d’autres outils comme phpstan) sache que cette variable existe, on peut ajouter une PHPDoc :
<?php
declare(strict_types=1);
use Doctrine\ORM\Mapping\ClassMetadata;
/** @var ClassMetadata $metadata */
A partir de là, vous pouvez configurer votre entité avec $metadata
.
Par exemple, pour ajouter un champ, vous pouvez utiliser mapField()
.
Cependant, vous allez passer par des gros tableaux, bien compliqués à écrire (il faut trouver dans la doc toutes les clés possibles, les valeurs possibles etc) : ce n’est pas très optimal et très difficile à relire / valider.
N’allez pas sur Twitter (ouais, je vais rester sur ce nom) pour insulter les mères de tout le monde : Doctrine est sympa, il nous a fait une classe ClassMetadataBuilder qui permet de passer par des objets et pas des array.
<?php
declare(strict_types=1);
use Doctrine\ORM\{
Mapping\Builder\ClassMetadataBuilder,
Mapping\ClassMetadata
};
/** @var ClassMetadata $metadata */
$builder = new ClassMetadataBuilder($metadata);
Documentation de ClassMetadataBuilder.
A votre tour : c’est le moment de configurer le mapping de votre entité, via $builder
.
Comme je suis assez sympa, je vous montre un exemple pour un identifiant :
<?php
declare(strict_types=1);
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\{
Mapping\Builder\ClassMetadataBuilder,
Mapping\ClassMetadata
};
/** @var ClassMetadata $metadata */
$builder = new ClassMetadataBuilder($metadata);
$builder
->createField('id', Types::INTEGER)
->makePrimaryKey()
->generatedValue()
->option('unsigned', true)
->build();
Vous pouvez exécuter la commande bin/console doctrine:mapping:info
pour vérifier que Doctrine trouve bien vos fichiers de mapping.
La commande bin/console doctrine:schema:validate
exécutera doctrine:mapping:info
,
et en plus, vérifiera que votre base de données correspond à votre mapping :
qu’il ne manque pas de migrations, et qu’elles ont toutes été jouées.
Si vous voulez voir ce que Doctrine veut faire de votre mapping dans votre base de données :
bin/console doctrine:schema:update --dump-sql
.