PHPackages                             mschop/pathogen - 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. mschop/pathogen

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

mschop/pathogen
===============

General-purpose path library for PHP.

0.7.1(4y ago)534.8k↓11.3%3[2 issues](https://github.com/mschop/pathogen/issues)2MITPHPPHP &gt;=7.4

Since Jul 8Pushed 1y agoCompare

[ Source](https://github.com/mschop/pathogen)[ Packagist](https://packagist.org/packages/mschop/pathogen)[ Docs](https://github.com/mschop/pathogen)[ RSS](/packages/mschop-pathogen/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (21)Used By (2)

!!! WARNING !!!
===============

[](#-warning-)

You are watching the documentation for v1.X (unreleased). For current stable release see

Pathogen
========

[](#pathogen)

*General-purpose path library for PHP.*

[![Run Unit Tests](https://github.com/mschop/pathogen/actions/workflows/docker-image.yml/badge.svg)](https://github.com/mschop/pathogen/actions/workflows/docker-image.yml)

Future development
------------------

[](#future-development)

This package is a fork of the abandoned package eloquent/pathogen. I will continue the work on this lib. Please feel free to issue feature requests or bug reports.

Installation and documentation
------------------------------

[](#installation-and-documentation)

- Available as [Composer](http://getcomposer.org/) package \[mschop/pathogen\].
- [API documentation](http://lqnt.co/pathogen/artifacts/documentation/api/) available.

What is Pathogen?
-----------------

[](#what-is-pathogen)

*Pathogen* is a library for path manipulation. *Pathogen* supports file system paths including Unix and Windows style paths, but is truly a general-purpose path implementation, capable of representing URI paths and other path-like structures while providing a comprehensive API.

Table of contents
-----------------

[](#table-of-contents)

- [Pathogen concepts](#pathogen-concepts)
    - [Path parts](#path-parts)
        - [Path atoms](#path-atoms)
        - [Path name](#path-name)
        - [Path name extensions](#path-name-extensions)
        - \[Trailing separators\](#trailing separators)
    - [Absolute and relative paths](#absolute-and-relative-paths)
    - [Special paths](#special-paths)
    - [Creating paths](#creating-paths)
        - [Static factory methods](#static-factory-methods)
    - [Path resolution](#path-resolution)
        - [Resolution methods](#resolution-methods)
        - [Resolver objects](#resolver-objects)
    - [Path normalization](#path-normalization)
        - [Normalize method](#normalize-method)
        - [Normalizer objects](#normalizer-objects)
    - [File system paths](#file-system-paths)
    - [Immutability of paths](#immutability-of-paths)
    - [Windows path support](#windows-path-support)
    - [Dependency consumer traits](#dependency-consumer-traits)
        - [Available dependency consumer traits](#available-dependency-consumer-traits)
- [Usage examples](#usage-examples)
    - [Resolving a user-provided path against the current working directory](#resolving-a-user-provided-path-against-the-current-working-directory)
    - [Determining whether one path exists inside another](#determining-whether-one-path-exists-inside-another)
    - [Appending an extension to a path](#appending-an-extension-to-a-path)
    - [Replacing a path's extension](#replacing-a-paths-extension)
    - [Replacing a section of a path](#replacing-a-section-of-a-path)

Pathogen concepts
-----------------

[](#pathogen-concepts)

### Path parts

[](#path-parts)

The overall structure of a *Pathogen* path can be broken down into smaller parts. This diagram shows some of these named parts as they apply to a typical path:

```
  A   A   ___ A ___
 / \ / \ /         \
/foo/bar/baz.qux.pop
         \_________/
            name
\__________________/
        path

A = atom

```

The 'name' portion can be further broken down as follows:

```
  NWE    E
/     \ / \
baz.qux.pop
\_/ \_____/
 NP   NS

NWE = name without extension
  E = extension
 NP = name prefix
 NS = name suffix

```

#### Path atoms

[](#path-atoms)

In *Pathogen*, a path consists of a sequence of 'atoms'. Atoms are the individual sections of the path hierarchy. Given the path `/path/to/foo`, the sequence of atoms would be `path`, `to`, `foo`. The slash character is referred to as the 'separator'.

The atoms `.` and `..` have special meaning in *Pathogen*. The single dot (`.`) is referred to as the 'self atom' and is typically used to reference the current path. The double dot (`..`) is referred to as the 'parent atom' and is used to reference the path above the current one. Anyone familiar with typical file system paths should be familiar with their behaviour already.

Given a path instance, the atoms of the path can be determined as follows:

```
$atoms = $path->atoms(); // returns an array of strings
```

#### Path name

[](#path-name)

The 'name' section of a path is simply the last atom of a path. If a path has no atoms, its name is an empty string. Given a path instance, the name of the path can be determined like so:

```
$name = $path->name(); // returns a string
```

#### Path name extensions

[](#path-name-extensions)

The name of a path can be further divided using extension separators (`.`). For example, given the path name `foo.bar.baz`, *Pathogen* can determine the 'name without extension' (`foo.bar`), the 'name prefix' (`foo`), the 'name suffix' (`bar.baz`), and the 'extension' (`baz`).

Given a path instance, the various sections can be retrieved as follows:

```
$nameWithoutExtension = $path->nameWithoutExtension(); // returns a string
$namePrefix = $path->namePrefix(); // returns a string
$nameSuffix = $path->nameSuffix(); // returns a string or null
$extension = $path->extension(); // returns a string or null
```

#### Trailing separators

[](#trailing-separators)

*Pathogen* is capable of representing a path with a trailing separator (`/`). This is useful in the case that a trailing separator has a special meaning to some logic, such as the behaviour of the Unix cp command. The trailing separator support is purely for the use of developers utilizing *Pathogen*; it does not affect any logic used by *Pathogen* itself.

It is worth noting that all new path instances produced by *Pathogen* will strip any trailing slashes unless it is explicitly stated otherwise.

### Absolute and relative paths

[](#absolute-and-relative-paths)

In *Pathogen*, absolute and relative paths are represented by two different classes. While both classes implement a common [PathInterface](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/PathInterface.html), other methods are provided by the [AbsolutePathInterface](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/AbsolutePathInterface.html) or the [RelativePathInterface](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/RelativePathInterface.html)respectively.

This distinction provides, amongst other benefits, the ability to harness PHP's type hinting to restrict the type of path required:

```
use Pathogen\AbsolutePathInterface;use Pathogen\Path;use Pathogen\RelativePathInterface;

function anyPath(Path $path)
{
    // accepts any path
}

function absoluteOnly(AbsolutePathInterface $path)
{
    // accepts only absolute paths
}

function relativeOnly(RelativePathInterface $path)
{
    // accepts only relative paths
}
```

### Special paths

[](#special-paths)

The 'root' path is considered the top-most absolute path, and is represented as a single separator with no atoms (`/`).

The 'self' path is considered to point to the 'current' path, and is represented as a single self atom (`.`).

### Creating paths

[](#creating-paths)

#### Static factory methods

[](#static-factory-methods)

Normally you do create a path the static factory methods.To use this method effectively, simply choose the most appropriate class for the type of path:

```
use Pathogen\AbsolutePath;
use Pathogen\FileSystem\FileSystemPath;
use Pathogen\Path;
use Pathogen\RelativePath;
use Pathogen\Exception\PathTypeMismatchException;

$path = Path::fromString('/path/to/foo'); // returns AbsolutePath
$path = Path::fromString('\path\to\foo'); // returns AbsolutePath
$path = Path::fromString('bar/baz'); // returns RelativePath
$path = Path::fromString('bar\baz'); // returns RelativePath

# Specific classes
$path = RelativePath::fromString('bar/baz'); // returns RelativePath
$path = RelativePath::fromString('/bar/baz'); // !!! throws PathTypeMismatchException
$path = AbsolutePath::fromString('/bar/baz'); // returns AbsolutePath
$path = AbsolutePath::fromString('bar/baz'); // !!! throws PathTypeMismatchException

# Drive Anchoring (Windows)
$path = Path::fromString('C:/bar/baz'); // returns AbsoluteDriveAnchoredPath
$path = Path::fromString('C:\bar\baz'); // returns AbsoluteDriveAnchoredPath
$path = Path::fromString('C:bar/baz'); // returns RelativeDriveAnchoredPath
```

You can also use the constructor to create new instances of Path.

```
use Pathogen\Path;
use Pathogen\AbsoluteDriveAnchoredPath;

// Equivalent to '/path/to/foo'
$atoms = ['path', 'to', 'foo'];
$path = new Path($atoms, hasTrailingSeparator: false);

// Equivalent to 'C:\path\to\foo'
$path = new AbsoluteDriveAnchoredPath(atoms: $atoms, hasTrailingSeparator: false, drive: 'C');
```

### Path resolution

[](#path-resolution)

Resolution of a path involves taking a path which may be relative or absolute, and figuring out where that path points to, given a known 'base' path. The result of path resolution will always be an absolute path.

For example, consider a current path of `/path/to/foo`. A relative path of `bar/baz`, will resolve to `/path/to/foo/bar/baz` against this path. Conversely, an absolute path of `/path/to/qux` will not change after resolution, as it is already an absolute path.

#### Resolution methods

[](#resolution-methods)

The simplest way to achieve path resolution with *Pathogen* is to use the most appropriate method on a path:

```
use Pathogen\FileSystem\FileSystemPath;

$basePath = FileSystemPath::fromString('/path/to/foo');
$relativePath = FileSystemPath::fromString('bar/baz');
$absolutePath = FileSystemPath::fromString('/path/to/qux');

echo $basePath->resolve($relativePath); // outputs '/path/to/foo/bar/baz'
echo $basePath->resolve($absolutePath); // outputs '/path/to/qux'

echo $relativePath->resolveAgainst($basePath); // outputs '/path/to/foo/bar/baz'
```

#### Resolver objects

[](#resolver-objects)

Path resolvers are also a standalone concept in *Pathogen*. A simple example of their usage follows:

```
use Pathogen\FileSystem\FileSystemPath;
use Pathogen\Resolver\PathResolver;

$resolver = new PathResolver;

$basePath = FileSystemPath::fromString('/path/to/foo');
$relativePath = FileSystemPath::fromString('bar/baz');
$absolutePath = FileSystemPath::fromString('/path/to/qux');

echo $resolver->resolve($basePath, $relativePath); // outputs '/path/to/foo/bar/baz'
echo $resolver->resolve($basePath, $absolutePath); // outputs '/path/to/qux'
```

### Path normalization

[](#path-normalization)

Normalization of a path is the process of converting a path to its simplest or *canonical* form. This means resolving as many of the self and parent atoms as possible. For example, the path `/path/to/foo/../bar` normalizes to `/path/to/bar`.

Normalization works differently for absolute and relative paths. Absolute paths can always be resolved to a canonical form with no self or parent atoms. Relative paths can often be simplified, but may still contain these special atoms. For example, the path `../foo/../..` will actually normalize to `../..`.

Note that for absolute paths, the root path (`/`) is the top-most path to which parent atoms will normalize. That is, paths with more parent atoms than regular atoms, like `/..`, `/../..`, or `/foo/../..` will all normalize to be the root path (`/`).

Normalization typically never takes place in *Pathogen* unless it is required for a calculation, or done manually through the API. If a normalized path is required for some reason, this is left to the developer to handle.

#### Normalize method

[](#normalize-method)

The simplest way to normalize a path is to use the `normalize()` method:

```
use Pathogen\FileSystem\FileSystemPath;

$path = FileSystemPath::fromString('/path/./to/foo/../bar');

echo $path->normalize(); // outputs '/path/to/bar'
```

#### Normalizer objects

[](#normalizer-objects)

Path normalizers are also a standalone concept in *Pathogen*. A simple example of their usage follows:

```
use Pathogen\FileSystem\FileSystemPath;
use Pathogen\FileSystem\Normalizer\FileSystemPathNormalizer;

$normalizer = new FileSystemPathNormalizer;

$path = FileSystemPath::fromString('/path/./to/foo/../bar');

echo $normalizer->normalize($path); // outputs '/path/to/bar'
```

### File system paths

[](#file-system-paths)

*Pathogen* provides support for dealing with file system paths in a *platform agnostic* way. There are two approaches supported by *Pathogen*, which can be applied depending on the situation.

The first approach is to inspect the path string and create an appropriate path instance based upon a 'best guess'. This is handled by the [FileSystemPath](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/FileSystem/FileSystemPath.html)class:

```
use Pathogen\FileSystem\FileSystemPath;

$pathFoo = FileSystemPath::fromString('/path/to/foo');   // creates a Unix-style path
$pathBar = FileSystemPath::fromString('C:/path/to/bar'); // creates a Windows path
```

The second approach is to create paths based upon the current platform the code is running under. That is, when running under Linux or Unix, create Unix-style paths, and when running under Windows, create windows paths. This is handled by the [PlatformFileSystemPath](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/FileSystem/PlatformFileSystemPath.html):

```
use Pathogen\FileSystem\PlatformFileSystemPath;

// creates a path to match the current platform
$path = PlatformFileSystemPath::fromString('/path/to/foo');
```

Note that [FileSystemPath](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/FileSystem/FileSystemPath.html) and [PlatformFileSystemPath](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/FileSystem/PlatformFileSystemPath.html) are only utility classes with static methods. The actual path class used will depend on the input. If it is necessary to type hint for a file system path, [FileSystemPathInterface](http://lqnt.co/pathogen/artifacts/documentation/api/Eloquent/Pathogen/FileSystem/FileSystemPathInterface.html) or one of its more specialized child interfaces should be used instead.

### Immutability of paths

[](#immutability-of-paths)

Paths in *Pathogen* are *immutable*, meaning that once they are created, they cannot be modified. When performing some mutating operation on a path, such as normalization or resolution, a new path instance is produced, rather than the original instance being altered. This allows a path to be exposed as part of an interface without creating a leaky abstraction.

### Windows path support

[](#windows-path-support)

*Pathogen* provides support for Windows paths. In addition to the methods available to Unix-style paths, Windows paths contain an optional drive specifier. The drive specifier is available via the `drive()` method:

```
$drive = $path->drive(); // returns a single-character string, or null
```

### Dependency consumer traits

[](#dependency-consumer-traits)

*Pathogen* provides some [traits](http://php.net/traits) to make consuming its services extremely simple for code targeting PHP 5.4 and higher.

The concept of a dependency consumer trait is simple. If a class requires, for example, a path factory, it can simply use a `PathFactoryTrait`. This gives the class `setPathFactory()` and `pathFactory()` methods for managing the path factory dependency.

This example demonstrates how to use the file system path factory trait:

```
use Pathogen\FileSystem\Factory\Consumer\FileSystemPathFactoryTrait;

class ExampleConsumer
{
    use FileSystemPathFactoryTrait;
}

$consumer = new ExampleConsumer;
echo get_class($consumer->pathFactory()); // outputs 'Pathogen\FileSystem\Factory\FileSystemPathFactory'
```

#### Available dependency consumer traits

[](#available-dependency-consumer-traits)

- [PlatformFileSystemPathFactoryTrait](src/Eloquent/Pathogen/FileSystem/Factory/Consumer/PlatformFileSystemPathFactoryTrait.php)
- [FileSystemPathFactoryTrait](src/Eloquent/Pathogen/FileSystem/Factory/Consumer/FileSystemPathFactoryTrait.php)
- [PathFactoryTrait](src/Eloquent/Pathogen/Factory/Consumer/PathFactoryTrait.php)

Usage examples
--------------

[](#usage-examples)

### Resolving a user-provided path against the current working directory

[](#resolving-a-user-provided-path-against-the-current-working-directory)

```
use Pathogen\FileSystem\Factory\PlatformFileSystemPathFactory;

$factory = new PlatformFileSystemPathFactory;
$workingDirectoryPath = $factory->createWorkingDirectoryPath();

$path = $workingDirectoryPath->resolve(
    $factory->create($_SERVER['argv'][1])
);
```

### Resolving a path against another arbitrary path

[](#resolving-a-path-against-another-arbitrary-path)

```
use Pathogen\Path;

$basePath = Path::fromString('/path/to/base');
$path = Path::fromString('../child');

$resolvedPath = $basePath->resolve($path);

echo $resolvedPath->string();              // outputs '/path/to/base/../child'
echo $resolvedPath->normalize()->string(); // outputs '/path/to/child'
```

### Determining whether one path exists inside another

[](#determining-whether-one-path-exists-inside-another)

```
use Pathogen\Path;

$basePath = Path::fromString('/path/to/foo');
$pathA = Path::fromString('/path/to/foo/bar');
$pathB = Path::fromString('/path/to/somewhere/else');

var_dump($basePath->isAncestorOf($pathA)); // outputs 'bool(true)'
var_dump($basePath->isAncestorOf($pathB)); // outputs 'bool(false)'
```

### Appending an extension to a path

[](#appending-an-extension-to-a-path)

```
use Pathogen\Path;

$path = Path::fromString('/path/to/foo.bar');
$pathWithExtension = $path->joinExtensions('baz');

echo $pathWithExtension->string(); // outputs '/path/to/foo.bar.baz'
```

### Replacing a path's extension

[](#replacing-a-paths-extension)

```
use Pathogen\Path;

$path = Path::fromString('/path/to/foo.bar');
$pathWithNewExtension = $path->replaceExtension('baz');

echo $pathWithNewExtension->string(); // outputs '/path/to/foo.baz'
```

### Replacing a section of a path

[](#replacing-a-section-of-a-path)

```
use Pathogen\Path;

$path = Path::fromString('/path/to/foo/bar');
$pathWithReplacement = $path->replace(1, array('for', 'baz'), 2);

echo $pathWithReplacement->string(); // outputs '/path/for/baz/bar'
```

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance23

Infrequent updates — may be unmaintained

Popularity35

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 70.7% 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 ~286 days

Recently: every ~759 days

Total

12

Last Release

1547d ago

PHP version history (3 changes)0.1.0PHP &gt;=5.3.3

0.3.0PHP &gt;=5.3

0.7.0PHP &gt;=7.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8030310?v=4)[mschop](/maintainers/mschop)[@mschop](https://github.com/mschop)

---

Top Contributors

[![ezzatron](https://avatars.githubusercontent.com/u/100152?v=4)](https://github.com/ezzatron "ezzatron (152 commits)")[![mschop](https://avatars.githubusercontent.com/u/8030310?v=4)](https://github.com/mschop "mschop (40 commits)")[![darianbr](https://avatars.githubusercontent.com/u/1787188?v=4)](https://github.com/darianbr "darianbr (21 commits)")[![Azeirah](https://avatars.githubusercontent.com/u/4040870?v=4)](https://github.com/Azeirah "Azeirah (1 commits)")[![rixbeck](https://avatars.githubusercontent.com/u/761149?v=4)](https://github.com/rixbeck "rixbeck (1 commits)")

---

Tags

filesystemmanipulationpathfile

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mschop-pathogen/health.svg)

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

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k639.1M2.2k](/packages/league-flysystem)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.6k263.6M790](/packages/league-flysystem-aws-s3-v3)[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k39.8M123](/packages/knplabs-gaufrette)[knplabs/knp-gaufrette-bundle

Allows to easily use the Gaufrette library in a Symfony project

72428.6M91](/packages/knplabs-knp-gaufrette-bundle)[league/flysystem-local

Local filesystem adapter for Flysystem.

225231.8M39](/packages/league-flysystem-local)[league/flysystem-memory

In-memory filesystem adapter for Flysystem.

8533.6M194](/packages/league-flysystem-memory)

PHPackages © 2026

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