PHPackages                             internal/path - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. internal/path

ActiveLibrary[File &amp; Storage](/categories/file-storage)

internal/path
=============

Type-safe, immutable file path library with cross-platform support and automatic normalization.

1.2.0(7mo ago)12117.0k↑30.5%[1 issues](https://github.com/php-internal/path/issues)[1 PRs](https://github.com/php-internal/path/pulls)3BSD-3-ClausePHPPHP &gt;=8.1CI passing

Since Dec 2Pushed 3w agoCompare

[ Source](https://github.com/php-internal/path)[ Packagist](https://packagist.org/packages/internal/path)[ Fund](https://boosty.to/roxblnfk)[ RSS](/packages/internal-path/feed)WikiDiscussions 1.x Synced yesterday

READMEChangelog (4)Dependencies (5)Versions (6)Used By (3)

Path helper for PHP
===================

[](#path-helper-for-php)

[![Support](https://camo.githubusercontent.com/92a5c9c142a4b40702e8f5905faa1afae6cfc4f79c417502e83bce1e2c90cf5f/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f7374796c653d666c61742d737175617265266c6162656c3d537570706f7274266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d253233666530303836)](https://boosty.to/roxblnfk)

A type-safe library for working with file system paths. Handles normalization, cross-platform compatibility, and all the edge cases with slashes and separators.

Path is an immutable value object – all methods return new instances, so it's safe to use as a DTO, pass between layers, or store in your domain models without worrying about side effects.

Installation
------------

[](#installation)

```
composer require internal/path
```

[![PHP](https://camo.githubusercontent.com/c8c9921f915fa245c798919a2f79b7625a6cebd3ccb1cb7083d5aba0ccbb8937/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f696e7465726e616c2f706174682e7376673f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://packagist.org/packages/internal/path)[![Latest Version on Packagist](https://camo.githubusercontent.com/3899c47827358ad65a1cef1dc3b15f3390443aa662ddd9009d7f9b41059bbc48/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e7465726e616c2f706174682e7376673f7374796c653d666c61742d737175617265266c6f676f3d7061636b6167697374)](https://packagist.org/packages/internal/path)[![License](https://camo.githubusercontent.com/5d6a9e0a0134c52f5c1de8c5a6891ac9246a3c8c828879b46d048fab1190614f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696e7465726e616c2f706174682e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Total Destroys](https://camo.githubusercontent.com/3347b477abf5c38d76ce3fd036846f0297810dd91fcdf0dba14f4db30724e714/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f696e7465726e616c2f706174682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/internal/path/stats)

Usage
-----

[](#usage)

### Creating paths

[](#creating-paths)

```
use Internal\Path;

// Create from string
$path = Path::create('/var/www/app');
$path = Path::create('src/helpers/utils.php');
```

### Joining paths

[](#joining-paths)

```
$base = Path::create('/var/www');
$full = $base->join('app', 'src', 'Controller.php');
// Result: /var/www/app/src/Controller.php

// Works with Path objects too
$subdir = Path::create('logs');
$logFile = $base->join($subdir, 'app.log');
```

### Working with path components

[](#working-with-path-components)

```
$file = Path::create('/home/user/documents/report.pdf');

$file->name();      // 'report.pdf'
$file->stem();      // 'report'
$file->extension(); // 'pdf'
$file->parent();    // Path('/home/user/documents')
```

### Path checks

[](#path-checks)

```
$path = Path::create('config/app.php');

$path->isAbsolute();  // false
$path->isRelative();  // true
$path->exists();      // checks if file/directory exists
$path->isFile();      // checks if it's a file
$path->isDir();       // checks if it's a directory
$path->isWriteable(); // checks if writable
```

### Converting paths

[](#converting-paths)

```
$relative = Path::create('src/Path.php');
$absolute = $relative->absolute();
// Result: /current/working/directory/src/Path.php

// Resolve against custom directory
$absolute = $relative->absolute('/var/www/app');
// Result: /var/www/app/src/Path.php

// Use as string
echo $path; // Path implements Stringable
```

### Pattern matching

[](#pattern-matching)

```
$path = Path::create('/var/www/app/Controller.php');
$path->match('*.php');           // true
$path->match('/var/www/*/Con*'); // true

// Supports wildcards
$path->match('file?.txt');       // matches file1.txt, fileA.txt, etc.
$path->match('file[123].txt');   // matches file1.txt, file2.txt, file3.txt
$path->match('test/*/*.php');    // matches test/any/file.php

// Control case sensitivity with optional parameter
$file = Path::create('File.TXT');
$file->match('*.txt');              // OS default (case-insensitive on Windows, case-sensitive on Unix)
$file->match('*.txt', false);       // case-insensitive (matches on any OS)
$file->match('*.txt', true);        // case-sensitive (won't match - different case)
$file->match('*.TXT', true);        // case-sensitive (matches - exact case)
```

Edge cases and special handling
-------------------------------

[](#edge-cases-and-special-handling)

The library handles common edge cases automatically:

### Hidden files and multiple extensions

[](#hidden-files-and-multiple-extensions)

```
// Hidden files (Unix-style)
$hidden = Path::create('.gitignore');
$hidden->stem();      // '.gitignore'
$hidden->extension(); // 'gitignore'

// Files with multiple dots
$config = Path::create('app.config.json');
$config->stem();      // 'app.config'
$config->extension(); // 'json' (only the last extension)
```

### Windows paths

[](#windows-paths)

```
// Automatically normalizes Windows backslashes
$winPath = Path::create('C:\Users\Admin\Documents');
echo $winPath; // 'C:/Users/Admin/Documents'

// Windows drive letters are recognized as absolute
Path::create('C:/Program Files')->isAbsolute(); // true
```

### Path normalization

[](#path-normalization)

```
// Removes redundant separators
Path::create('path//to///file.txt'); // 'path/to/file.txt'

// Resolves . and .. segments
Path::create('path/./to/../file.txt'); // 'path/file.txt'

// Empty path becomes current directory
Path::create(''); // '.'
```

### Safety checks

[](#safety-checks)

```
// Cannot join absolute paths (prevents common mistakes)
$base = Path::create('/var/www');
$base->join('/etc/config'); // throws LogicException

// Cannot navigate above root in absolute paths
Path::create('/var/../../root'); // throws LogicException
```

### Converting to absolute with custom base directory

[](#converting-to-absolute-with-custom-base-directory)

```
// Relative base directory is converted to absolute first
$path = Path::create('lib/helper.php');
$path->absolute('project/app'); // resolves 'project/app/lib/helper.php' against current directory first

// Absolute path with matching base - validation passes
$absolutePath = Path::create('/var/www/app/src/file.php');
$absolutePath->absolute('/var/www/app'); // returns same path (validation OK)
$absolutePath->absolute('/var/www');     // returns same path (validation OK - parent directory)

// Absolute path with non-matching base - throws exception
$absolutePath = Path::create('/var/www/app/file.php');
$absolutePath->absolute('/home/user'); // throws LogicException - path doesn't start with base
```

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance80

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community14

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~47 days

Total

5

Last Release

24d ago

PHP version history (2 changes)1.0.0PHP &gt;=8.1

1.x-devPHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/110fa17dca123e71e4ef4132d1d6a66d20058a07fc6118e716dd67dd4316e886?d=identicon)[roxblnfk](/maintainers/roxblnfk)

---

Top Contributors

[![roxblnfk](https://avatars.githubusercontent.com/u/4152481?v=4)](https://github.com/roxblnfk "roxblnfk (22 commits)")

---

Tags

filesystemhelperunixpathfilewindowscross-platformfilepath

###  Code Quality

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/internal-path/health.svg)

```
[![Health](https://phpackages.com/badges/internal-path/health.svg)](https://phpackages.com/packages/internal-path)
```

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k679.9M2.5k](/packages/league-flysystem)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.7k285.7M1.0k](/packages/league-flysystem-aws-s3-v3)[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k41.5M133](/packages/knplabs-gaufrette)[knplabs/knp-gaufrette-bundle

Allows to easily use the Gaufrette library in a Symfony project

72430.0M104](/packages/knplabs-knp-gaufrette-bundle)[league/flysystem-local

Local filesystem adapter for Flysystem.

225267.1M87](/packages/league-flysystem-local)[wikimedia/relpath

Work with file paths to join or find the relative path

13933.5k4](/packages/wikimedia-relpath)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
