Please consider using the the latest stable version for any production code.

Modifying URIs

If the modifications do not alter the current object, it is returned as is, otherwise, a new modified object is returned.

The method may throw a InvalidArgumentException exception if the resulting URI is not valid for a scheme specific URI.

Basic modifications

To completely replace one of the URI part you can use the modifying methods exposed by all URI object

<?php

public Uri::withScheme(string $scheme): self
public Uri::withUserInfo(string $user [, string $password = null]): self
public Uri::withHost(string $host): self
public Uri::withPort(int|null $port): self
public Uri::withPath(string $path): self
public Uri::withQuery(string $query): self
public Uri::withFragment(string $fragment): self

Since All URI object are immutable you can chain each modifying methods to simplify URI creation and/or modification.

<?php

use League\Uri\Schemes\Ws as WsUri;

$uri = WsUri::createFromString("ws://thephpleague.com/fr/")
    ->withScheme("wss")
    ->withUserInfo("foo", "bar")
    ->withHost("www.example.com")
    ->withPort(81)
    ->withPath("/how/are/you")
    ->withQuery("foo=baz");

echo $uri; //displays wss://foo:bar@www.example.com:81/how/are/you?foo=baz

URI modifiers

Often what you really want is to partially update one of the URI component. Using the current public API it is possible but requires several intermediary steps. For instance here’s how you would update the query string from a given URI object:

<?php

use League\Uri\Components\Query;
use League\Uri\Schemes\Http as HttpUri;

$uri = HttpUri::createFromString("http://www.example.com?foo=toto#~typo");
$uriQuery = new Query($uri->getQuery());
$updateQuery = $uriQuery->merge("foo=bar&taz=");
$newUri = $uri->withQuery($updateQuery->__toString());
echo $newUri; // display http://www.example.com?foo=bar&taz#~typo

URI modifiers principles

<?php

function(Psr\Http\Message\UriInterface $uri): Psr\Http\Message\UriInterface
//or
function(League\Uri\Interfaces\Uri $uri): League\Uri\Interfaces\Uri

To ease these operations the package introduces the concept of URI modifiers

A URI modifier:

Let’s recreate the above example using a URI modifier.

<?php

use League\Uri\Components\Query;
use League\Uri\Interfaces\Uri;
use Psr\Http\Message\UriInterface;

$mergeQuery = function ($uri) {
    if (!$uri instanceof Uri && !$uri instanceof UriInterface) {
        throw new InvalidArgumentException(sprintf(
            'Expected data to be a valid URI object; received "%s"',
            (is_object($uri) ? get_class($uri) : gettype($uri))
        ));
    }
    $currentQuery = new Query($uri->getQuery());
    $updatedQuery = $currentQuery->merge('foo=bar&taz')->__toString();

    return $uri->withQuery($updatedQuery);
};

And now the code becomes:

<?php

use League\Uri\Schemes\Http as HttpUri;

$uri = HttpUri::createFromString("http://www.example.com?foo=toto#~typo");
$newUri = $mergeQuery($uri);
echo $newUri; // display http://www.example.com?foo=bar&taz#~typo

The anonymous function $mergeQuery is an rough example of a URI modifier. The library League\Uri\Modifiers\MergeQuery provides a better and more suitable implementation.

URI Modifiers can be grouped for simplicity in different categories that deals with