Introduction
Windwalker Uri provides a PSR-7 UriInterface implementation for building, parsing, and rendering URLs. Most URLs in an application come from several sources: a configured base address, a route, user input, and a query built by code. Joining these pieces as strings is error-prone. This package treats a URI as a value object: each change returns a new instance, so a base URL can be shared between services without one of them altering it for the others.
The package has these main parts:
Uri: the PSR-7 URI value object. It parses a string, exposes its parts, and returns modified copies throughwith*()methods.ExtendedUriInterface: the interfaceUriimplements. It adds query variable helpers, user and password accessors, and native conversions.UriFactory: a PSR-17 factory that createsUriinstances.UriTemplate: an RFC 6570 URI Template withexpand()andextract(). It is an optional add-on that needs a template library.UriHelperandUriNormalizer: static helpers for query building, filtering, encoding, and path normalization.Uriuses them internally.
Installation
composer require windwalker/uri ^4.0The package requires PHP 8.4.6 or later. It depends on psr/http-message, psr/http-factory, and windwalker/utilities.
Use as Standalone Component
The Composer autoloader loads the package. Create a Uri from a string, change its parts, and render it:
use Windwalker\Uri\Uri;
$uri = new Uri('https://example.com/search?q=php');
$uri = $uri->withVar('page', 2)
->withFragment('results');
echo $uri;
// https://example.com/search?q=php&page=2#resultsEach with*() call returns a new instance, so the original stays unchanged. Read the Uri page for the full model.
For a PSR-17 factory, use UriFactory:
use Windwalker\Uri\UriFactory;
$uri = new UriFactory()->createUri('https://example.com/api');Use in Windwalker
The Uri package does not register services in the DI container, so there is nothing to inject. Create a Uri where you need it and pass it on as a value. The same code works inside a Windwalker application and outside one:
use Windwalker\Uri\Uri;
class CallbackUrlBuilder
{
public function build(string $token): string
{
$uri = new Uri('https://example.com/callback')
->withVar('token', $token);
return (string) $uri;
}
}When a value may already be a PSR-7 URI, such as the URI of a request message, or may be null, pass it to Uri::wrap(). It returns the same instance for a Uri and converts other values:
$uri = Uri::wrap($request->getUri());If a library asks for a PSR-17 UriFactoryInterface, create a UriFactory directly with new UriFactory().
Core Concepts
A Uri keeps the scheme, user information, host, port, path, query, and fragment as separate parts. Reading a part never changes the URI, and rendering it with __toString() or toString() always rebuilds the string from those parts. Query data is kept in two forms: the encoded query string and an array of decoded variables, which withVar() and withoutVar() keep in sync.
withPath(), withQuery(), and withVar() filter and encode the values they receive. withPathAppend() is the exception and appends the suffix as given. The Uri page explains the difference.
Topic Pages
- Uri: creating, reading, and modifying URIs, query variables, rendering with selected parts, and native conversions.
- URI Template: building URLs from RFC 6570 templates, and extracting variables from an incoming URL.
- Helpers: the static encoding, filtering, and path normalization helpers that the package uses internally.