Skip to content

URI objects

Greg Bowler edited this page Apr 24, 2026 · 2 revisions

GT\Http\Uri is the package's PSR-7 URI implementation.

Working with URIs as objects is usually safer than repeatedly splitting strings by :, /, ?, and #. The object keeps the parts separate and gives you a consistent way to inspect and replace them.

Create a URI

use GT\Http\Uri;

$uri = new Uri("https://user:pass@example.com:8080/path/123?q=abc#test");

Then read whichever part you need:

echo $uri->getScheme();   // https
echo $uri->getAuthority(); // user:pass@example.com:8080
echo $uri->getUserInfo();  // user:pass
echo $uri->getHost();      // example.com
echo $uri->getPort();      // 8080
echo $uri->getPath();      // /path/123
echo $uri->getQuery();     // q=abc
echo $uri->getFragment();  // test

Build a URI gradually

$uri = new Uri()
	->withScheme("https")
	->withHost("example.com")
	->withPath("/articles")
	->withQuery("page=2");

As with other PSR-7 objects, each with...() method returns a new instance.

Query helpers

This implementation adds a couple of convenience methods beyond the base PSR-7 interface:

  • getQueryValue()
  • withQueryValue()
  • withoutQueryValue()
$uri = new Uri("https://example.com/search?q=phpgt&page=2");

echo $uri->getQueryValue("q"); // phpgt

$nextPage = $uri->withQueryValue("page", "3");
$withoutPage = $uri->withoutQueryValue("page");

Relative and reference-style URIs

The class supports more than fully qualified HTTP URLs. It also handles:

  • relative references such as ./images/logo.svg
  • network-path references such as //example.org
  • query-only references such as ?page=2
  • fragment-only references such as #section

That is useful when your application works with both absolute URLs and relative references in the same codebase.

Default ports

isDefaultPort() tells you whether the port matches the default for the current scheme.

This matters because https://example.com:443/ and https://example.com/ usually mean the same endpoint.

URI resolution

For relative-reference work, GT\Http\UriResolver can resolve one URI against another.

use GT\Http\UriResolver;

$base = new Uri("https://example.com/docs/start/");
$relative = new Uri("../api");

$absolute = (new UriResolver())->resolve($base, $relative);
echo $absolute; // https://example.com/docs/api

URI creation from parsed parts

If you already have a parse_url() style array, UriFactory can turn it back into a Uri.

use GT\Http\UriFactory;

$parts = parse_url("https://example.com/a?b=c");
$uri = (new UriFactory())->createFromParts($parts);

Validation

Invalid URIs throw UriParseErrorException, and invalid port numbers throw PortOutOfBoundsException.

That is helpful because URI mistakes are usually easier to fix at construction time than after they have spread through an application.


Requests and responses both rely on headers, so head to the next page covering Working with headers.

Clone this wiki locally