Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129123 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 98BE31A00BC for ; Fri, 7 Nov 2025 04:05:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762488353; bh=LCNr7OiJtPMFwSrdOR6ePLgSpVtxTQ89SOcspF5Ls1E=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Ug01eviiifw+k4ohQcvTnhq7/XbhIw8bXzc56jEJxEvdISceZvK8GBY/B3CZi1nfj WeSS9OkQeqr40SgqOc51iziLcBh8PtPSi3oiOlT8jJBvlyjSVrvy6ItbIcpaBgEN+Z yrVvheqcCVIArm4wEySIZ8VSbK3tzuADvhWQzLRuA9ilHp8dk+bFq6StX9FFEIfGsv fgsrGF27WwZZciLTvcGnWnf8tkdkgiAyPo/9VFNvlkcIWobRkgjYKu03wLyph5jH9w JkyaeWHVHM7mL3sZR62C2n7ICFxILAwFw9w5RAFerIWvXvMRhC/z2pH7l9i1NLBr+O 8Fvl0Ndn+IElg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0D97518004F for ; Fri, 7 Nov 2025 04:05:49 +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.7 required=5.0 tests=BAYES_05,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, T_SPF_TEMPERROR autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 ; Fri, 7 Nov 2025 04:05:48 +0000 (UTC) Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-47754e9cc7fso1819685e9.2 for ; Thu, 06 Nov 2025 20:05:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762488342; x=1763093142; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=pZJNf/6fuwhW/VrGWg6KfGTf3C/E4ZOrwzDTco1PUsI=; b=KzUJJSRV9j1fJrLkwEsfjL8OP+6tcsLxNSsP/VlERmNT3jBrE35IGU6ThxXzxk3nrY uEW81qL1BUFTPAzLdXcmmEQvsfynbzWzYqaEZKSVmqb3RmGZJ0TzL0J+kmfthmN+x6bX e3tE18q5taDukpkuGFscgsE4q6L6kptg5c8gqOvlZh7Plbi8R0lt5h8Kofq2wLv5RjsS uSD9lQPXTcFhuQJ0ABOUrNdmPju722YIYMYxYX5tQHUl3sBufGQSVjUzlBveddjhX7KR Oc4f88/rOrlKFgAfknx7jGXVvjjRKktCgcmHAc1VgZXxkPDd+BDeX8sYT36tXVo3lT1s FuHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762488342; x=1763093142; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=pZJNf/6fuwhW/VrGWg6KfGTf3C/E4ZOrwzDTco1PUsI=; b=op7grBaQEH2PLrlIvPpT8+zGNXm0BlBzuejiFgAQDK5fbAvEqP5SwvyaQ+MlS4f3Dh gm1NYYnr6oG6pAn8sJIl1qn+ScF+pQPdcuzF5oBPJqbYxUTBLegctwu4059ZeatWKDBH r5cJ5VgVuM18pJ7lilbwsPbZrCx6PGPpeFejAS3VQBvromTK87rJBazPoKJfO4ZXK+dI nk/fco5yjmUCJjd+tfA9ltLy16jyHrbssowIPQuGq+iABsOQBlt2u7QqXQ0pVLelBjkr YohYtB3cDFiCd3ZsL5t7djJi47RilyDM1imsNaHgvpvw1ZCan7E+rfhZKJdfXQhLIvoA tawg== X-Gm-Message-State: AOJu0YzW27/aTQUq0PvC6K3doSuuH/E1+ix1Ph9TpTW9eTfyXBZjeRpg bIn6MPnnf+1JA7uiLzS3Fh/voI9xze7SbiFE2UiiwVbdAgIigAP36UxM03v15IIWcYl0B1Yf5wV eAsSSCd4t/Y1QpBvlx4Ujq2UkzLNDXqPWBkvNug== X-Gm-Gg: ASbGnct2cRNg7BYKjyWLZBTGnDgUlcXtmgWHcSFzDfiGIIrwrzi+oazIccsyXM6LBoL yOEzQtVUUT/1K8zLDm4eA4wh6DH1ImBgcBSJS8lPbePFgeh/jJgaN+oWBQXaSXcS9gs3ygD1/tq 8uAnVuFSNvjPoYI3cWeaeBPO9e9/Q0yRJ5gZkrjlGKnXb1ywAlJpwl2mlCxHVd8XNxqKjOoi1D6 4E7cvSd4QQQw7e4dJd53b0idWaagOv/FHJAZCCrwqZfIZvrTSxpJJGn4xB1 X-Google-Smtp-Source: AGHT+IFcL87VhtOJTyYXxGWJVdgTROYk0kKDRwILOGb6/NIYzTcClRoR6l/Y5SfPYXNunYxRgT7ObOGwhncputlEFjw= X-Received: by 2002:a05:600c:1381:b0:477:fad:acd9 with SMTP id 5b1f17b1804b1-4776bcc5191mr15572255e9.34.1762488342007; Thu, 06 Nov 2025 20:05:42 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 7 Nov 2025 08:05:30 +0400 X-Gm-Features: AWmQ_bnFGhOEzOVIK92bP8NNe6dSYKGFZ-Yq0-Mo0g5tr9j-hCjgcNoU2Rh3sIc Message-ID: Subject: Re: [PHP-DEV] [RFC] [Discussion] BackedEnum::values() - Seeking feedback before formal RFC To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="0000000000008bd3500642f94b17" From: udaltsov.valentin@gmail.com (Valentin Udaltsov) --0000000000008bd3500642f94b17 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable =D1=87=D1=82, 6 =D0=BD=D0=BE=D1=8F=D0=B1. 2025=E2=80=AF=D0=B3., 19:30 Larry= Garfield : > On Wed, Nov 5, 2025, at 10:09 PM, Mikhail Savin wrote: > > Hi internals, > > > > I would like to propose adding a native values() method to the BackedEn= um > > 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 trai= ts > > * Used in major frameworks: Symfony core (TypeIdentifier.php), > > Laravel ecosystem > > * Documented by PHP.net: The manual itself shows EnumValuesTrait as > > an example > > Correction: The manual does not show an EnumValuesTrait that I can find. > There is a *comment* in the manual that includes this method, but that's > not part of the manual proper, and frankly 90% of comments in the manual > should be removed. (cf: > https://www.php.net/manual/en/language.enumerations.traits.php#129250) > > > 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 > > I am unclear why this is a major advantage over > array_column(Status::cases(), 'value'); > > > =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 > > This is a hard-stop. There are hundreds of thousands of packages in the > wild that need to support multiple PHP versions. Nearly all packaglist > packages (which I presume is where you're drawing the research from; eith= er > that or GitHub which will give a similar result set) support at least two > consecutive versions, if not 4, 5, or 6. > > A hard break like this would essentially mean the packages containing > those 40,000 enums would be unable to support both PHP 8.5 and 8.6 at the > same time. That's simply not an acceptable impact on the ecosystem, > regardless of how nice the feature may or may not be. > > --Larry Garfield > We could add a virtual $values property. Since enum properties are not allowed in userland, it will not break any existing code. =E2=80=94 Valentin > --0000000000008bd3500642f94b17 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
=D1=87=D1=82, 6 =D0=BD=D0=BE=D1=8F=D0= =B1. 2025=E2=80=AF=D0=B3., 19:30 Larry Garfield <larry@garfieldtech.com>:
O= n Wed, Nov 5, 2025, at 10:09 PM, Mikhail Savin wrote:
> Hi internals,
>
> I would like to propose adding a native values() method to the BackedE= num
> 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:
>
>=C2=A0 =C2=A0 =C2=A0interface BackedEnum {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0public static function values(): arra= y;
>=C2=A0 =C2=A0 =C2=A0}
>
> This would allow:
>
>=C2=A0 =C2=A0 =C2=A0enum Status: string {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case Active =3D 'active';
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case Inactive =3D 'inactive';=
>=C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0 =C2=A0Status::values(); // ['active', 'inacti= ve']
>
> =3D=3D Motivation =3D=3D
>
> This pattern is extremely common in the wild. Based on GitHub code sea= rch:
>
>=C2=A0 =C2=A0* ~3,860+ direct implementations of this exact pattern
>=C2=A0 =C2=A0* ~20,000-40,000 estimated real usage when accounting for = shared traits
>=C2=A0 =C2=A0* Used in major frameworks: Symfony core (TypeIdentifier.p= hp),
>=C2=A0 =C2=A0 =C2=A0Laravel ecosystem
>=C2=A0 =C2=A0* Documented by PHP.net: The manual itself shows EnumValue= sTrait as
>=C2=A0 =C2=A0 =C2=A0an example

Correction: The manual does not show an EnumValuesTrait that I can find.=C2= =A0 There is a *comment* in the manual that includes this method, but that&= #39;s not part of the manual proper, and frankly 90% of comments in the man= ual should be removed.=C2=A0 (cf: https://www.php.net/manual/en/language.enumerations.traits.ph= p#129250)

> Common use cases:
>=C2=A0 =C2=A0* Database migrations: $table->enum('status', S= tatus::values())
>=C2=A0 =C2=A0* Form validation: $validator->rule('status', &= #39;in', Status::values())
>=C2=A0 =C2=A0* API responses: ['allowed_statuses' =3D> Statu= s::values()]
>
> =3D=3D Implementation =3D=3D
>
> I have a working implementation with tests:
> https://github.com/php/php-src/pull/20398
>
> The implementation:
>=C2=A0 =C2=A0* Mirrors the existing cases() method structure
>=C2=A0 =C2=A0* Extracts the value property from each case
>=C2=A0 =C2=A0* Returns an indexed array (0, 1, 2, ...)
>=C2=A0 =C2=A0* Only available on BackedEnum, not UnitEnum
>=C2=A0 =C2=A0* All tests pass

I am unclear why this is a major advantage over array_column(Status::cases(= ), 'value');

> =3D=3D Backward Compatibility - Important Discussion Point =3D=3D
>
> This is a breaking change. Enums that already define a values() method=
> will fail with:
>
>=C2=A0 =C2=A0 =C2=A0Fatal error: Cannot redeclare BackedEnum::values()<= br> >
> Based on ecosystem research:
>=C2=A0 =C2=A0* ~24,000-44,000 enum instances will break
>=C2=A0 =C2=A0* All implementations are functionally identical to what&#= 39;s being proposed
>=C2=A0 =C2=A0* Migration is mechanical: just delete the user-defined me= thod

This is a hard-stop.=C2=A0 There are hundreds of thousands of packages in t= he wild that need to support multiple PHP versions.=C2=A0 Nearly all packag= list packages (which I presume is where you're drawing the research fro= m; either that or GitHub which will give a similar result set) support at l= east two consecutive versions, if not 4, 5, or 6.

A hard break like this would essentially mean the packages containing those= 40,000 enums would be unable to support both PHP 8.5 and 8.6 at the same t= ime.=C2=A0 That's simply not an acceptable impact on the ecosystem, reg= ardless of how nice the feature may or may not be.

--Larry Garfield


--0000000000008bd3500642f94b17--