How to persist enum with Symfony Doctrine (entity field type:"enum")
Yes doctrine does not support php Enum from version 8.1 but you can create your own Doctrine type. Defining a custom Doctrine type
In your case it should be something link this:
<?php
namespace App\DBAL;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use App\Enum\GradeEnum;
use InvalidArgumentException;
use JetBrains\PhpStorm\Pure;
class GradeType extends Type
{
protected string $name;
protected array $values = [
GradeEnum::A5plus,
GradeEnum::A5,
GradeEnum::A4,
GradeEnum::A3,
GradeEnum::A2,
GradeEnum::A1,
GradeEnum::B2,
GradeEnum::B1,
GradeEnum::C2,
GradeEnum::C1,
GradeEnum::D2,
GradeEnum::D1,
];
const GRADE = 'grade';
public function getName(): string
{
return self::GRADE;
}
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
{
$values = array_map(function ($val) {
/** @var GradeEnum $val */
return "'{$val->name}'";
}, $this->values);
return 'ENUM(' . implode(', ', $values) . ')';
}
#[Pure]
public function convertToPHPValue($value, AbstractPlatform $platform): ?GradeEnum
{
if (null === $value) {
return null;
}
return GradeEnum::getGradeFromString($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
/** @var GradeEnum $value */
if ($value !== null) {
if (!in_array($value, $this->values)) {
throw new InvalidArgumentException("Invalid '" . $this->name . "' value.");
} else {
return $value->name;
}
}
return null;
}
public function canRequireSQLConversion(): bool
{
return true;
}
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
{
return true;
}
}
<?php
namespace App\Enum;
enum GradeEnum: int
{
case A5plus = 0;
case A5 = 1;
case A4 = 2;
case A3 = 3;
case A2 = 4;
case A1 = 5;
case B2 = 6;
case B1 = 7;
case C2 = 8;
case C1 = 9;
case D2 = 10;
case D1 = 11;
public static function getGradeFromString(string $grade): GradeEnum {
return match ($grade) {
self::A5plus->name => self::A5plus,
self::A5->name => self::A5,
self::A4->name => self::A4,
self::A3->name => self::A3,
self::A2->name => self::A2,
self::A1->name => self::A1,
self::B1->name => self::B1,
self::B2->name => self::B2,
self::C1->name => self::C1,
self::C2->name => self::C2,
self::D1->name => self::D1,
self::D2->name => self::D2,
};
}
}
Do not forget to add your type into your doctrine.yaml
doctrine:
dbal:
types:
grade: App\DBAL\GradeType
mapping_types:
enum: string
grade: grade
Have a good day !
Starting with version 2.11, the ORM supports php 8 enums
enum Suit: string {
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
#[Entity]
class Card
{
/** ... */
#[Column(type: 'string', enumType: Suit::class)]
public $suit;
}
You can read more about this in the offical blog post. Official docs should follow soon.