rize/uri-template
RFC 6570 URI Template implementation for PHP. Expand templates into URLs and extract variables from matching URIs. Supports all expression types/levels, path segment and query expansions, plus base URI and default parameters—handy for building API endpoints.
% modifier for nested arrays (e.g., list[]=a&list[]=b) and strict mode for extraction add flexibility for complex query parameters, common in analytics or data export tools.Route service provider or middleware for URI validation.require in composer.json with no build steps or configuration overhead.url("/users/{id}") → $uri->expand("/users/{id}", ["id" => 1]))./search/{term}).~0.3.x (supports PHP 7.1+), but lose type safety and PHP 8.4+ compatibility.?list[]=a&list[]=b).~0.3.x if PHP 8.1 is unavailable, but monitor for security updates.route("users.show", ["id" => 1])) or augment it (e.g., for third-party API clients)?~0.3.x?filter[user][role]=admin) or custom modifiers beyond RFC 6570?UrlGenerator or Symfony’s Uri component suffice? (This package adds RFC 6570 compliance and extraction.)// Before
$client->get("https://api.example.com/users/{$id}");
// After
$uri = new UriTemplate();
$client->get($uri->expand("https://api.example.com/users/{id}", ["id" => 1]));
$template = "/search/{term}/{?limit}";
$uri = new UriTemplate();
$params = $uri->extract($template, request()->getPathInfo());
config/api_templates.php) and reuse across services.'google_cloud' => [
'base' => 'https://{region}-{service}.googleapis.com/{version}',
'defaults' => ['version' => 'v1'],
],
UriTemplate expansion.// Before
$url = "https://api.stripe.com/v1/customers/{$customerId}/subscriptions";
// After
$uri = new UriTemplate("https://api.stripe.com/{version}", ["version" => "v1"]);
$url = $uri->expand("/customers/{id}/subscriptions", ["id" => $customerId]);
public function handle(Request $request, Closure $next) {
$template = "/products/{category}/{?page,limit}";
$params = (new UriTemplate())->extract($template, $request->getPathInfo());
if ($params === null) {
abort(404);
}
return $next($request->merge($params));
}
UriTemplate for all URI construction.class ApiClient {
protected UriTemplate $uri;
public function __construct(string $baseTemplate, array $defaults = []) {
$this->uri = new UriTemplate($baseTemplate, $defaults);
}
public function buildUrl(string $template, array $vars = []): string {
return $this->uri->expand($template, $vars);
}
}
$params = $uri->extract("/users/{id:[0-9]+}", $request->path(), strict: true);
if ($params === null) {
abort(400, "Invalid user ID format");
}
$this->app->singleton(UriTemplate::class, fn() => new UriTemplate());
$client = new Client();
$response = $client->get($uri->expand("/search/{term}", ["term" => "laravel"]));
?page=1&limit=10).~0.3.x if using older PHP.How can I help you explore Laravel packages today?