-
-
Notifications
You must be signed in to change notification settings - Fork 56
feat!: consts for types
#486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat!: consts for types
#486
Conversation
WalkthroughAdds a new PHP enum Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/MartinGeorgiev/Doctrine/DBAL/Type.php(1 hunks)src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.php(2 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 0
File: :0-0
Timestamp: 2025-03-26T02:46:12.804Z
Learning: The PR "preserve the type of floats and integers when transforming back and forth between PostgreSQL and PHP" improves type handling by ensuring that integers remain integers, floats remain floats, numeric strings stay as strings, and booleans are properly converted through the transformation process.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what TYPE_NAME constants contain and getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the point[] array type should be documented as "point[]" not "_point" in the AVAILABLE-TYPES.md table, to be consistent with all other array types like text[], jsonb[], inet[], etc.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 443
File: tests/Unit/MartinGeorgiev/Utils/PostgresArrayToPHPArrayTransformerTest.php:169-172
Timestamp: 2025-09-06T22:15:32.757Z
Learning: In martin-georgiev/postgresql-for-doctrine, TextArray users should expect the database to normalize data to strings only. The design assumes that intended PHP data for TextArray is always strings, not other data types, which is a reasonable tradeoff that aligns with PostgreSQL text[] type semantics.
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what TYPE_NAME constants contain and getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-09-06T22:15:32.757Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 443
File: tests/Unit/MartinGeorgiev/Utils/PostgresArrayToPHPArrayTransformerTest.php:169-172
Timestamp: 2025-09-06T22:15:32.757Z
Learning: In martin-georgiev/postgresql-for-doctrine, TextArray users should expect the database to normalize data to strings only. The design assumes that intended PHP data for TextArray is always strings, not other data types, which is a reasonable tradeoff that aligns with PostgreSQL text[] type semantics.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the point[] array type should be documented as "point[]" not "_point" in the AVAILABLE-TYPES.md table, to be consistent with all other array types like text[], jsonb[], inet[], etc.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-24T16:52:32.488Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 0
File: :0-0
Timestamp: 2025-08-24T16:52:32.488Z
Learning: This repository uses BaseType extension pattern for custom Doctrine DBAL types with PostgreSQL platform assertions, comprehensive unit and integration testing with data providers, and dedicated exception classes for type conversion errors.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-04-11T11:23:44.192Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 340
File: tests/MartinGeorgiev/Doctrine/DBAL/Types/InetArrayTest.php:145-145
Timestamp: 2025-04-11T11:23:44.192Z
Learning: In the PostgreSQL for Doctrine test cases, methods that test database-to-PHP conversions should use `mixed` type for parameter and include non-string test cases in their data providers, following the pattern in classes like InetTest, CidrTest, and MacaddrTest.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.phpsrc/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-03-11T12:32:10.726Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 263
File: src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Numrange.php:19-21
Timestamp: 2025-03-11T12:32:10.726Z
Learning: In the postgresql-for-doctrine repository, PostgreSQL range functions have distinct implementations for different data types. The `Numrange` function works with numeric/decimal values and is tested using the `ContainsDecimals` fixture with properties typed as `float`. In contrast, the `Int4range` function works with 32-bit integers and is tested using the `ContainsIntegers` fixture with properties typed as `int`. While the PHP implementations share a similar structure (extending `BaseFunction`), they are semantically different as they handle different PostgreSQL data types.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.php
🧬 Code graph analysis (1)
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.php (1)
src/MartinGeorgiev/Doctrine/DBAL/Type.php (1)
Type(7-10)
🔇 Additional comments (1)
src/MartinGeorgiev/Doctrine/DBAL/Types/BigIntArray.php (1)
7-8: Technical implementation is correct.The import and constant usage are syntactically correct, and the change maintains the same TYPE_NAME value ('bigint[]'), ensuring no backward compatibility issues. However, if this pattern is intended to be applied across all type classes in the repository, ensure consistency by updating other type classes similarly.
The verification script in the Type.php review will help confirm whether this pattern should be applied to other type classes as well.
Also applies to: 22-22
| abstract class Type | ||
| { | ||
| public const BIGINT_ARRAY = 'bigint[]'; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify completeness and consistency with other type classes.
This implementation introduces a central Type class with only the BIGINT_ARRAY constant. Based on the repository's learnings, there are many other array types (text[], jsonb[], inet[], point[], etc.) that should also have constants defined here if the goal is to centralize type name constants.
Additionally, the class name Type in namespace MartinGeorgiev\Doctrine\DBAL might cause confusion with Doctrine's own Doctrine\DBAL\Types\Type class.
Run the following script to check all existing type classes and identify which ones should have constants added:
This will help verify:
- How many type classes exist that should potentially use centralized constants
- Whether the current approach is consistent across all types
- The inheritance hierarchy to understand the design pattern
🏁 Script executed:
#!/bin/bash
# Description: Find all type classes and their TYPE_NAME declarations to assess completeness
# Find all type classes in the Types directory
echo "=== All Type Classes ==="
fd -e php -p 'src/MartinGeorgiev/Doctrine/DBAL/Types/.*\.php$' --exec basename {}
echo -e "\n=== TYPE_NAME Declarations ==="
# Search for TYPE_NAME constant declarations across all type classes
rg -n -A1 'protected const TYPE_NAME' src/MartinGeorgiev/Doctrine/DBAL/Types/
echo -e "\n=== Checking for BaseType or similar parent classes ==="
# Find base classes to understand the inheritance hierarchy
rg -n 'class.*extends (Base\w+|AbstractType)' src/MartinGeorgiev/Doctrine/DBAL/Types/Length of output: 10459
Complete the centralization of type constants or document this as a staged migration.
Verification confirms the incomplete pattern: only BigIntArray uses the new Type::BIGINT_ARRAY constant, while 27 other types still define their TYPE_NAME as string literals ('text[]', 'jsonb[]', 'inet[]', 'point[]', 'macaddr[]', 'cidr[]', 'bool[]', 'real[]', 'integer[]', 'smallint[]', 'double precision[]', 'geometry[]', 'geography[]', 'point', 'inet', 'cidr', 'macaddr', 'ltree', 'jsonb', 'geometry', 'geography', 'tstzrange', 'tsrange', 'int4range', 'int8range', 'numrange', 'daterange').
Either:
- Migrate all type classes to use constants defined in the Type class (TextArray, PointArray, JsonbArray, etc.)
- Document this as a staged refactor and track remaining types for future PRs
- Revert and maintain string literals for consistency
Mixing both approaches (one type using constants, others using strings) creates inconsistent patterns and technical debt.
🤖 Prompt for AI Agents
In src/MartinGeorgiev/Doctrine/DBAL/Type.php around lines 7-10, the code
introduced a single constant (BIGINT_ARRAY) while the other 27 types still use
string literals, causing inconsistent patterns; fix by adding constants for all
remaining type names (e.g., TEXT_ARRAY, JSONB_ARRAY, INET, POINT_ARRAY, MACADDR,
CIDR, BOOL_ARRAY, REAL_ARRAY, INTEGER_ARRAY, SMALLINT_ARRAY,
DOUBLE_PRECISION_ARRAY, GEOMETRY, GEOGRAPHY, TSTZRANGE, TSRANGE, INT4RANGE,
INT8RANGE, NUMRANGE, DATERANGE, LTREE, JSONB, POINT, etc.) into this Type class
and update each type class to reference Type::CONSTANT for its TYPE_NAME; if you
cannot migrate all in one PR, instead add a clear TODO and documentation comment
in this file describing staged migration and list the remaining types plus
create/reference a tracking issue so the mixed approach is explicitly tracked.
|
You can use a native |
|
#[ORM\Column(type: Type::BIGINT_ARRAY->value)]
Update: I think I now got what you meant ;-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/MartinGeorgiev/Doctrine/DBAL/Type.php (1)
7-10: Incomplete migration pattern noted.As flagged in the previous review, only
BigIntArraycurrently uses this constant while 27 other type classes still use string literals. This creates inconsistency across the codebase.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/MartinGeorgiev/Doctrine/DBAL/Type.php(1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what TYPE_NAME constants contain and getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 0
File: :0-0
Timestamp: 2025-03-26T02:46:12.804Z
Learning: The PR "preserve the type of floats and integers when transforming back and forth between PostgreSQL and PHP" improves type handling by ensuring that integers remain integers, floats remain floats, numeric strings stay as strings, and booleans are properly converted through the transformation process.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the point[] array type should be documented as "point[]" not "_point" in the AVAILABLE-TYPES.md table, to be consistent with all other array types like text[], jsonb[], inet[], etc.
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what TYPE_NAME constants contain and getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the AVAILABLE-TYPES.md documentation table's second column shows DBAL type names (what getName() method returns) not PostgreSQL internal catalogue names. Array types use the format like 'text[]', 'jsonb[]', 'inet[]' - not the underscore-prefixed PostgreSQL internal names like '_text', '_jsonb', '_inet'.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-19T13:07:15.184Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 421
File: docs/AVAILABLE-TYPES.md:31-33
Timestamp: 2025-08-19T13:07:15.184Z
Learning: In martin-georgiev/postgresql-for-doctrine, the point[] array type should be documented as "point[]" not "_point" in the AVAILABLE-TYPES.md table, to be consistent with all other array types like text[], jsonb[], inet[], etc.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-09-06T22:15:32.757Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 443
File: tests/Unit/MartinGeorgiev/Utils/PostgresArrayToPHPArrayTransformerTest.php:169-172
Timestamp: 2025-09-06T22:15:32.757Z
Learning: In martin-georgiev/postgresql-for-doctrine, TextArray users should expect the database to normalize data to strings only. The design assumes that intended PHP data for TextArray is always strings, not other data types, which is a reasonable tradeoff that aligns with PostgreSQL text[] type semantics.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-04-11T11:23:44.192Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 340
File: tests/MartinGeorgiev/Doctrine/DBAL/Types/InetArrayTest.php:145-145
Timestamp: 2025-04-11T11:23:44.192Z
Learning: In the PostgreSQL for Doctrine test cases, methods that test database-to-PHP conversions should use `mixed` type for parameter and include non-string test cases in their data providers, following the pattern in classes like InetTest, CidrTest, and MacaddrTest.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
📚 Learning: 2025-08-24T16:52:32.488Z
Learnt from: martin-georgiev
Repo: martin-georgiev/postgresql-for-doctrine PR: 0
File: :0-0
Timestamp: 2025-08-24T16:52:32.488Z
Learning: This repository uses BaseType extension pattern for custom Doctrine DBAL types with PostgreSQL platform assertions, comprehensive unit and integration testing with data providers, and dedicated exception classes for type conversion errors.
Applied to files:
src/MartinGeorgiev/Doctrine/DBAL/Type.php
| enum Type | ||
| { | ||
| public const BIGINT_ARRAY = 'bigint[]'; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the file exists and view its actual content
if [ -f "src/MartinGeorgiev/Doctrine/DBAL/Type.php" ]; then
echo "=== File content ==="
cat -n "src/MartinGeorgiev/Doctrine/DBAL/Type.php"
echo ""
echo "=== File size ==="
wc -l "src/MartinGeorgiev/Doctrine/DBAL/Type.php"
else
echo "File not found at src/MartinGeorgiev/Doctrine/DBAL/Type.php"
# Try to find it
fd "Type.php" --type f
fiRepository: martin-georgiev/postgresql-for-doctrine
Length of output: 222
🌐 Web query:
PHP 8.1 enum syntax public const vs case backing values
💡 Result:
Short answer: they're different things.
-
case (backed or pure) defines an enum member (an instance). Backed cases are declared with a scalar type and value (enum E: string { case A = 'a'; }) and each instance has a read‑only ->value plus static from/tryFrom helpers. Backed enums require the enum type (string|int) and every case must have a unique scalar. [1][2]
-
public const inside an enum is just a class constant (a scalar or a reference). It is not an enum case and does not satisfy an enum typehint. A const can reference a case (aliasing it) — e.g. public const X = self::SomeCase; — but that const holds the case reference or scalar you assign, not a case instance value unless you explicitly use the case->value (PHP 8.2 added easier use of case values in consts). [3][1]
Examples:
-
Backed case:
enum Status: string { case Active = 'active'; }
$v = Status::Active->value; // 'active' — Status::from('active') returns Status::Active. [2] -
Enum const alias / scalar const:
enum Status { case Active; public const LIVE = self::Active; public const TAG = 'live'; }
Status::Active is an enum instance; Status::TAG is a string and does NOT satisfy a Status typehint. [1][3]
If you want to map external scalars (DB values, API keys) to enum instances, use a backed enum (case = 'value') so you can safely convert with from/tryFrom. [2][3]
Sources: PHP manual (enum constants + backed enums) and related docs. [1][2][3]
References
[1] PHP manual — Enumeration constants.
[2] PHP manual — Backed enumerations.
[3] Shopware / community notes on using enums and consts (shows const vs case behavior and PHP 8.2 improvement).
🌐 Web query:
PHP enum public const vs backed enum case DBAL doctrine type constants
💡 Result:
Short answer
- Use enum cases (backed enums) when the value must round‑trip to storage (they have a scalar .value). Use public const in an enum when you need additional named constants that are not enum cases (aliases, calculated constants). [1][2]
Why (technical)
- Backed enum case: a language-level case with an associated int|string value (e.g. enum Status: string { case Active = 'A'; }). It serializes/deserializes easily and is intended for DB mapping. [2][1]
- public const inside an enum: just a plain constant (can reference cases) — useful for aliases or other constants but not a case and has no .value semantics. [1]
Doctrine/DBAL implications and common patterns
- Doctrine ORM (2.11+) can map PHP 8.1+ backed enums automatically (it recognizes enum types and provides enumType mapping) — prefer backed enums for direct, safe mapping. [3][4]
- DBAL has an enum type for MySQL or you can implement a custom Doctrine\DBAL\Types\Type. If you don’t use backed enums, custom Type classes often keep the allowed DB values as private/consts inside the Type (e.g. private const STATUS_VISIBLE = 'visible') and convert to/from PHP values in convertToPHPValue/convertToDatabaseValue. That pattern is for when you want DB values decoupled from PHP enum cases. [5][6][7]
- Recommendation:
- If you control both PHP and DB and want simple round-trip mapping: use backed enums and let Doctrine map them (cleanest). [3][4]
- If you must support DB-specific ENUM semantics, multiple DB platforms, or need different DB strings than enum values, implement a custom DBAL Type and keep a list of allowed DB constants in the Type (or map between enum cases and DB strings explicitly). [5][7]
References
- PHP enum constants & examples (manual). [1]
- PHP enumerations RFC / backed enums explanation. [2]
- Doctrine ORM release notes (PHP 8.1 enum support). [3]
- Doctrine ORM basic mapping / typed property & enum mapping docs. [4]
- Doctrine cookbook: MySQL ENUM and Type pattern. [5]
- Doctrine DBAL types reference (enum mapping behavior). [6]
- Doctrine custom mapping types guide (how to implement Type classes). [7]
🌐 Web query:
PHP enum with only public constants without cases valid syntax
💡 Result:
Yes — PHP enums may have zero cases and may contain constants, so an enum that only defines public constants (no case statements) is valid syntax. Example:
References: PHP manual — Basic enumerations (zero-case enums valid) [1]; Enumeration constants (enum may include public constants) [2].
Based on my verification, the original review comment contains a critical factual error. The code is syntactically valid PHP—enums can contain zero cases and public constants. However, the architectural concerns are valid. Here's the rewritten review comment:
This enum design pattern is not recommended for DBAL type mapping, even though it's syntactically valid.
An enum with only public constants (no cases) is valid PHP 8.1+ syntax, but it's an unusual pattern that defeats the purpose of using an enum. For DBAL type constants, choose one of these approaches:
Option 1: Backed enum with cases (type-safe, matches Doctrine conventions)
-enum Type
+enum Type: string
{
- public const BIGINT_ARRAY = 'bigint[]';
+ case BIGINT_ARRAY = 'bigint[]';
}Trade-off: Callers use Type::BIGINT_ARRAY->value in DBAL type annotations.
Option 2: Abstract class with constants (simpler, original approach)
-enum Type
+abstract class Type
{
public const BIGINT_ARRAY = 'bigint[]';
}Trade-off: No enum type safety, but constants are used directly without ->value.
Align with the maintainer's preference on which trade-off is acceptable. For DBAL custom types, backed enums (Option 1) are more idiomatic and provide type safety; abstract classes (Option 2) are simpler if enum semantics aren't needed.
🤖 Prompt for AI Agents
In src/MartinGeorgiev/Doctrine/DBAL/Type.php around lines 7 to 10, the current
enum contains only public constants (no cases) which is syntactically valid but
an anti-pattern for DBAL type mapping; replace this with either a backed enum
with cases so callers use Type::BIGINT_ARRAY->value (preferred for type-safety
and Doctrine conventions) or convert to an abstract class with public constants
so callers use Type::BIGINT_ARRAY directly; pick the maintainer-preferred
approach and update all call sites and docblocks accordingly.
Continuing on #362 (comment)
Is this what you had in mind?
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.