Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. UriResolver.php

function UriResolver::relativize

Returns the target URI as a relative reference from the base URI.

This method is the counterpart to resolve():

(string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))

One use-case is to use the current request URI as base URI and then generate relative links in your documents to reduce the document size or offer self-contained downloadable document archives.

$base = new Uri('http://example.com/a/b/'); echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.

This method also accepts a target that is already relative and will try to relativize it further. Only a relative-path reference will be returned as-is.

echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well

File

vendor/guzzlehttp/psr7/src/UriResolver.php, line 128

Class

UriResolver
Resolves a URI reference in the context of a base URI and the opposite way.

Namespace

GuzzleHttp\Psr7

Code

public static function relativize(UriInterface $base, UriInterface $target) : UriInterface {
    if ($target->getScheme() !== '' && ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')) {
        return $target;
    }
    if (Uri::isRelativePathReference($target)) {
        // As the target is already highly relative we return it as-is. It would be possible to resolve
        // the target with `$target = self::resolve($base, $target);` and then try make it more relative
        // by removing a duplicate query. But let's not do that automatically.
        return $target;
    }
    if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
        return $target->withScheme('');
    }
    // We must remove the path before removing the authority because if the path starts with two slashes, the URI
    // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also
    // invalid.
    $emptyPathUri = $target->withScheme('')
        ->withPath('')
        ->withUserInfo('')
        ->withPort(null)
        ->withHost('');
    if ($base->getPath() !== $target->getPath()) {
        return $emptyPathUri->withPath(self::getRelativePath($base, $target));
    }
    if ($base->getQuery() === $target->getQuery()) {
        // Only the target fragment is left. And it must be returned even if base and target fragment are the same.
        return $emptyPathUri->withQuery('');
    }
    // If the base URI has a query but the target has none, we cannot return an empty path reference as it would
    // inherit the base query component when resolving.
    if ($target->getQuery() === '') {
        $segments = explode('/', $target->getPath());
        
        /** @var string $lastSegment */
        $lastSegment = end($segments);
        return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
    }
    return $emptyPathUri;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal