Hi Màté,
As always I tried to implement a polyfill for the Percent-Encoding and
Decoding Support RFC. Turns out while doing so I was able to refactor the
enum. Of note, the case names are the one used in the text and *NOT* in the
Enum example provided as they differ. I will update the names once you have
updated them.
Here's my alternate proposal for Uri\Rfc3986. Keep in mind that the same
reasoning would apply for the Uri\Whatwg counterpart.
namespace Uri\Rfc3986 {
enum UriComponent
{
case UserInfo;
case Host;
case Path;
case PathSegment;
case AbsolutePathReferenceFirstSegment;
case RelativePathReferenceFirstSegment;
case Query;
case FormQuery;
case Fragment;
case AllReservedCharacters;
case AllButUnreservedCharacters;
/** * @throws InvalidUriException */
public function encode(string $input): string;
/** * @throws InvalidUriException */
public function decode(string $input): string;
}
}
As previously stated, I added the encode/decode method in the Enum this way
the feature is fully handled by the Enum and no direct reference to the Uri
class via a static method is done.
The Enum is renamed *UriComponent* instead of the current
*UriPercentEncodingMode
*the name change highlights the intent of the Enum encoding and decoding
URI component, where each enum case represents a defined component context.
Both methods may trigger an exception (I do not know if specific exceptions
like UnableToEncodeException and/or UnableToDecodeException should be added
but, for now, the generic InvalidUriException is used.
This rewrite also greatly simplifies the Enum usage.
Below you will see your examples from the RFC rewritten
- Decoding the fragment
$uri = new Uri\Rfc3986\Uri("https://example.com#_%40%2F");
$fragment = $uri->getFragment(); // returns "_%40%2F"
echo Uri\Rfc3986\UriComponent::Fragment->decode($fragment); //returns
"_%40/"
- Decoding the query
//with the query component
$uri = new Uri\Rfc3986\Uri("https://example.com/?q=%3A%29");
$query = $uri->getQuery(); // returns "q=%3A%29"
echo Uri\Rfc3986\UriComponent::Query->decode($query); //returns "q=:)"
- Usage with the new Uri::withPathSegments method
$uri = new Uri\Rfc3986\Uri("https://example.com");
$uri = $uri->withPathSegments([
"foo",
Uri\Rfc3986\UriComponent::PathSegment->decode("bar/baz")
]);
$uri->toRawString(); // https://example.com/foo/bar%2Fbaz
Let me know what you think,
regards,
Ignace
On Tue, Mar 3, 2026 at 10:24 AM ignace nyamagana butera <[email protected]>
wrote:
> Hi Máté,
>
> I just re-read the RFC and I like the updates and precision you've brought
> to it here's my review:
> For the builders I have nothing more design wise to add this is already
> solid. I may nitpick on the *Builder::clear() method name I would have gone
> with *Builder::reset() but I presume other developers would go with clear.
> Other than that the public API is spot on.
>
> For the Enum, my only concern is that they serve just as flags and their
> usage is tightly coupled to the Uri classes. I would add 2 static named
> constructors fromUrl and tryFromUrl just for completeness. I believe the
> maintenance cost is negligible but the developer DX is improved and allows
> for a broader usage of the Enum.
>
> In regards to the path segments usage and constructor I see you already
> integrate my Enum suggestions and you have explained why a fully
> fledged class is not the right approach. So the current design is already
> solid.
>
> Last but not least, The Percent encoding feature should be IMHO improved
> by moving the encode/decode methods from being static methods on the URI
> classes to becoming public API on the Enum. This would indeed imply
> renaming the enum from Uri\Rfc3986\UriPercentEncodingMode to
> Uri\Rfc3986\UriPercentEncoder with two methods encode/decode. Again it
> makes for a more self-contained feature and adds to the DX. Developer will
> not have to always statically call the URI classes for encoding/decoding
> strings as the Enums and their cases already convey the information
> correctly.
>
> Overall I believe this is going into the right direction
>
> Regards,
> Ignace
>
>
> On Sun, Mar 1, 2026 at 11:09 PM Máté Kocsis <[email protected]>
> wrote:
>
>> Hey Ignace et al,
>>
>> I have updated the RFC in the past few weeks with a lot of extra info,
>> mostly related to path segment handling: I investigated WHATWG URL's
>> behavior more thoroughly, and it turned out that path segments are
>> handled very interestingly, so there was a significant difference compared
>> to RFC 3986 yet again.
>>
>> Please give the RFC another read, if possible.
>>
>> Regards,
>> Máté
>>
>>