Oihana PHP

path

Table of Contents

Functions

canonicalizePath()  : string
Converts any given path to a **canonical, absolute‑style** representation.
computeRelativePath()  : string
Computes the relative path between two normalized relative paths.
directoryPath()  : string
Returns the directory part of the path.
extractCanonicalParts()  : array<string|int, string>
Extracts the canonical path segments of « $pathWithoutRoot ».
isAbsolutePath()  : bool
Determines whether a given path is absolute.
isBasePath()  : bool
Checks whether a given canonical path **lies inside** a base directory.
isLocalPath()  : bool
Determines whether the given path refers to a local file system location.
isRelativePath()  : bool
Determines whether a given path is relative.
joinPaths()  : string
Concatenates multiple path fragments into a single canonical path.
makeAbsolute()  : string
Turns a relative path into an absolute path in canonical form.
makeRelative()  : string
Turns an absolute path into a path relative to another absolute path.
normalizePath()  : string
Normalizes the given file system path by replacing backslashes with slashes.
realpathParent()  : string
Resolves a path's parent and leaves its last segment as it stands.
relativePath()  : string
Returns the relative path from a base path to a target path.
splitPath()  : array<string|int, string>
Splits a **canonical** filesystem path into two parts: 1. **Root** : the protocol / drive / leading slash portion 2. **Remainder** : the sub‑path that follows

Functions

canonicalizePath()

Converts any given path to a **canonical, absolute‑style** representation.

canonicalizePath(string $path) : string

The algorithm:

  1. Early return / cache – looks up the path in a static LRU‑style buffer (see CanonicalizeBuffer).
  2. Home expansion – replaces a leading tilde ~ with the current user’s home directory (platform‑aware via getHomeDirectory()).
  3. Separator normalisation – back‑slashes ⇒ forward‑slashes via normalizePath().
  4. Root / remainder split – handled by splitPath().
  5. Dot & dot‑dot cleanup – collapses . and .. segments with extractCanonicalParts().
  6. Buffer write‑back – stores the result; periodically cleans the buffer after insertions.

No filesystem access is performed; non‑existent paths are allowed.

Parameters
$path : string

The path to canonicalise. May be relative or absolute, Windows or Unix, and may start with ~.

Tags
example
canonicalizePath('~/projects/../site//index.php');
// -> "/home/alice/site/index.php"   (Linux)

canonicalizePath('C:\\Temp\\..\\Logs\\.');
// -> "C:/Logs"
see
normalizePath()
splitPath()
extractCanonicalParts()
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

Canonicalised path with forward slashes and no redundant . / .. segments.

computeRelativePath()

Computes the relative path between two normalized relative paths.

computeRelativePath(string $targetPath, string $basePath) : string
Parameters
$targetPath : string

The target relative path.

$basePath : string

The base relative path.

Tags
example
echo computeRelativePath( 'foo/bar/baz' , 'foo'     ) . PHP_EOL; // 'bar/baz'
echo computeRelativePath( 'foo/baz'     , 'foo/bar' ) . PHP_EOL; // '../baz'
echo computeRelativePath( 'foo/bar'     , 'foo/bar' ) . PHP_EOL; // '.'
echo computeRelativePath( 'a/b'         , 'a/b/c/d' ) . PHP_EOL; // '../..'
echo computeRelativePath( 'a/b/c'       , 'a'       ) . PHP_EOL; // 'b/c'
echo computeRelativePath( 'a/x/y'       , 'a/b/c'   ) . PHP_EOL; // '../../x/y'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

The relative path from base to target.

directoryPath()

Returns the directory part of the path.

directoryPath(string $path) : string

This function normalizes and extracts the parent directory from a file path. It handles edge cases not covered by PHP's built-in dirname(), such as:

  • Preserving trailing slashes in Windows root paths (e.g., "C:/")
  • Correctly handling URI schemes (e.g., "file:///path/to/file")
  • Supporting UNC (network) paths on Windows (e.g., "\server\share\folder")
  • Returning an empty string when no directory is applicable

This method is similar to PHP's dirname(), but handles various cases where dirname() returns a weird result:

  • dirname() does not accept backslashes on UNIX
  • dirname("C:/symfony") returns "C:", not "C:/"
  • dirname("C:/") returns ".", not "C:/"
  • dirname("C:") returns ".", not "C:/"
  • dirname("symfony") returns ".", not ""
  • dirname() does not canonicalize the result

This method fixes these shortcomings and behaves like dirname() otherwise.

The result is a canonical path.

Parameters
$path : string

The file path from which to extract the directory.

Tags
example

Unix-style paths

directoryPath('/var/www/html/file.txt'); // Returns '/var/www/html'

Windows-style paths

directoryPath('C:\Windows\System32\file.txt'); // Returns 'C:\Windows\System32'
directoryPath('D:/Program Files/My App/file.txt'); // Returns 'D:/Program Files/My App'

Paths with URI schemes

directoryPath('file:///home/user/doc.txt'); // Returns '/home/user'

Edge cases

directoryPath('file.txt'); // Returns ''
directoryPath(''); // Returns ''
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

The directory part of the path, or an empty string if no directory can be extracted.

extractCanonicalParts()

Extracts the canonical path segments of « $pathWithoutRoot ».

extractCanonicalParts(string $root, string $pathWithoutRoot) : array<string|int, string>

This method breaks down the input path into segments, and processes them to remove:

  • Redundant current directory references (.)
  • Properly resolvable parent references (..)

It does not access the filesystem and works purely on string logic.

Parameters
$root : string

The base root path. Used to determine whether .. segments can be collapsed. If empty, leading .. segments will be preserved.

$pathWithoutRoot : string

The input path (already stripped of the root part).

Tags
example
extractCanonicalParts('/var/www', 'project/../cache/./logs')
// Returns: ['cache', 'logs']

extractCanonicalParts('', '../../folder')
// Returns: ['..', '..', 'folder']
note

This function does not validate that the resulting path actually exists.

author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
array<string|int, string> —

An array of canonical path segments.

isAbsolutePath()

Determines whether a given path is absolute.

isAbsolutePath(string $path) : bool

This function checks for both UNIX-style absolute paths (starting with "/") and Windows-style absolute paths (e.g., "C:", "C:/", or just "C:"). It also handles paths with URI schemes like "file://" by stripping the scheme before analysis.

Parameters
$path : string

The path to check.

Tags
example

Unix-style paths

isAbsolutePath('/var/www'); // true

Windows-style paths

isAbsolutePath('C:\\Users\\Test'); // true
isAbsolutePath('D:/folder/file.txt'); // true
isAbsolutePath('C:'); // true
isAbsolutePath('\\network-share\folder'); // true

Paths with schemes

isAbsolutePath('file:///c/Users/'); // true

Relative paths

isAbsolutePath('documents/report.pdf'); // false
isAbsolutePath('../images/pic.jpg'); // false
isAbsolutePath('file.txt'); // false

Edge cases

isAbsolutePath(''); // false
isAbsolutePath('/'); // true
isAbsolutePath('C:/'); // true
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool —

True if the path is absolute, false otherwise.

isBasePath()

Checks whether a given canonical path **lies inside** a base directory.

isBasePath(string $basePath, string $childPath) : bool

The comparison is done purely on canonicalized strings (see canonicalizePath()); the filesystem is not consulted.

Algorithm

  1. Canonicalize both $basePath and $ofPath.
  2. Right–trim the base (to avoid double slash issues).
  3. Append a trailing slash to both and use str_starts_with() to ensure the whole first segment matches – preventing false positives like /var/www-legacy being considered inside /var/www.
Parameters
$basePath : string

The supposed ancestor directory.

$childPath : string

The child path to test.

Tags
example
isBasePath( '/var/www' , '/var/www/site/index.php' ); // true
isBasePath( '/var/www' , '/var/www' );                // true (exact match)
isBasePath( '/var/www' , '/var/www-legacy' );         // false
isBasePath( 'C:/Users' , 'C:/Users/Bob/file.txt') ;   // true (Windows)
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool —

True if childPath is equal to or contained in basePath.

isLocalPath()

Determines whether the given path refers to a local file system location.

isLocalPath(string $path) : bool

A path is considered "local" if:

  • It is not empty.
  • It does not contain a URL-like scheme (e.g. http://, ftp://, s3://, etc.).

This function uses a lightweight string check to detect the presence of ://, which is common in remote paths or stream wrappers.

Parameters
$path : string

The path to check. Can be relative, absolute, or URL-style.

Tags
example
isLocalPath('/var/log/app.log');     // true
isLocalPath('C:\\Users\\Admin');     // true
isLocalPath('https://example.com');  // false
isLocalPath('s3://my-bucket/file');  // false
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool —

True if the path is local; false if it looks like a remote or virtual path.

isRelativePath()

Determines whether a given path is relative.

isRelativePath(string $path) : bool

A path is considered relative if it is not absolute. This function is the direct inverse of isAbsolutePath(). It will return true for paths that do not start with a slash, a backslash, or a Windows drive letter.

Parameters
$path : string

The path to check.

Tags
see
isAbsolutePath()
example
// Relative paths (returns true)
var_dump( isRelativePath( 'documents/report.pdf' ) ) ; // true
var_dump( isRelativePath( '../images/pic.jpg'    ) ) ; // true
var_dump( isRelativePath( 'file.txt'             ) ) ; // true
var_dump( isRelativePath( ''                     ) ) ; // true (empty path)

// Absolute paths (returns false)
var_dump( isRelativePath( '/var/www'             ) ) ; // false
var_dump( isRelativePath( 'C:\\Users\\Test'      ) ) ; // false
var_dump( isRelativePath( 'D:/folder/'           ) ) ; // false
var_dump( isRelativePath( 'C:'                   ) ) ; // false
var_dump( isRelativePath( 'file:///c/Users/'     ) ) ; // false
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool —

True if the path is relative, false if it is absolute.

joinPaths()

Concatenates multiple path fragments into a single canonical path.

joinPaths(string ...$paths) : string

Behaviour rules

  1. Empty segments ('') are ignored.
  2. The first non‑empty segment is kept “as‑is” so a leading slash, drive letter (C:/), or scheme (phar://) is preserved.
  3. Every subsequent segment is joined with exactly one forward‑slash (/) separator – unless the previous fragment already ends with / or \.
  4. After assembly, the result is passed through canonicalizePath() to normalise slashes and collapse . / ...
  5. If all fragments are empty, an empty string is returned.

⚠ Type‑hint fix – the function returns a string, not a bool. The signature has been updated accordingly.

Parameters
$paths : string

Arbitrary number of path fragments. May contain Unix, Windows or URL‑style segments.

Tags
example
joinPaths('/var', 'log', 'app.log');
// → '/var/log/app.log'

joinPaths('C:\\', 'Temp', '..', 'Logs');
// → 'C:/Logs'

joinPaths('phar://archive.phar', '/sub', '/file.php');
// → 'phar://archive.phar/sub/file.php'

joinPaths('', 'relative', 'path');   // leading blanks ignored
// → 'relative/path'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

Canonical, joined path (or empty string).

makeAbsolute()

Turns a relative path into an absolute path in canonical form.

makeAbsolute(string $path, string $basePath) : string

This function joins a relative path with an absolute base path to create a new absolute path. It also canonicalizes the result, which means:

  • Dot segments ("." and "..") are resolved.
  • All directory separators are converted to forward slashes ("/").
  • Redundant slashes are removed.

If the provided path is already absolute, it is simply canonicalized and returned, ignoring the base path.

The function correctly handles URI schemes (like "phar://" or "vfs://") by preserving the scheme from the base path in the final result.

Parameters
$path : string

The path to resolve. Can be relative or absolute.

$basePath : string

The absolute base path. Must not be empty.

Tags
throws
InvalidArgumentException

If the base path is empty or not an absolute path.

author

Marc Alcaraz (ekameleon)

since
1.0.0
example
// Basic usage with a Unix-style path
makeAbsolute('documents/../project/file.txt', '/home/user');
// => '/home/user/project/file.txt'

// Usage with a Windows-style path
makeAbsolute('data\\.\\config.ini', 'C:\\Users\\Test');
// => 'C:/Users/Test/data/config.ini'

// When the path is already absolute, the base path is ignored
makeAbsolute('/etc/app.conf', '/var/www');
// => '/etc/app.conf'

// Correctly handles URI schemes
makeAbsolute('src/bootstrap.php', 'phar:///usr/local/bin/composer.phar');
// => 'phar:///usr/local/bin/composer.phar/src/bootstrap.php'
Return values
string —

The resulting absolute path in canonical form.

makeRelative()

Turns an absolute path into a path relative to another absolute path.

makeRelative(string $path, string $basePath) : string
Parameters
$path : string

The absolute path to convert.

$basePath : string

The absolute path to which the conversion should be relative.

Tags
throws
InvalidArgumentException

If paths cannot be compared (e.g., different roots, or not absolute).

example
// --- Basic Unix cases ---

// The target path is a subdirectory
makeRelative('/var/www/project/app', '/var/www/project');
// => 'app'

// Navigating to a parent then to a sibling directory
makeRelative('/var/www/assets', '/var/www/project/app');
// => '../../assets'

// The paths are identical
makeRelative('/var/www', '/var/www');
// => ''

// --- Specific cases ---

// Navigating from the root directory
makeRelative('/home/user/documents', '/');
// => 'home/user/documents'

// Example with a Windows path
makeRelative('C:/Users/Test/Documents', 'C:/Users/Test/Downloads');
// => '../Documents'

// Example with a URI scheme (phar)
makeRelative('phar:///app/src/controller', 'phar:///app/src/model');
// => '../controller'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

The relative path.

normalizePath()

Normalizes the given file system path by replacing backslashes with slashes.

normalizePath(string $path) : string

This function is useful to unify path separators across different operating systems. It ensures all directory separators are forward slashes (/), making the path suitable for consistent comparison, storage, or manipulation.

It does not resolve relative components like . or .., nor does it canonicalize or validate the path against the filesystem.

Parameters
$path : string

The path to normalize. Can contain mixed or inconsistent separators.

Tags
example
normalizePath('C:\\Users\\myuser\\Documents');
// Returns: 'C:/Users/myuser/Documents'

normalizePath('/var/www/html');
// Returns: '/var/www/html'
see
realpath()

For actual filesystem canonicalization.

author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

The normalized path with all backslashes (\) replaced by forward slashes (/).

realpathParent()

Resolves a path's parent and leaves its last segment as it stands.

realpathParent(string $path) : string

realpath() answers for the whole path, which is too much when the last segment is the thing being judged: a symbolic link would be replaced by what it points at, and a path that does not exist would answer false. This resolves everything above the last segment — so a linked ancestor cannot hide where a path really leads — and keeps the last segment verbatim.

When the parent cannot be resolved, because it does not exist, the path is canonicalized lexically instead: there is nothing on disk to ask.

Parameters
$path : string

The path to resolve.

Tags
example
use function oihana\files\path\realpathParent;

// On macOS, where /var is a link to /private/var:
realpathParent( '/var/folders/x/T' ) ; // '/private/var/folders/x/T'

// The parent is the filesystem root, and the result carries one separator, not two:
realpathParent( '/tmp' ) ;             // '/tmp'

// A link is kept as itself, never followed:
symlink( '/elsewhere' , '/tmp/pointer' ) ;
realpathParent( '/tmp/pointer' ) ;     // '/tmp/pointer'
author

Marc Alcaraz (ekameleon)

since
1.6.0
Return values
string —

The path with its parent resolved and its last segment untouched.

relativePath()

Returns the relative path from a base path to a target path.

relativePath(string $path, string $basePath) : string

Both paths must be of the same type (both absolute or both relative), and must share the same root (e.g., same drive letter on Windows). The result is a canonical relative path.

Parameters
$path : string

The target path.

$basePath : string

The base path.

Tags
throws
InvalidArgumentException

If the paths are incompatible (e.g., absolute vs relative, or different roots).

example
echo relativePath( '/foo/bar/baz' , '/foo'     ) . PHP_EOL; // 'bar/baz'
echo relativePath( '/foo/baz'     , '/foo/bar' ) . PHP_EOL; // '../baz'
echo relativePath( '/foo/bar'     , '/foo/bar' ) . PHP_EOL; // '.'
echo relativePath( '/a/b'         , '/a/b/c/d' ) . PHP_EOL; // '../../'
echo relativePath( '/a/b/c'       , '/a'       ) . PHP_EOL; // 'b/c'
echo relativePath( '/a/x/y'       , '/a/b/c'   ) . PHP_EOL; // '../../x/y'

echo relativePath( 'foo/bar/baz'  , 'foo'     ) . PHP_EOL; // 'bar/baz'
echo relativePath( 'foo/baz'      , 'foo/bar' ) . PHP_EOL; // '../baz'
echo relativePath( 'foo/bar'      , 'foo/bar' ) . PHP_EOL; // '.'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string —

The relative path.

splitPath()

Splits a **canonical** filesystem path into two parts: 1. **Root** : the protocol / drive / leading slash portion 2. **Remainder** : the sub‑path that follows

splitPath(string $path) : array<string|int, string>

Supported patterns

Input example Returned root Returned remainder
/var/www/html / var/www/html
C:/Windows/System32 C:/ Windows/System32
C: C:/ (empty)
file:///home/user/docs file:/// home/user/docs
\\\\server\\share\\folder (UNC) // server/share/folder

Note : The input path is assumed to be canonical (slashes normalisés à /, pas de segments . ou ..). The function does not perform any filesystem checks.

Parameters
$path : string

Canonical path (absolute or relative, UNIX or Windows, with optional URL‑style scheme).

Tags
example
[$root, $rest] = splitPath('/etc/nginx/nginx.conf');
// $root = '/' | $rest = 'etc/nginx/nginx.conf'

[$root, $rest] = splitPath('C:/Program Files');
// $root = 'C:/' | $rest = 'Program Files'

[$root, $rest] = splitPath('C:');
// $root = 'C:/' | $rest = ''

[$root, $rest] = splitPath('file:///var/log');
// $root = 'file:///' | $rest = 'var/log'
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
array<string|int, string> —

An array with [0] => root, [1] => remainder. Both strings can be empty.

On this page

Search results