Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calling Uri::__toString() leads to unexpected object comparison result #622

Open
pawelbaranski opened this issue Mar 12, 2025 · 0 comments

Comments

@pawelbaranski
Copy link

pawelbaranski commented Mar 12, 2025

Description
calling a __toString() getter, changes the Uri object state, which makes == comparison for Uri object unreliable. That is essentially a BC break in my opinion.

How to reproduce

use GuzzleHttp\Psr7\Uri;

$uri1 = new Uri('http://test.com');
$uri2 = new Uri('http://test.com');

var_dump($uri1 == $uri2); //true

$uri2->__toString();

var_dump($uri1 == $uri2); //false

Possible Solution

it is caused by composedComponents that is used to store the value of resolved uri, and it is done lazy, on first call.

public function __toString(): string
{
    if ($this->composedComponents === null) {
        $this->composedComponents = self::composeComponents(
            $this->scheme,
            $this->getAuthority(),
            $this->path,
            $this->query,
            $this->fragment
        );
    }

    return $this->composedComponents;
}

I see two solutions:

  • either do not store that value, somewhat on behalf of the client, and make the client store it if he needs to have it resolved
  • or resolve it in __constructor

Additional Context

I am in the middle of migration to newer php version, and I needed to update guzzlehttp/psr7 package and ended up fixing the codebase as we have == comparison used on Uri objects, thankfully there were tests that also broke so was not a surprise on production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant