Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129656 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 E61BD1A00BC for ; Fri, 19 Dec 2025 07:59:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1766131196; bh=stLKhymAndiFSX4l2XJHQJUgfVzusN2A0Z2PtgBSCbw=; h=References:In-Reply-To:From:Date:Subject:To:From; b=Oo4jm1HnogySIRfqbBAaK3V8eKMmIa+lr/OWVurrJRY6ndqeI2oWe+HQLrvWD6/oV M2QTe14TjhHKiStMMG7dj6EeHS4FM+EVy1sqLQ5WOd2SqirSAGAZTd1mHqV9xzVzWz mxN46j6FL/6q9EDRIYV2aNHhfCBJ4grzev5aP18SMXmKfcavUBhYhNPfTNmeoUWOzM kPuWFIBqOmx9iDFDTutJtiqmmWDx5UVib6kvo4eeR20PHZsVxt4rjMiHDboCdVklhM VjTgG8x6EyGXm4OKoxSBzUk6W0pS2syEVqTeijbmh1e3NGC5ML8s4Z3zAQIzW+H7MJ Pi5RqL+8r3Ueg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 577DB180072 for ; Fri, 19 Dec 2025 07:59:55 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-oa1-f52.google.com (mail-oa1-f52.google.com [209.85.160.52]) (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, 19 Dec 2025 07:59:55 +0000 (UTC) Received: by mail-oa1-f52.google.com with SMTP id 586e51a60fabf-3f11ad6e76fso1297036fac.1 for ; Thu, 18 Dec 2025 23:59:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766131189; x=1766735989; darn=lists.php.net; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=4fYUXwXk+ObR1OGYFsdvH52ymXhr7QLWG+8pokXtaYw=; b=Q/4IJOaQTA+r3afIUjXojZCgOVWSK6gOYzzFCdecWGOeWU+2W65qROpMhL4pLxBzZN H5japgIYTZ9xxuj0ky4N2+SG9SWgWqWYYTaaKLzmu9kOcoWo6EfbtQzcv9bEw5xrLpBF tNNC0h0BpHIv+MApF6NW6gJI50+6+jGHwsisGw+VqlRcBMzFd1cPKl4Sa0f5WDoRAX6Y EXmEtnOh2i6whE9NTrjbsOu6Ed92qTgzMt4d7yp7i0s6nG9PtJ1NkwupyilkF8rbtEWA gMkZ5/8wpoTUHDQpt2xPvZkCHM34LH3XakZF/1WetV2fN/6oL7JcdR3OU4ZsL4M68gZi fWWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766131189; x=1766735989; h=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=4fYUXwXk+ObR1OGYFsdvH52ymXhr7QLWG+8pokXtaYw=; b=S1hv+FIEO4hm34AYt1R2M26Yo+greZK7i6Zf6Q69Q1eyfQjT4uIH2tfXKudjBxrhp9 As8nI/Q6hg7gBfqkZ8D+d4UliwgJ+eniS/OAE/Q965ZyVSZ9+hGwKI7SCRccn8TJOQUN COmZz3FW3chE0k9hcREkmHyLah7mgqmwphH502B2SjHo2GtuL+xmqoPzleTH6RQLN0yA K46CFz3FgwaqQ1Bd9+GG8Zhva7Wr9apHzUZK+/i3XZvf7bFmr1S5aHXlTCJOdn8XYpak 5yg2DjcqUxnOMpC7bNF9h2HMh6LG5UfVvwl+fxkySKosSZnwN7AnICIXFPU2Tf1hGHbv /jYA== X-Forwarded-Encrypted: i=1; AJvYcCXNr1iQ6k7riwGlNJfbCClrD4fC/UDaxQ36MvMvLOkxixxPE2Q/xzBGFaiK7eaas+o+dQuKPqEnDqA=@lists.php.net X-Gm-Message-State: AOJu0YyPdJiYE+CkWZiwMs/14GSXtHMHt8eBV+/KGD3v8qJ3MAx3nVN/ /TKb8SW6ToUgZfcQt/OfcYs3tWIVdYGm287cYJAVrdvG+GKwDZT8Y/Q2nkITDd7+NCyBZJvwuYj 3Tw6Xw2eOCBNCMTZd2SxsapziZRKRMuE= X-Gm-Gg: AY/fxX6/LxdEmAhVdz+gGJQDyfoEGu4LD9tUb7iBH7KxzSJTiJr2fSo8nRyMivIDwm1 3j8dptHMdNuWHSG7cuS/Zu6PhJUMxd6DW11zXrZBIK09DkNca3GukbjtK4TALftR/XIW2tYjDcH zAfglMYSThDS3UbcM9ybPHljeXvRlZWldMVeZfIgoBC2E3u7tbYNzDqBl3Vs4BVeurCi0CnFdVx vCnEV5M0K4JNRv6d+uWBrVC1ter8KBkEpOivzYUy6Nim5ZWbrSjlgZYkW4lT0UFbqQ5GEAfdZ8A VzBeo7HNgUYYUTqwqlEf9gFG5qujQQ== X-Google-Smtp-Source: AGHT+IHGkpOBn4WuwmZoU0MQ/fv6gjF7HWbzWKF866udN9czs4hqFxY5Y/TIgPG5Pw9Av5hihh/bT/yr7oJ8Ybwp6eo= X-Received: by 2002:a05:6820:162a:b0:659:9a49:9069 with SMTP id 006d021491bc7-65d0ea9711amr986419eaf.52.1766131189425; Thu, 18 Dec 2025 23:59:49 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <83238ad3-c844-4457-dfb3-11321787e022@php.net> In-Reply-To: Date: Fri, 19 Dec 2025 08:59:38 +0100 X-Gm-Features: AQt7F2pqL4q56EXnYZaNl4PMGP080AEYXr9CGCfoZDdCI2k6suIxmt2vvkwNfTI Message-ID: Subject: Re: [PHP-DEV] [RFC] [Discussion] Followup Improvements for ext/uri To: =?UTF-8?B?TcOhdMOpIEtvY3Npcw==?= , PHP Internals List Content-Type: multipart/alternative; boundary="0000000000002c28c00646497663" From: nyamsprod@gmail.com (ignace nyamagana butera) --0000000000002c28c00646497663 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Dec 18, 2025 at 10:46=E2=80=AFPM M=C3=A1t=C3=A9 Kocsis wrote: > Hi, > > The WHATWG URL living standard does the following: >> >> let url =3D new URL('https://example.com?debug&foo=3Dbar&debug=3D'); >> console.log( >> url.searchParams.toString(), //returns debug=3D&foo=3Dbar&debug=3D' >> ); >> >> the pair gets converted to ['debug' =3D> '']. The roundtrip does not >> conserve the query string as is but all key/pair (tuples) are present. >> > > Yes, confirmed. Unfortunately, WHATWG URL only supports string values, so > there's no way to support > query parameters without a key (e.g. ?debug) in the RFC implementation > either. :( > > On the other hand, the RFC 3986 implementation supports this notion, even > uriparser calls this out > in its documentation: > https://uriparser.github.io/doc/api/latest/index.html#querystrings. > > However, there are a few other problems which came up when I was updating > my implementation. > > 1.) Yesterday, I wrote that name mangling of the query params shouldn't > happen. However, as I realized, > it is still needed for non-list arrays, because the [..] suffix must be > added to their name: > > $params =3D new Uri\Rfc3986\UriQueryParams() > ->append("foo", [2 =3D> "bar", 4 =3D> "baz"]); > > echo $params->toRfc3986String(); // > foo%5B2%5D=3Dbar&foo%5B4%5D=3Dbaz > > var_dump($params->getFirst("foo")); // NULL > > Even though I appended params with the name "foo", no items can be > returned when calling getFirst(), > because of name mangling. > > 2.) I'm not really sure how empty arrays should be represented? PHP > doesn't retain them, and they are > simply skipped. But should we do the same thing? I can't really come up > with any other sensible behavior. > > $params =3D new Uri\Rfc3986\UriQueryParams() > ->append("foo", []); > > echo $params->toRfc3986String(); // ??? > > 3.) We wrote earlier that objects shouldn't be supported when creating > the query string from variables. But what about > backed enums? Support for them in http_build_query() was added not long > ago: https://github.com/php/php-src/pull/15650 > Should we support them, right? > > Regards, > M=C3=A1t=C3=A9 > > Hi M=C3=A1t=C3=A9 1.) Yesterday, I wrote that name mangling of the query params shouldn't > happen. However, as I realized, it is still needed for non-list arrays, because the [..] suffix must be > added to their name: When I talk about data mangling I am talking about this parse_str('foo.bar=3Dbaz', $params); var_dump($params); //returns ['foo_bar' =3D> 'baz'] The bracket is a PHP specificity and I would not change it now otherwise you introduce a huge BC break in the ecosystem for no particular gain IMHO. 2.) I'm not really sure how empty arrays should be represented? PHP doesn't > retain them, and they are > simply skipped. But should we do the same thing? I can't really come up > with any other sensible behavior. > $params =3D new Uri\Rfc3986\UriQueryParams() > ->append("foo", []); This to me should yield the same result as ->append('foo', null); as the array construct is only indicative of a repeating parameter name if there is no repeat then it means no data is attached to the name. 3.) We wrote earlier that objects shouldn't be supported when creating > the query string from variables. But what about > backed enums? Support for them in http_build_query() was added not long > ago: https://github.com/php/php-src/pull/15650 > Should we support them, right? This gave me a WTF? moment (sorry for the language). Why was this change added in PHP without a proper discussion in the internals or even an RFC because it sets up a lot of precedence and even changes how http_build_query is supposed to work in regards to objects. If this had landed on the internal list I would have objected to it on the ground as it breaks expectation in the function handling of type in PHP. Do I agree with everything the function does ? No, but introducing inconsistencies in the function is not a good thing. Now http_build_query is aware of specific objects. Sringable or Travarsable objects are not detected but Enum are ?? Pure Enum emits a TypeError but resource do not ? Backed Enums are not converted to int or to string by PDO ? Why would http_build_query do it differently ? The same reasoning apply as to why Backed Enum does not have a Stringable interface. Yes the output was "weird" in PHP8.1-> PHP8.3 but it was expected. Should something be done for DateInterval too because the output using http_build_query is atrocious ? I still stand on my opinion that objects, resources should NEVER be converted. In an ideal world only scalar + null and their repeated values encapsulated in an array should be allowed; everything else should be left to the developer to decide. So yes in your implementation I do think that Backed Enum should not be treated differently than others objects and should throw. PS: I would even revert this change or deprecated it for removal in PHP9 (in a separate RFC) Best regards, Ignace --0000000000002c28c00646497663 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Thu, Dec 18, 2025 at 10:46=E2=80=AFPM = M=C3=A1t=C3=A9 Kocsis <kocsism= ate90@gmail.com> wrote:
Hi,

The WHATWG URL living standard does the following:
<= div style=3D"color:rgb(8,8,8)">
let url =3D new URL('https://example.com?debug&foo=3Dbar&=
amp;debug=3D');
cons= ole.log(
url.searchParams.toString()= , //returns debug=3D&foo=3Dbar&debug=3D'
);
the pair gets converted to ['debug' =3D> '']. The r= oundtrip does not conserve the query string as is but all key/pair (tuples)= are present.

Yes,= confirmed. Unfortunately, WHATWG URL only supports string values, so there= 's no way to support
query parameters without a key (e.g. ?de= bug) in the RFC implementation either. :(

On the o= ther hand, the RFC 3986 implementation supports this notion,=C2=A0even urip= arser calls this out
in its documentation: = https://uriparser.github.io/doc/api/latest/index.html#querystrings.
=C2=A0
However, there are a few other problems which came = up when I was updating my implementation.

1.) Yest= erday, I wrote that name mangling of the query params shouldn't happen.= However, as I realized,
it is still needed for non-list arrays, = because the [..] suffix must be added to their name:

$params =3D new Uri\Rfc3986\UriQueryParams()
=C2=A0 =C2=A0 ->appen= d("foo", [2 =3D> "bar", 4 =3D> "baz"]);=

echo $params->toRfc3986String();=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // foo%5B2%5D=3Dbar&foo%5= B4%5D=3Dbaz

var_dump($params->getFirst("fo= o"));=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0// NULL

Even though I appended params with t= he name "foo", no items can be returned when calling getFirst(),<= /div>
because of name mangling.

2.) I'm no= t really sure how empty arrays should=C2=A0be represented? PHP doesn't = retain them, and they are
simply skipped. But should we do the sa= me thing? I can't really come up with any other sensible behavior.

$params =3D new Uri\Rfc3986\UriQueryParams()
=C2=A0= =C2=A0 ->append("foo", []);

echo $params->toRfc3986= String();=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 // ???

3.) We wrote earlier that object= s shouldn't be supported when creating the=C2=A0query string from varia= bles. But what about
backed enums? Support for them in http_build= _query() was added not long ago: https://github.com/php/php-src/pull/15650=
Should we support them, right?

Regards,=
M=C3=A1t=C3=A9

Hi M=C3=A1t=C3=A9=C2=A0

1.) Yesterday, I wrote that name mangling of the query = params shouldn't happen. However, as I realized,
it is still needed for non-list arr= ays, because the [..] suffix must be added to their name:=C2=A0

When I talk about data mangling I am talking about thi= s

parse_str('foo.bar=3Dbaz', $params);
var_dum= p($params); //returns ['foo_bar' =3D> 'baz']
<= br>
The bracket is a PHP specificity=C2=A0and I would not change = it now otherwise you introduce a huge BC break in the ecosystem
f= or no particular gain IMHO.

2.) I'm not really sure how empty arrays sh= ould=C2=A0be represented? PHP doesn't retain them, and they are
simp= ly skipped. But should we do the same thing? I can't really come up wit= h any other sensible behavior.
$params =3D new Uri\Rfc3986\UriQueryParam= s()
=C2=A0 =C2=A0 ->append("foo", []);
This to me should yield the same result as ->append('foo= ', null);=C2=A0 as the array construct is only indicative of a repeatin= g parameter name
if there is no repeat then it means no data is a= ttached to the name.=C2=A0

3.) We wrote earlier that objects shouldn&= #39;t be supported when creating the=C2=A0query string from variables. But = what about
backed enums? Support for them in http_build_query() was adde= d not long ago:=C2=A0https://github.com/php/php-src/pull/15650
Should w= e support them, right?

This gave me a WTF? = moment (sorry for the language). Why was this change added in PHP without a= proper discussion in the internals
or even an RFC because it set= s up a lot of precedence and even changes how http_build_query is supposed = to work in regards to objects.
If this had landed on the internal= list I would have objected to it on the ground as it breaks expectation in= the function handling of type in PHP.
Do I agree with everything= the function does ? No, but introducing inconsistencies in the function is= not a good thing. Now http_build_query
is aware of specific obje= cts. Sringable=C2=A0or Travarsable objects are not detected but Enum are ??= Pure Enum emits a TypeError but resource
do not ? Backed E= nums are not converted to int or to string by PDO ? Why would http_build_qu= ery do it differently=C2=A0? The same reasoning apply as to
why B= acked Enum does not have a Stringable interface.

Y= es the output was "weird" in PHP8.1-> PHP8.3 but it was expect= ed. Should something be done for DateInterval too because the
out= put using http_build_query is atrocious ?

I still = stand on my opinion that objects, resources should NEVER be converted. In a= n ideal world only scalar=C2=A0+ null and their repeated values
e= ncapsulated in an array should be allowed; everything else should be left t= o the developer to decide. So yes in your implementation I do think
that Backed Enum should not be treated differently than others objects a= nd should throw.

PS: I would even revert this chan= ge or deprecated it for removal in PHP9 (in a separate RFC)

<= /div>
Best regards,
Ignace

--0000000000002c28c00646497663--