@@ -168,7 +168,7 @@ Here is a complete list of ``Column``s attributes (all optional):
168168- ``insertable `` (default: ``true ``): Whether the column should be inserted.
169169- ``updatable `` (default: ``true ``): Whether the column should be updated.
170170- ``generated `` (default: ``null ``): Whether the generated strategy should be ``'NEVER' ``, ``'INSERT' `` and ``ALWAYS ``.
171- - ``enumType `` (requires PHP 8.1 and ``doctrine/orm `` 2.11): The PHP enum class name to convert the database value into.
171+ - ``enumType `` (requires PHP 8.1 and ``doctrine/orm `` 2.11): The PHP enum class name to convert the database value into. See :ref: ` reference-enum-mapping `.
172172- ``precision `` (default: 0): The precision for a decimal (exact numeric) column
173173 (applies only for decimal column),
174174 which is the maximum number of digits that are stored for the values.
@@ -321,6 +321,160 @@ that value and raw value are different, you have to use the raw value representa
321321 $messageRepository = $entityManager->getRepository(Message::class);
322322 $deMessages = $messageRepository->findBy(['language' => 'de']); // Use lower case here for raw value representation
323323
324+ .. _reference-enum-mapping :
325+
326+ Mapping PHP Enums
327+ -----------------
328+
329+ .. versionadded :: 2.11
330+
331+ Doctrine natively supports mapping PHP backed enums to database columns.
332+ A backed enum is a PHP enum that the same scalar type (``string `` or ``int ``)
333+ assigned to each case. Doctrine stores the scalar value in the database and
334+ converts it back to the enum instance when hydrating the entity.
335+
336+ Using ``enumType `` provides three main benefits:
337+
338+ - **Automatic conversion **: Doctrine handles the conversion in both directions
339+ transparently. When loading an entity, scalar values from the database are
340+ converted into enum instances. When persisting, enum instances are reduced
341+ to their scalar ``->value `` before being sent to the database.
342+ - **Type-safety **: Entity properties contain enum instances directly. Your
343+ getters return ``Suit `` instead of ``string ``, removing the need to call
344+ ``Suit::from() `` manually.
345+ - **Validation **: When a database value does not match any enum case, Doctrine
346+ throws a ``MappingException `` during hydration instead of silently returning
347+ an invalid value.
348+
349+ This feature works with all database platforms supported by Doctrine (MySQL,
350+ PostgreSQL, SQLite, etc.) as it relies on standard column types (``string ``,
351+ ``integer ``, ``json ``, ``simple_array ``) rather than any vendor-specific enum
352+ type.
353+
354+ .. note ::
355+
356+ This is unrelated to the MySQL-specific ``ENUM `` column type covered in
357+ :doc: `the MySQL Enums cookbook entry </cookbook/mysql-enums >`.
358+
359+ Defining an Enum
360+ ~~~~~~~~~~~~~~~~
361+
362+ .. literalinclude :: basic-mapping/Suit.php
363+ :language: php
364+
365+ Only backed enums (``string `` or ``int ``) are supported. Unit enums (without
366+ a scalar value) cannot be mapped.
367+
368+ Single-Value Columns
369+ ~~~~~~~~~~~~~~~~~~~~
370+
371+ Use the ``enumType `` option on ``#[Column] `` to map a property to a backed enum.
372+ The underlying database column stores the enum's scalar value (``string `` or ``int ``).
373+
374+ .. literalinclude :: basic-mapping/EnumMapping.php
375+ :language: php
376+
377+ When the PHP property is typed with the enum class, Doctrine automatically
378+ infers the appropriate column type (``string `` for string-backed enums,
379+ ``integer `` for int-backed enums) and sets ``enumType ``. You can also specify
380+ the column ``type `` explicitly.
381+
382+ Storing Collections of Enums
383+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
384+
385+ You can store multiple enum values in a single column by combining ``enumType ``
386+ with a collection column type: ``json `` or ``simple_array ``.
387+
388+ .. note ::
389+
390+ Automatic type inference does not apply to collection columns. When the
391+ PHP property is typed as ``array ``, Doctrine cannot detect the enum class.
392+ You must specify both ``type `` and ``enumType `` explicitly.
393+
394+ .. literalinclude :: basic-mapping/EnumCollectionMapping.php
395+ :language: php
396+
397+ With ``json ``, the values are stored as a JSON array (e.g. ``["hearts","spades"] ``).
398+ With ``simple_array ``, the values are stored as a comma-separated string
399+ (e.g. ``hearts,spades ``).
400+
401+ In both cases, Doctrine converts each element to and from the enum
402+ automatically during hydration and persistence.
403+
404+ .. tip ::
405+
406+ Use ``json `` when enum values may contain commas, when you need to store
407+ int-backed enums (as it preserves value types), when the column also
408+ stores complex/nested data structures, or when you want to query individual
409+ values using database-native JSON operators (e.g. PostgreSQL ``jsonb ``).
410+ Prefer ``simple_array `` for a compact, human-readable storage of
411+ string-backed enums whose values do not contain commas.
412+
413+ +-------------------+-----------------------------+-------------------------------+
414+ | Column type | Database storage | PHP type |
415+ +===================+=============================+===============================+
416+ | ``string `` | ``hearts `` | ``Suit `` |
417+ +-------------------+-----------------------------+-------------------------------+
418+ | ``integer `` | ``1 `` | ``Priority `` |
419+ +-------------------+-----------------------------+-------------------------------+
420+ | ``json `` | ``["hearts","spades"] `` | ``array<Suit> `` |
421+ +-------------------+-----------------------------+-------------------------------+
422+ | ``simple_array `` | ``hearts,spades `` | ``array<Suit> `` |
423+ +-------------------+-----------------------------+-------------------------------+
424+
425+ Nullable Enums
426+ ~~~~~~~~~~~~~~
427+
428+ Enum columns can be nullable. When the database value is ``NULL ``, Doctrine
429+ preserves it as ``null `` without triggering any validation error.
430+
431+ .. code-block :: php
432+
433+ <?php
434+ #[ORM\Column(type: 'string', nullable: true, enumType: Suit::class)]
435+ private Suit|null $suit = null;
436+
437+ Default Values
438+ ~~~~~~~~~~~~~~
439+
440+ You can specify a database-level default using an enum case directly in the
441+ column options:
442+
443+ .. code-block :: php
444+
445+ <?php
446+ #[ORM\Column(options: ['default' => Suit::Hearts])]
447+ public Suit $suit;
448+
449+ Using Enums in Queries
450+ ~~~~~~~~~~~~~~~~~~~~~~
451+
452+ Enum instances can be used directly as parameters in DQL, QueryBuilder, and
453+ repository methods. Doctrine converts them to their scalar value automatically.
454+
455+ .. code-block :: php
456+
457+ <?php
458+ // QueryBuilder
459+ $qb = $em->createQueryBuilder();
460+ $qb->select('c')
461+ ->from(Card::class, 'c')
462+ ->where('c.suit = :suit')
463+ ->setParameter('suit', Suit::Clubs);
464+
465+ // Repository
466+ $cards = $em->getRepository(Card::class)->findBy(['suit' => Suit::Clubs]);
467+
468+ XML Mapping
469+ ~~~~~~~~~~~
470+
471+ When using XML mapping, the ``enum-type `` attribute is used on ``<field> ``
472+ elements:
473+
474+ .. code-block :: xml
475+
476+ <field name =" suit" type =" string" enum-type =" App\Entity\Suit" />
477+
324478 .. _reference-mapping-types :
325479
326480Doctrine Mapping Types
0 commit comments