The Hierarchical Path component
The library provides a League\Uri\Components\HierarchicalPath
class to ease complex path manipulation on a Hierarchical URI object like http
scheme URI. The class extends the default Path
object with methods dedicated to manipulate hierarchical paths.
Path creationΒΆ
Using the default constructor
Just like any other component, a new League\Uri\Components\HierarchicalPath
object can be instantiated using its default constructor.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$absolute_path = new Path('/hello/world');
echo $absolute_path; //display '/hello/world'
$relative_path = new Path('hello/world');
echo $relative_path; //display 'hello/world'
$end_slash = new Path('hello/world/');
echo $end_slash; //display 'hello/world/'
Using a League Hierarchical Uri object
<?php
use League\Uri\Schemes\Http as HttpUri;
$uri = HttpUri::createFromString('http://uri.thephpleague.com/path/to/here');
$path = $uri->path; // $path is a League\Uri\Components\HierarchicalPath object;
Using a named constructor
A path is a collection of segment delimited by the path delimiter /
. So it is possible to create a HierarchicalPath
object using a collection of segments with the HierarchicalPath::createFromSegments
method.
The method expects at most 2 arguments:
- The first required argument must be a collection of segments (an
array
or aTraversable
object) - The second optional argument, a
Uri\Path
constant, tells whether this is a rootless path or not:HierarchicalPath::IS_ABSOLUTE
: the created object will represent an absolute path;HierarchicalPath::IS_RELATIVE
: the created object will represent a rootless path;
<?php
use League\Uri\Components\HierarchicalPath as Path;
$relative_path = Path::createFromSegments(['shop', 'example', 'com']);
echo $relative_path; //display 'shop/example/com'
$absolute_path = Path::createFromSegments(['shop', 'example', 'com'], Path::IS_ABSOLUTE);
echo $absolute_path; //display '/shop/example/com'
$end_slash = Path::createFromSegments(['shop', 'example', 'com', ''], Path::IS_ABSOLUTE);
echo $end_slash; //display '/shop/example/com/'
Path representationsΒΆ
String representation
Basic path representations is done using the following methods:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/windows/My Documents 100%20/foo.txt');
$path->getUriComponent(); //return '/windows/My%20Documents%20100%20/foo.txt'
$path->__toString(); //return '/windows/My%20Documents%20100%20/foo.txt'
$path->getContent(); //return '/windows/My%20Documents%20100%20/foo.txt'
Array representation
A path can be represented as an array of its internal segments. Through the use of the HierarchicalPath::getSegments
method the class returns the object array representations.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->getSegments(); //return ['path', 'to', 'the', 'sky'];
$absolute_path = new Path('/path/to/the/sky/');
$absolute_path->getSegments(); //return ['path', 'to', 'the', 'sky', ''];
$relative_path = new Path('path/to/the/sky/');
$relative_path->getSegments(); //return ['path', 'to', 'the', 'sky', ''];
Accessing Path contentΒΆ
Countable and IteratorAggregate
The class provides several methods to works with its segments. The class implements PHPβs Countable
and IteratorAggregate
interfaces. This means that you can count the number of segments and use the foreach
construct to iterate overs them.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
count($path); //return 4
foreach ($path as $offset => $segment) {
//do something meaningful here
}
Segment offsets
If you are interested in getting all the segments offsets you can do so using the HierarchicalPath::keys
method like shown below:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->keys(); //return [0, 1, 2, 3];
$path->keys('sky'); //return [3];
$path->keys('gweta'); //return [];
The method returns an array containing all the segments offsets. If you supply an argument, only the offsets whose segment value equals the argument are returned.
To know If an offset exists before using it you can use the HierarchicalPath::hasKey
method which returns true
or false
depending on the presence or absence of the submitted $offset
in the current object.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->hasKey(2); //return true
$path->hasKey(23); //return false
Segment content
If you are only interested in a given segment you can access it directly using the HierarchicalPath::getSegment
method as show below:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->getSegment(0); //return 'path'
$path->getSegment(23); //return null
$path->getSegment(23, 'now'); //return 'now'
The method returns the value of a specific offset. If the offset does not exists it will return the value specified by the optional second argument or null
.
The basename
To ease working with path you can get the trailing segment of a path by using the HierarchicalPath::getBasename
method, this method takes no argument. If the segment ends with an extension, it will be included in the output.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->getBasename(); //return 'sky'
$alt_path = new Path('path/to/the/sky.html');
$alt_path->getBasename(); //return 'sky.html'
The basename extension
If you are only interested in getting the basename extension, you can directly call the HierarchicalPath::getExtension
method. This method, which takes no argument, returns the trailing segment extension as a string if present or an empty string. The leading .
delimiter is removed from the method output.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$path->getBasename(); //return ''
$path = new Path('/path/to/file.csv');
$path->getExtension(); //return 'csv';
The getExtension
method takes into account path parameters:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky.txt;foo=bar,baz');
$path->getBasename(); //return 'sky.txt;foo=bar,baz'
$path->getExtension(); //return 'txt';
The dirname
Conversely, you can get the path dirname by using the HierarchicalPath::getDirname
method, this method takes no argument and works like PHPβs dirname
function.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky.txt');
$path->getExtension(); //return 'txt'
$path->getBasename(); //return 'sky.txt'
$path->getDirname(); //return '/path/to/the'
Path normalizationΒΆ
Out of the box, the HierarchicalPath
object operates a number of non destructive normalizations. For instance, the path is correctly URI encoded against the RFC3986 rules.
Modifying PathΒΆ
Path extension manipulation
You can easily change or remove the extension from the path basename using the HierarchicalPath::withExtension
method.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$newPath = $path->withExtension('csv');
echo $newPath->getExtension(); //displays csv;
echo $path->getExtension(); //displays '';
Append segments
To append segments to the current object you need to use the HierarchicalPath::append
method. This method accept a single argument which represents the data to be appended. This data can be a string, an object which implements the __toString
method or another HierarchicalPath
object:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path();
$newPath = $path->append(new Path('path'))->append('to/the/sky');
$newPath->__toString(); //return path/to/the/sky
Prepend segments
To prepend segments to the current path you need to use the HierarchicalPath::prepend
method. This method accept a single argument which represents the data to be prepended. This data can be a string, an object which implements the __toString
method or another HierarchicalPath
object:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path();
$newPath = $path->prepend(new Path('sky'))->prepend(new Path('path/to/the'));
$newPath->__toString(); //return path/to/the/sky
Replace segments
To replace a segment you must use the HierarchicalPath::replace
method with the following arguments:
$offset
which represents the segment offset to remove if it exists.$data
which represents the data to be inject. This data can be a string, an object which implements the__toString
method or anotherHierarchicalPath
object.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/foo/example/com');
$newPath = $path->replace(0, new Path('bar/baz'));
$Path->__toString(); //return /bar/baz/example/com
Remove segments
To remove segments from the current object and returns a new HierarchicalPath
object without them you must use the HierarchicalPath::without
method. This method expects a single argument. This argument is an array containing a list of parameter names to remove.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/path/to/the/sky');
$newPath = $path->without([0, 1]);
$newPath->__toString(); //return '/the/sky'
Filter segments
You can filter the HierarchicalPath
object using the HierarchicalPath::filter
method. Filtering is done using the same arguments as PHPβs array_filter
.
You can filter the path according to its segments values:
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/foo/bar/yolo/');
$newPath = $path->filter(function ($value) {
return ! empty($value);
}, Path::FILTER_USE_VALUE);
echo $newPath; //displays '/foo/bar/yolo'
You can filter the path according to its segments key.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/foo/bar/yolo/');
$newPath = $query->filter(function ($value) {
return 1 != $value;
}, Path::FILTER_USE_KEY);
echo $newPath; //displays '/foo/yolo'
You can filter the path according to its segment value and key.
<?php
use League\Uri\Components\HierarchicalPath as Path;
$path = new Path('/foo/bar/yolo/');
$newPath = $query->filter(function ($value, $key) {
return 1 != $key && strpos($value, 'l') !== false;
}, Path::FILTER_USE_KEY);
echo $newPath; //displays '/yolo'
By specifying the second argument flag you can change how filtering is done:
- use
HierarchicalPath::FILTER_USE_VALUE
to filter according to the segment value; - use
HierarchicalPath::FILTER_USE_KEY
to filter according to the segment offset; - use
HierarchicalPath::FILTER_USE_BOTH
to filter according to the segment value and offset;
By default, if no flag is specified the method will filter the query using the HierarchicalPath::FILTER_USE_VALUE
flag.