Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129110 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 95ADD1A00BC for ; Thu, 6 Nov 2025 06:01:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762408905; bh=N6DcGRaNcdKj7u8+5Bz7/q4brccbpMdIYLYT8LZEsXI=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=K4b1EyY5bsokJG7C/zOPINiv3TtNxCaoX3TTxrv4XjUAR9Ru2K544L6YAIEUbonoB gZkQDh1pUNqRHyxTvENzeRGADQg55TKNFtGTBFqr22luHS86ZTl7D6nJdsctzW043J otINPFyM/2fU5TKm0ZYYpUBm/aCtP3y4Tygs+maHIrsSXGqSD9i4ik3MnoTJMuDN85 gIezMuZZaHZtXLrXkohgp/9xQYB5lV3mEP5Xcxouu+23Yut9zRc50lSXOSCqAg21SU LO7snPjDAk6+0ozjWRcJOML0kBzw1/hbtHAKRycAnZY2uKAW/NTPFpSpJ3iyyz7mvC KE/Jyo8pcRTPA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 96F54180078 for ; Thu, 6 Nov 2025 06:01:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_40,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,HTML_MESSAGE, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from www589.your-server.de (www589.your-server.de [162.55.254.28]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 6 Nov 2025 06:01:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nicksdot.dev; s=default2508; h=References:To:Cc:In-Reply-To:Date:Subject: Mime-Version:Content-Type:Message-Id:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=4eq6JZGnsypkr9ewHAwIMNnQkD4SDucOLrxSlNPAPyo=; b=Vu43joiTZt7eP6Ao1Pd3GW9TPw Sk0s4a5VT1uOmUzzFVzAoTvZWKOXSYDpLdskr8ErGysdHzHKPNj0HLuEnFkfYfZZwH2GJmAHoyTyJ Hx5OMRNnWbdmM0sPOeF00zCoruPNVIa/P3rqnWalUZPOcab3qorg7fsm38HY2uwCG7LK9WOvddJCU 3W/BlIi0ZXmKcHZX02igP3oDIblzfM/EPWsfdiObFKZBz0IddDRMQMv8cDRfHpLLPcsoKD65Y6PbH z92oTZpgrcYnu/dTuryQYwucp5h2TnuYhSqRoviKyTutVX+PuOPZ5p5N/gy21rI1Kb0cxJGESd+B1 WSASg7cg==; Received: from sslproxy04.your-server.de ([78.46.152.42]) by www589.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1vGt3w-000JpQ-0Q; Thu, 06 Nov 2025 07:01:36 +0100 Received: from localhost ([127.0.0.1]) by sslproxy04.your-server.de with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vGt3v-0006RP-21; Thu, 06 Nov 2025 07:01:35 +0100 Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_C6F97A0E-05AA-4B74-BAAB-C21C2A4F77C7" Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.700.81\)) Subject: Re: [PHP-DEV] [RFC] [Discussion] BackedEnum::values() - Seeking feedback before formal RFC Date: Thu, 6 Nov 2025 13:01:22 +0700 In-Reply-To: Cc: internals@lists.php.net To: Mikhail Savin References: X-Mailer: Apple Mail (2.3826.700.81) X-Virus-Scanned: Clear (ClamAV 1.0.9/27814/Wed Nov 5 11:44:40 2025) From: php@nicksdot.dev (Nick) --Apple-Mail=_C6F97A0E-05AA-4B74-BAAB-C21C2A4F77C7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On 6. Nov 2025, at 11:09, Mikhail Savin = wrote: >=20 > Hi internals, >=20 > 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. >=20 > =3D=3D Summary =3D=3D >=20 > The proposal adds: >=20 > interface BackedEnum { > public static function values(): array; > } >=20 > This would allow: >=20 > enum Status: string { > case Active =3D 'active'; > case Inactive =3D 'inactive'; > } > =20 > Status::values(); // ['active', 'inactive'] >=20 > =3D=3D Motivation =3D=3D >=20 > This pattern is extremely common in the wild. Based on GitHub code = search: >=20 > * ~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 >=20 > Common use cases: > * Database migrations: $table->enum('status', Status::values()) > * Form validation: $validator->rule('status', 'in', = Status::values()) > * API responses: ['allowed_statuses' =3D> Status::values()] >=20 > =3D=3D Implementation =3D=3D >=20 > I have a working implementation with tests: > https://github.com/php/php-src/pull/20398 >=20 > 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 >=20 > =3D=3D Backward Compatibility - Important Discussion Point =3D=3D >=20 > This is a breaking change. Enums that already define a values() method > will fail with: >=20 > Fatal error: Cannot redeclare BackedEnum::values() >=20 > 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 >=20 > The break is justified because: >=20 > 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 >=20 > =3D=3D Questions for Discussion =3D=3D >=20 > 1. BC break acceptability: Given the scope and straightforward = migration, > is this break acceptable? >=20 > 2. Method name: values() matches community usage (3,860+ examples) and > parallels cases(). Alternatives like getValues() or toArray() were > considered but seem inferior. Thoughts? >=20 > 3. Target version: Currently targeting PHP 8.6 (master branch). Is = this > appropriate? >=20 > 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.) >=20 > =3D=3D Prior Art =3D=3D >=20 > * 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) >=20 > =3D=3D Next Steps =3D=3D >=20 > If feedback is generally positive, I will: > 1. Request RFC karma > 2. Create formal RFC on wiki.php.net > 3. Address any concerns raised in this discussion > 4. Move to formal voting after discussion period >=20 > =3D=3D Implementation Details =3D=3D >=20 > 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 >=20 > PR: https://github.com/php/php-src/pull/20398 >=20 > Looking forward to your feedback! >=20 > 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? >=20 > 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 --Apple-Mail=_C6F97A0E-05AA-4B74-BAAB-C21C2A4F77C7 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii
On 6. Nov = 2025, at 11:09, Mikhail Savin <mikhail.d.savin@gmail.com> = 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.

=3D=3D Summary = =3D=3D

The proposal adds:

    interface = BackedEnum {
        public static function = values(): array;
    }

This would = allow:

    enum Status: string {
    =     case Active =3D 'active';
        = case Inactive =3D 'inactive';
    }
  =  
    Status::values(); // ['active', = 'inactive']

=3D=3D Motivation =3D=3D

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' =3D> Status::values()]

=3D=3D = Implementation =3D=3D

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

=3D=3D Backward Compatibility - Important Discussion Point = =3D=3D

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

=3D=3D Questions for Discussion = =3D=3D

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.)

=3D=3D Prior Art =3D=3D

  * 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)

=3D=3D Next Steps =3D=3D

If feedback is generally = positive, I will:
  1. Request RFC karma
  2. Create = formal RFC on wiki.php.net
  3. Address any concerns = raised in this discussion
  4. Move to formal voting after = discussion period

=3D=3D Implementation Details =3D=3D

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

Lo= oking forward to your feedback!

Best regards, Savin = Mikhail
GitHub: @savinmikhail
=

Hey,

Thank= s 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()`
<= br>
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

= --Apple-Mail=_C6F97A0E-05AA-4B74-BAAB-C21C2A4F77C7--