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é
>>
>>

Reply via email to