URN Value Object
The League\Uri\Urn is a specific class developped around URN creation and manipulation
as defined in RFC8141.
Instantiation
While the default constructor cannot be used as it is marked as private, the League\Uri\Urn provides several
named constructors to help creating a new instance.
use League\Uri\Urn;
$urn = Urn::new('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
$urnBis = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
$urnRfc2141 = Urn::fromRfc2141(nid: 'example', nss: 'animal:nose');
Urn::parse('invalid uri'); // returns null on failure
The new() method allows creating a new instance from an encoded string. The method is an alias of
the fromString() method. By default, the submitted URNs will be validated against RFC8141.
While both methods support strings, you can also use the new native URI classes as input, as well as
PSR-7 UriInterface implementing objects.
The fromRfc2141() named constructor allows creating URNs using the legacy RFC2141 rules.
While all the previous methods would throw a SyntaxError on malformed URN, the parse() method returns null
to enable using the method during input validation.
URN String Representation
The Urn class handles URI according to RFC8141, as such you can retrieve its string representation using
the toString method. the __toString() method is an alias of the toString() method.
$urn = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
echo $urn->toString(); // displays 'urn:example:animal:nose?+foo=bar&fo%26o=b%3Far'
echo $uri; // displays 'urn:example:animal:nose?+foo=bar&fo%26o=b%3Far'
An Urn instance can be JSON-encoded using its string representation to allow better interoperability with
Javascript.
$urn = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
json_encode($urn); //returns "urn:example:animal:nose?+foo=bar&fo%26o=b%3Far"
The toDisplayString() method returns a human-readable representation of the URI,
corresponding to its IRI form as defined in RFC 3987. Although the resulting
value may not constitute a syntactically valid URN, it is intended for
presentation purposes — for example, as the textual content of an HTML <a> element.
$urn = Urn::fromString('urn:example:%F0%9F%98%88');
echo $urn->toDisplayString(); // displays 'urn:example:😈'
The toRfc2141() returns the URN legacy representation from the obsolete RFC2141 specification.
$urn = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
echo $urn->toString(); // displays 'urn:example:animal:nose?+foo=bar&fo%26o=b%3Far'
echo $urn->toRfc2141(); // displays 'urn:example:animal:nose'
The optional components as defined by RFC8141 are stripped if present.
It is possible to convert your League\Uri\Urn instance into a League\Uri\Uri object using the
toUri() method. The method returns a League\Uri\Uri instance.
$urn = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
$uri = $urn->toUri(); // returns a League\Uri\Uri instance
$uri->equals($urn); // returns true
Accessing The URN properties
Let’s examine the result of building an URN:
use League\Uri\Urn;
$urn = Urn::fromString('urn:example:animal:ferret:nose?+weight=2.3;length=5.1?=profile=standard#section2');
echo $urn->getNid(); // displays 'example'
echo $urn->getNss(); // displays 'animal:ferret:nose'
echo $urn->getRComponent(); // displays 'weight=2.3;length=5.1'
echo $urn->getQComponent(); // displays 'profile=standard'
echo $urn->getFComponent(); // displays 'section2'
URN information
The components related properties r-component, q-component and f-component are optional, as such,
they can be null if they have no value or be a non-empty string. They can never be the empty string.
To ease gathering information about optional component presence the class exposes the following methods:
Urn::hasRComponent: returnstrueif the r-component value is notnull;Urn::hasQComponent: returnstrueif the q-component value is notnull;Urn::hasFComponent: returnstrueif the f-component value is notnull;Urn::hasOptionalComponent: returnstrueif at least one of the optional component is set;
$urn = Urn::fromString('urn:example:animal:nose?+foo=bar&fo%26o=b%3Far');
$urn->hasOptionalComponent(); // returns true
$urn->hasFComponent(); // returns false
$urn->hasRComponent(); // returns true
Modifying URN Properties
Use the modifying methods exposed by all URN instances to replace one of the URN part or component. If the modifications do not alter the current object, it is returned as is, otherwise, a new modified object is returned.
$urn = Urn::fromString('urn:example:animal:nose')
->withQComponent('foo=bar')
->withFComponent('fragment');
echo $urn->toString(); // returns 'urn:example:animal:nose?=foo=bar#fragment'
The following modifier methods exist:
withNid: will update the URN namespace identifier part;withNss: will update the URN namespace specific string part;withRComponent: will update the URNr-componentvalue;withQComponent: will update the URNq-componentvalue;withFComponent: will update the URNf-componentvalue;
Normalization and Comparison
Out-of-the-box, the only normalization that will occur it that the scheme will be lowercased to urn. But
you can improve normalization by lowercasing the URN NIS part. This is done if you call the normalize() method.
It will return a new instance fully normalized. This instance is used to compare URN.
use League\Uri\Urn;
use League\Uri\UrnComparisonMode;
$urn = Urn::fromString('UrN:Example:Animal:NOSE');
echo $urn; //returns "urn:Example:Animal:NOSE"
$newUrn = $urn->normalize();
echo $newUrn; //returns "urn:example:Animal:NOSE"
By default, when comparing two URN only the NIS and the NSS parts are considered as per the requirements of
the RFC. However, depending on the specificity of some URN namespace, the optional component may be used. To
cover both situations the UrnComparisonMode enum is used with the equals method.
use League\Uri\Urn;
use League\Uri\UrnComparisonMode;
$urn = Urn::fromRfc2141('example', 'animal:nose')->withQComponent('foo/bar');
$urnBis = Urn::fromRfc2141('example', 'animal:nose');
$urn->equals($urnBis, UrnComparisonMode::ExcludeComponents); // returns true
$urn->equals($urnBis, UrnComparisonMode::IncludeComponents); // returns false