> On 6. Nov 2025, at 11:09, Mikhail Savin <[email protected]> wrote: > > Hi internals, > > I would like to propose adding a native values() method to the BackedEnum > interface that returns an array of all backing values. Before creating a > formal RFC, I'm seeking feedback on the concept and approach. > > == Summary == > > The proposal adds: > > interface BackedEnum { > public static function values(): array; > } > > This would allow: > > enum Status: string { > case Active = 'active'; > case Inactive = 'inactive'; > } > > Status::values(); // ['active', 'inactive'] > > == Motivation == > > This pattern is extremely common in the wild. Based on GitHub code search: > > * ~3,860+ direct implementations of this exact pattern > * ~20,000-40,000 estimated real usage when accounting for shared traits > * Used in major frameworks: Symfony core (TypeIdentifier.php), > Laravel ecosystem > * Documented by PHP.net: The manual itself shows EnumValuesTrait as > an example > > Common use cases: > * Database migrations: $table->enum('status', Status::values()) > * Form validation: $validator->rule('status', 'in', Status::values()) > * API responses: ['allowed_statuses' => Status::values()] > > == Implementation == > > I have a working implementation with tests: > https://github.com/php/php-src/pull/20398 > > The implementation: > * Mirrors the existing cases() method structure > * Extracts the value property from each case > * Returns an indexed array (0, 1, 2, ...) > * Only available on BackedEnum, not UnitEnum > * All tests pass > > == Backward Compatibility - Important Discussion Point == > > This is a breaking change. Enums that already define a values() method > will fail with: > > Fatal error: Cannot redeclare BackedEnum::values() > > Based on ecosystem research: > * ~24,000-44,000 enum instances will break > * All implementations are functionally identical to what's being proposed > * Migration is mechanical: just delete the user-defined method > > The break is justified because: > > 1. Behavior is unchanged - native implementation does exactly what users > already implemented > 2. Migration is trivial - simply remove the redundant method > 3. Precedent exists - PHP 8.1 native enums broke myclabs/php-enum > (4.9k stars) similarly > 4. Long-term benefit - standardization, discoverability, elimination > of boilerplate > 5. No alternative - virtual properties are technically infeasible; > different name doesn't match community expectations > > == Questions for Discussion == > > 1. BC break acceptability: Given the scope and straightforward migration, > is this break acceptable? > > 2. Method name: values() matches community usage (3,860+ examples) and > parallels cases(). Alternatives like getValues() or toArray() were > considered but seem inferior. Thoughts? > > 3. Target version: Currently targeting PHP 8.6 (master branch). Is this > appropriate? > > 4. Deprecation period: Should we emit E_DEPRECATED in 8.5 and fatal error > in 9.0? Or accept the break immediately? (Deprecation adds engine > complexity and delays benefit.) > > == Prior Art == > > * Symfony: Uses this pattern in core components > * PHP.net Manual: Documents EnumValuesTrait approach > * TypeScript: Object.values(Enum) > * Python: [e.value for e in Enum] > * myclabs/php-enum: Had values() method (4.9k stars) > > == Next Steps == > > If feedback is generally positive, I will: > 1. Request RFC karma > 2. Create formal RFC on wiki.php.net <http://wiki.php.net/> > 3. Address any concerns raised in this discussion > 4. Move to formal voting after discussion period > > == Implementation Details == > > For those interested in the technical details, the PR includes: > * Core implementation in zend_enum.c > * Stub file updates > * Comprehensive test coverage (9 test files) > * Reflection support > * Documentation in NEWS and UPGRADING > > PR: https://github.com/php/php-src/pull/20398 > > Looking forward to your feedback! > > Best regards, Savin Mikhail > GitHub: @savinmikhail
Hey, Thanks for this! I would love to see this in core. > 2. Method name: values() matches community usage (3,860+ examples) and > parallels cases(). Alternatives like getValues() or toArray() were > considered but seem inferior. Thoughts? `values()` > 1. BC break acceptability: Given the scope and straightforward migration, > is this break acceptable? > 3. Target version: Currently targeting PHP 8.6 (master branch). Is this > appropriate? > > 4. Deprecation period: Should we emit E_DEPRECATED in 8.5 and fatal error > in 9.0? Or accept the break immediately? (Deprecation adds engine > complexity and delays benefit.) Perhaps the smoothest way would be to allow from 8.6 redeclaring `values()`, in the same time deprecate it and break it later (9.0)? Cheers
