URI Template
The League\Uri\UriTemplate
class enables expanding a URI object based on a URI template and its
submitted parameters following RFC 6570 URI Template.
Template expansion
The UriTemplate::expand
public method expands a URI template to generate a valid URI conforming
to RFC3986.
<?php
use League\Uri\UriTemplate;
$template = 'https://example.com/hotels/{hotel}/bookings/{booking}';
$params = ['booking' => '42', 'hotel' => 'Rest & Relax'];
$uriTemplate = new UriTemplate($template);
$uri = $uriTemplate->expand($params); // instance of League\Uri\Uri
echo $uri; //display https://example.com/hotels/Rest%20%26%20Relax/bookings/42"
Template variables
Default variables can be set using the constructor
The constructor takes a optional set of default variables that can be applied by default when expanding the URI template.
$template = 'https://api.twitter.com/{version}/search/{term:1}/{term}/{?q*,limit}';
$params = [
'term' => 'john',
'q' => ['a', 'b'],
'limit' => '10',
];
$uriTemplate = new UriTemplate($template, ['version' => 1.1]);
echo $uriTemplate->expand($params);
//displays https://api.twitter.com/1.1/search/j/john/?q=a&q=b&limit=10
Applying variables with the expand method
The default variables are overwritten by those supplied to the expand
method.
$template = 'https://api.twitter.com/{version}/search/{term:1}/{term}/{?q*,limit}';
$params = [
'term' => 'john',
'q' => ['a', 'b'],
'limit' => '10',
'version' => '2.0'
];
$uriTemplate = new UriTemplate($template, ['version' => '1.1']);
echo $uriTemplate->expand($params), PHP_EOL;
//displays https://api.twitter.com/2.0/search/j/john/?q=a&q=b&limit=10
Updating the default variables
At any given time you may update your default variables but since the UriTemplate
is an immutable object instead of modifying the current instance, a new
instance with the modified default variables will be returned.
$template = 'https://api.twitter.com/{version}/search/{term:1}/{term}/{?q*,limit}';
$params = [
'term' => 'john',
'q' => ['a', 'b'],
'limit' => '10',
'version' => '2.0'
];
$uriTemplate = new UriTemplate($template, ['version' => '1.0', 'foo' => 'bar']);
$uriTemplate->getDefaultVariables(); //returns new VariableBag(['version' => '1.0'])
$newUriTemplate = $uriTemplate->withDefaultVariables(['version' => '1.1']);
$newUriTemplate->getDefaultVariables(); //returns new VariableBag(['version' => '1.1'])
$template = 'https://example.com/hotels/{hotel}/book{?query*}';
$params = [
'hotel' => 'Rest & Relax',
'query' => [
'period' => [
'start' => '2020-01-12',
'end' => '2020-01-15',
],
],
];
$uriTemplate = new UriTemplate($template);
$uriTemplate->expand($params);
// will throw a League\Uri\UriTemplate\TemplateCanNotBeExpanded when trying to expand the `period` value.
Using the prefix modifier on a list will trigger an exception.
While this is not forbidden by the RFC, the UriTemplate
class will throw an exception
if an attempt is made to use the prefix modifier with a list of value. Other
implementations will silently ignore the modifier but this package will
trigger the exception to alert the user that something might be wrong and
that the generated URI might not be the one expected.
$template = 'https://api.twitter.com/{version}/search/{term:1}/{term}/{?q*,limit}';
$params = [
'term' => ['john', 'doe'],
'q' => ['a', 'b'],
'limit' => '10',
'version' => '2.0'
];
$uriTemplate = new UriTemplate($template);
echo $uriTemplate->expand($params), PHP_EOL;
// throw a League\Uri\UriTemplate\TemplateCanNotBeExpanded because the term variable is a list and not a string.
Strict expansion with expandOrFail
By default, if variables are missing or are not provided an empty string is used as replacement
string as per the RFC. If you want to force correct expansion you can use the expandOrFail
method. It behaves exactly like the expand
method but will additionnally throw an
exception if there are missing required variables.
$template = 'https://api.twitter.com/{version}/search/{term}/{?q*,limit}';
$params = [
'term' => ['john', 'doe'],
'q' => ['a', 'b'],
'limit' => '10',
];
$uriTemplate = new UriTemplate($template);
echo $uriTemplate->expand($params), PHP_EOL;
// display https://api.twitter.com//search/john,doe/?q=a&q=b&limit=10 with missing version
echo $uriTemplate->expandOrFail($params);
// will throw a TemplateCanNotBeExpanded exception with the following message
// Missing variables `version`
Expressions
Using braces in your template
The following implementation disallow the use of braces {
or }
outside of being URI
template expression delimiters. If not used as the boundary of an expression an
exception will be triggered.
$template = 'https://example.com/hotels/{/book{?query*}';
$uriTemplate = new UriTemplate($template);
// will throw a League\Uri\Exceptions\SyntaxError on instantiation
If your template do require them you should URL encode them.
$template = 'https://example.com/hotels/%7B/{hotel}';
$params = ['booking' => 42, 'hotel' => 'Rest & Relax'];
$uriTemplate = new UriTemplate($template);
echo $uriTemplate->expand($params), PHP_EOL;
// https://example.com/hotels/%7B/Rest%20%26%20Relax