Filesystem

CakePHP provides filesystem utilities for working with files and directories efficiently. These utilities are split into two main classes:

  • Finder - A fluent, iterator-based API for discovering files and directories

  • Path - Static utilities for path manipulation

Finder

class Cake\Utility\Fs\Finder

The Finder class provides a lazy, iterator-based approach to discovering files and directories with a fluent interface for building complex queries. It’s memory-efficient and works consistently across different operating systems.

Available Methods

Location & Type

Cake\Utility\Fs\Finder::in(string $directory)

Add a directory to search in. Can be called multiple times.

Cake\Utility\Fs\Finder::files()

Find only files (returns iterator).

Cake\Utility\Fs\Finder::directories()

Find only directories (returns iterator).

Cake\Utility\Fs\Finder::all()

Find both files and directories (returns iterator).

Cake\Utility\Fs\Finder::recursive(bool $recursive = true)

Enable or disable recursive directory traversal. Default is true.

Filtering by Name

Cake\Utility\Fs\Finder::name(string $pattern)

Include files/directories matching a glob pattern. Multiple calls use OR logic.

Cake\Utility\Fs\Finder::notName(string $pattern)

Exclude files/directories matching a glob pattern. Multiple calls use OR logic.

Filtering by Path

Cake\Utility\Fs\Finder::path(string $pattern)

Include files whose relative path matches a pattern (substring or regex). Multiple calls use OR logic.

Cake\Utility\Fs\Finder::notPath(string $pattern)

Exclude files whose relative path matches a pattern (substring or regex). Multiple calls use OR logic.

Cake\Utility\Fs\Finder::pattern(string $globPattern)

Include files matching a glob pattern against the full relative path. Supports ** for recursive matching.

Cake\Utility\Fs\Finder::exclude(string $directory)

Exclude specific directories from traversal. More efficient than filtering.

Depth Control

Cake\Utility\Fs\Finder::depth(int $depth, DepthOperator $operator = DepthOperator::EQUAL)

Filter by directory depth using operators like EQUAL, LESS_THAN, GREATER_THAN, etc.

Custom Filtering

Cake\Utility\Fs\Finder::filter(callable $callback)

Apply custom filter callback. Receives SplFileInfo and relative path. Multiple calls use AND logic.

Cake\Utility\Fs\Finder::ignoreHiddenFiles()

Exclude hidden files (files starting with .).

Basic Usage

Finding Files and Directories

Find all PHP files in a directory:

use Cake\Utility\Fs\Finder;

$finder = (new Finder())
    ->in('src')
    ->name('*.php')
    ->files();

foreach ($files as $file) {
    echo $file->getPathname();
}

Find directories while excluding certain ones:

$directories = (new Finder())
    ->in('src')
    ->exclude('vendor')
    ->exclude('tmp')
    ->directories();

By default, the Finder searches recursively. Use recursive(false) for top-level only:

$finder = (new Finder())
    ->in('src')
    ->recursive(false)
    ->files();

Filtering Examples

By Filename Pattern

Include and exclude specific filename patterns:

$finder = (new Finder())
    ->in('src')
    ->name('*.php')              // Include all PHP files
    ->notName('*Test.php')       // Exclude test files
    ->notName('*Fixture.php')    // Exclude fixtures
    ->files();

By Path Pattern

Filter by path containing specific strings or regex patterns:

$finder = (new Finder())
    ->in('src')
    ->path('Controller')                    // Include paths containing "Controller"
    ->notPath('Test')                       // Exclude paths containing "Test"
    ->path('/Controller\.php$/')            // Or use regex patterns
    ->files();

By Depth

Control traversal depth using type-safe operators:

use Cake\Utility\Fs\Enum\DepthOperator;

// Maximum depth of 3
$finder = (new Finder())
    ->in('src')
    ->depth(3, DepthOperator::LESS_THAN)
    ->files();

// Depth range (1, 2, or 3)
$finder = (new Finder())
    ->in('src')
    ->depth(0, DepthOperator::GREATER_THAN)
    ->depth(4, DepthOperator::LESS_THAN)
    ->files();

Available depth operators: EQUAL, NOT_EQUAL, LESS_THAN, GREATER_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL.

Using Glob Patterns

Use glob patterns with ** for recursive matching:

$finder = (new Finder())
    ->in('.')
    ->pattern('src/**/*Controller.php')
    ->pattern('tests/**/*Test.php')
    ->files();

Glob syntax: * matches any characters except /, ** matches including /, ? matches single character, [abc] matches any character in set.

Custom Filters

For complex filtering, use custom callbacks:

use SplFileInfo;

$finder = (new Finder())
    ->in('src')
    ->filter(fn(SplFileInfo $file) => $file->getSize() > 1024)
    ->filter(fn(SplFileInfo $file) => $file->getMTime() > strtotime('-1 week'))
    ->files();

The callback receives SplFileInfo and the relative path:

$finder = (new Finder())
    ->in('.')
    ->filter(function (SplFileInfo $file, string $relativePath) {
        return str_starts_with($relativePath, 'src/Controller')
            || str_starts_with($relativePath, 'src/Model');
    })
    ->files();

Complete Example

Combining multiple filters:

use Cake\Utility\Fs\Finder;
use Cake\Utility\Fs\Enum\DepthOperator;

$finder = (new Finder())
    ->in('src')
    ->in('plugins')
    ->name('*.php')
    ->notName('*Test.php')
    ->exclude('vendor')
    ->exclude('tmp')
    ->path('Controller')
    ->depth(5, DepthOperator::LESS_THAN)
    ->ignoreHiddenFiles()
    ->files();

foreach ($finder as $file) {
    echo $file->getRealPath() . PHP_EOL;
}

Path

class Cake\Utility\Fs\Path

The Path class provides static utilities for path manipulation.

Available Methods

static Cake\Utility\Fs\Path::normalize(string $path)

Convert paths to use forward slashes.

static Cake\Utility\Fs\Path::makeRelative(string $path, string $base)

Convert an absolute path to a relative path based on a base directory.

static Cake\Utility\Fs\Path::join(string ...$segments)

Join multiple path segments into a single path.

static Cake\Utility\Fs\Path::matches(string $pattern, string $path)

Test if a path matches a glob pattern. Supports *, **, ?, and [abc] syntax.

Examples

use Cake\Utility\Fs\Path;

// Normalize path separators
Path::normalize('path\\to\\file.php');
// Returns: 'path/to/file.php'

// Make relative paths
Path::makeRelative('/var/www/app/src/Controller/UsersController.php', '/var/www/app');
// Returns: 'src/Controller/UsersController.php'

// Join path segments
Path::join('src', 'Controller', 'UsersController.php');
// Returns: 'src/Controller/UsersController.php'

// Match glob patterns
Path::matches('*.php', 'test.php');                                      // true
Path::matches('src/**/*.php', 'src/Controller/UsersController.php');    // true
Path::matches('src/**/Test/*.php', 'src/Controller/UsersController.php'); // false