Oihana PHP

files

Table of Contents

Namespaces

archive
enums
exceptions
helpers
openssl
path
phar

Functions

assertDirectory()  : void
Asserts that a directory exists and is accessible, optionally checking readability and writability.
assertFile()  : void
Asserts that a file exists and is accessible.
assertWritableDirectory()  : void
Asserts that a directory exists and is readable and writable.
copyFilteredFiles()  : bool
Recursively copies files and directories from a source to a destination with filtering.
deleteDirectory()  : bool
Deletes a directory recursively.
deleteTemporaryDirectory()  : bool
Deletes a directory located in the system temporary folder (recursively).
findFiles()  : array<string|int, SplFileInfo>
Lists files in a directory with advanced filtering, sorting, and recursive options.
getBaseFileName()  : string
Returns the base file name without its extension from a given file path.
getDirectory()  : string
Normalises (and optionally validates) a directory path.
getFileExtension()  : string|null
Retrieves the file extension (including multipart extensions) from a given file path.
getHomeDirectory()  : string
Returns the current user’s home directory as a **canonical** path.
getRoot()  : string
Extracts the root directory component of a given path.
getSchemeAndHierarchy()  : array{0: ?string, 1: string}
Split a filename or URI into its scheme (if any) and hierarchical part.
getTemporaryDirectory()  : string
Builds a path inside the system temporary directory.
getTimestampedDirectory()  : string
Get a timestamped file path using a formatted date and optional prefix/suffix.
getTimestampedFile()  : string|null
Get a timestamped file path using a formatted date and optional prefix/suffix.
makeDirectory()  : string|null
Creates a directory if it does not exist and returns the path of the directory.
makeTemporaryDirectory()  : string
Creates (or returns if already present) a directory inside the system temporary folder.
makeTimestampedDirectory()  : string|null
Creates a directory named with a formatted timestamp.
makeTimestampedFile()  : string|null
Generates a timestamped file path if not exist. Using a formatted date and optional prefix/suffix.
recursiveFilePaths()  : array<string|int, mixed>
Recursively retrieves all .php files in a folder (and its subfolders).
requireAndMergeArrays()  : array<string|int, mixed>
Requires multiple PHP files (each returning an array) and merges the results.
shouldExcludeFile()  : bool
Checks if a file path should be excluded based on an array of patterns.
sortFiles()  : void
Sorts an array of SplFileInfo objects.
validateMimeType()  : void
Validate the MIME type of a file against a list of allowed types.

Functions

assertDirectory()

Asserts that a directory exists and is accessible, optionally checking readability and writability.

assertDirectory(string|null $path[, bool $isReadable = true ][, bool $isWritable = false ][, int|null $expectedPermissions = null ]) : void
Parameters
$path : string|null

The path of the directory to check.

$isReadable : bool = true

Whether to assert that the directory is readable. Default: true.

$isWritable : bool = false

Whether to assert that the directory is writable. Default: false.

$expectedPermissions : int|null = null

Optional permission mask (e.g., 0755).

Tags
throws
DirectoryException

If the path is null, empty, not a directory, or fails accessibility checks.

example
try
{
    $directoryPath = '/chemin/vers/le/repertoire' ;

    assertDirectory( $directoryPath , true , true , 0755 ) ;

    echo "The directory is accessible with the good permissions.\n";
}
catch ( DirectoryException $e )
{
    echo "Error: " . $e->getMessage() . PHP_EOL ;
}
author

Marc Alcaraz (ekameleon)

since
1.0.0

assertFile()

Asserts that a file exists and is accessible.

assertFile(string|null $file[, array<string|int, mixed>|null $expectedMimeTypes = null ][, bool $isReadable = true ][, bool $isWritable = false ]) : void
Parameters
$file : string|null

The path of the file to check.

$expectedMimeTypes : array<string|int, mixed>|null = null
$isReadable : bool = true

Whether to assert that the directory is readable. Default: true.

$isWritable : bool = false

Whether to assert that the directory is writable. Default: false.

Tags
throws
FileException

If the file path is null, empty, or if the file does not exist or is not accessible.

example

Basic usage: check if a file exists and is readable.

$file = 'test.txt';
file_put_contents($file, 'data');
try
{
   assertFile($file);
    // Continue ...
}
catch (FileException $e)
{
    // Handle error...
}
unlink($file);

Check for specific MIME types.

$file = 'document.txt';
file_put_contents($file, 'some text');
try
{
     // Will pass because a .txt file is typically 'text/plain'.
     assertFile( $file , ['text/plain', 'application/pdf'] );
}
catch ( FileException $e )
{
    // Throws an exception if MIME type is not in the allowed list.
}
unlink($file);

Check if a file is writable.

$file = 'config.ini';
file_put_contents($file, '[settings]');
try
{
    // Asserts the file exists, is readable, and is writable.
    assertFile($file, null, true, true);
}
catch (FileException $e)
{
    // Throws an exception if file is not writable.
}
unlink($file);
author

Marc Alcaraz (ekameleon)

since
1.0.0

assertWritableDirectory()

Asserts that a directory exists and is readable and writable.

assertWritableDirectory(string|null $directory) : void
Parameters
$directory : string|null

The path of the directory to check.

Tags
throws
DirectoryException

If the directory path is null, empty, or if the directory does not exist or is not accessible.

example

Success case: Check a writable directory. The system's temporary directory is a good candidate.

$tempDir = sys_get_temp_dir();
try
{
    assertWritableDirectory($tempDir);
   // Script continues if the directory is indeed writable.
   echo "Directory $tempDir is writable.";
}
catch (DirectoryException $e)
{
    // Handle the error if the directory is not accessible.
}

Failure case: The directory does not exist.

$fakeDir = '/a/path/that/does/not/exist';
try
{
    assertWritableDirectory($fakeDir);
}
catch (DirectoryException $e)
{
     // An exception is thrown because the directory is not valid.
     echo "Caught expected exception: " . $e->getMessage();
}
author

Marc Alcaraz (ekameleon)

since
1.0.0

copyFilteredFiles()

Recursively copies files and directories from a source to a destination with filtering.

copyFilteredFiles(string $sourceDir, string $destDir[, array<string|int, string> $excludePatterns = [] ][, callable|null $filterCallback = null ]) : bool

This function iterates through a source directory and copies its contents to a destination directory, preserving the folder structure. It provides two methods for filtering which files and directories get copied:

  1. $excludePatterns: An array of glob/regex patterns. Any file or directory matching a pattern in this array will be skipped. See shouldExcludeFile().
  2. $filterCallback: An optional user-defined function. This callback receives the full path of each item and must return true for the item to be copied.

Destination directories are created as needed.

Parameters
$sourceDir : string

The path to the source directory to copy from.

$destDir : string

The path to the destination directory.

$excludePatterns : array<string|int, string> = []

An array of patterns to exclude from the copy.

$filterCallback : callable|null = null

Optional callback for custom filtering. It receives the file path and should return true to include it.

Tags
throws
DirectoryException

If a directory cannot be created in the destination path.

example

Source directory structure:

/tmp/source/
├── .git/
│   └── config
├── images/
│   └── logo.png  (size: 5KB)
├── index.php     (size: 1KB)
└── error.log
$source = '/tmp/source';
$destination = '/tmp/destination';

// Exclude .git directories and all .log files.
$exclude = ['.git', '*.log'];

// Only include files smaller than 2KB (2048 bytes).
$filter = function(string $filePath)
{
   return is_dir($filePath) || filesize($filePath) < 2048;
};

copyFilteredFiles($source, $destination, $exclude, $filter);

Resulting destination directory:

/tmp/destination/
├── images/
└── index.php

Explanation:

  • .git/ was skipped by the exclude pattern.
  • error.log was skipped by the exclude pattern.
  • images/logo.png was skipped by the filter callback (size > 2KB).
  • index.php was copied as it passed both filters.
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

Returns true if at least one file or directory was copied, false otherwise.

deleteDirectory()

Deletes a directory recursively.

deleteDirectory(string|array<string|int, mixed>|null $path[, bool $assertable = true ][, bool $isReadable = true ][, bool $isWritable = true ]) : bool
Parameters
$path : string|array<string|int, mixed>|null

Directory or segments to remove.

$assertable : bool = true

Whether to validate the resulting path. Defaults to true.

$isReadable : bool = true

Check if the directory is readable (Default true).

$isWritable : bool = true

Check if the directory is writable (Default false).

Tags
throws
DirectoryException

If the directory path is null, empty, or if the directory cannot be deleted.

example

Create a temporary directory structure and then delete it.

$baseDir = sys_get_temp_dir() . '/temp_dir_to_delete';
$subDir = $baseDir . '/nested_dir';
mkdir($subDir, 0777, true); // Create nested directories
file_put_contents($baseDir . '/file.txt', 'content');

try
{
    if ( deleteDirectory( $baseDir ) )
    {
          // The directory and all its contents are now removed.
          // is_dir($baseDir) will return false.
    }
}
catch (DirectoryException $e)
{
    // Handle potential permission errors or other issues.
    echo "Error: " . $e->getMessage();
}

Using an array to specify the path to delete.

$parentDir = sys_get_temp_dir();
$dirName = 'another_temp_dir';
mkdir($parentDir . '/' . $dirName);
try
{
    // The path will be resolved to '/path/to/temp/another_temp_dir' and deleted.
    if (deleteDirectory([$parentDir, $dirName]))
    {
        // The directory is now removed.
    }
}
catch (DirectoryException $e)
{
    // Handle error.
}
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

Returns true if the directory is removed.

deleteTemporaryDirectory()

Deletes a directory located in the system temporary folder (recursively).

deleteTemporaryDirectory(string|array<string|int, string>|null $path[, bool $assertable = true ][, bool $isReadable = true ][, bool $isWritable = true ]) : bool

The given $path is appended to sys_get_temp_dir() in the same way as getTemporaryDirectory():

  • null → sys temp dir itself,
  • 'logs' → "/tmp/logs",
  • ['my', 'app'] → "/tmp/my/app".
Parameters
$path : string|array<string|int, string>|null

Optional sub‑path(s) inside sys_get_temp_dir().

$assertable : bool = true

Whether to validate the composed directory before deletion. Defaults to true.

$isReadable : bool = true

Check readability (passed to assertDirectory()). Defaults to true.

$isWritable : bool = true

Check writability (passed to assertDirectory()). Defaults to true.

Tags
throws
DirectoryException

If validation/deletion fails.

example
use function oihana\files\deleteTemporaryDirectory;

// Remove /tmp/old_reports (et son contenu)
deleteTemporaryDirectory('old_reports');

// Remove /tmp/tmp123/cache/images
deleteTemporaryDirectory(['tmp123', 'cache', 'images']);

// Force failure if folder is not writable
deleteTemporaryDirectory('protected_dir', isWritable: true);
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

True if the directory was deleted or did not exist.

findFiles()

Lists files in a directory with advanced filtering, sorting, and recursive options.

findFiles(string|null $directory[, array{filter?: callable|null, followLinks?: bool|null, includeDots?: bool|null, mode?: string|null, order?: string|null, pattern?: string|array|null, recursive?: bool|null, sort?: callable|string|array|null} $options = [] ]) : array<string|int, SplFileInfo>

This function provides flexible options for retrieving files and directories from a given path. It supports recursive search, glob and regex pattern matching, sorting, symbolic link following, and custom filters.

Parameters
$directory : string|null

The target directory path. If null or invalid, a DirectoryException is thrown.

$options : array{filter?: callable|null, followLinks?: bool|null, includeDots?: bool|null, mode?: string|null, order?: string|null, pattern?: string|array|null, recursive?: bool|null, sort?: callable|string|array|null} = []

Optional settings to customize the file listing.

  • filter : A function to map or transform each SplFileInfo result.
  • followLinks : Whether to follow symbolic links (default: false).
  • includeDots : Whether to include dot files (default: false).
  • mode : Filter by type: 'files', 'dirs', or 'both' (default: 'files').
  • order : Sort order: 'asc' (default) or 'desc'.
  • pattern : A glob pattern, regex, or list of patterns to match file names.
  • recursive : Whether to search recursively (default: false).
  • sort : A sort option, eg: callback, predefined string, or array of keys.
Tags
throws
DirectoryException
example
  1. Basic usage: list files in directory
use function oihana\files\findFiles;
use SplFileInfo;

$files = findFiles('/var/www');
  1. Recursive search
$files = findFiles('/var/www', [
'recursive' => true,
]);
  1. Include dotfiles
$files = findFiles('/var/www', [
'includeDots' => true,
]);
  1. Follow symbolic links (only affects recursive mode)
$files = findFiles('/var/www', [
'recursive'   => true,
'followLinks' => true,
]);
  1. Filter by file name pattern (glob or regex)
$files = findFiles('/var/www', [
'pattern' => '*.php',
]);
  1. Filter by multiple patterns (mixed glob + regex)
$files = findFiles('/var/www', [
'pattern' => ['*.php', '/^config\..+$/'],
]);
  1. List directories only
$dirs = findFiles('/var/www', [ 'mode' => 'dirs', ]);
  1. List both files and directories
$all = findFiles('/var/www', [ 'mode' => 'both' ]);
  1. Custom sort: by real path
$files = findFiles('/var/www', [
'sort' => fn(SplFileInfo $a, SplFileInfo $b) => strcmp($a->getRealPath(), $b->getRealPath()),
]);
  1. Predefined sort (e.g., name), descending order
$files = findFiles('/var/www', [
'sort'  => 'name',
'order' => 'desc',
]);
  1. Combined sort: type then name (directories first)
$files = findFiles('/var/www', [
'sort' => ['type', 'name'],
]);
  1. Map output to base names only
$names = findFiles('/var/www', [
'filter' => fn(SplFileInfo $file) => $file->getBasename(),
]);
  1. Get only file sizes
$sizes = findFiles('/var/www', [
'filter' => fn(SplFileInfo $file) => $file->getSize(),
]);
  1. List recursively with all options combined
$files = findFiles('/var/www',
[
    'recursive'    => true,
    'followLinks'  => true,
    'includeDots'  => true,
    'mode'         => 'files',
    'pattern'      => ['*.log', '*.txt'],
    'sort'         => 'ci_name',
    'order'        => 'asc',
    'filter'       => fn(SplFileInfo $file) => $file->getFilename(),
]);
see
sortFiles()
see
FindFindOption
see
FindMode
see
Order::asc
author

Marc Alcaraz (ekameleon)

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

getBaseFileName()

Returns the base file name without its extension from a given file path.

getBaseFileName(string $file[, array<string|int, mixed>|null $multiplePartExtensions = null ]) : string

This function extracts the file name from a full path and removes its extension. It supports both single and multi-part extensions (e.g. .tar.gz, .blade.php).

Parameters
$file : string

The full path to the file (e.g. '/path/to/archive.tar.gz').

$multiplePartExtensions : array<string|int, mixed>|null = null

Optional list of multi-part extensions to consider (e.g. ['.tar.gz', '.blade.php']). If null, the method defaults to FileExtension::getMultiplePartExtensions().

Tags
throws
InvalidArgumentException

If the file path is empty or invalid.

example
use function oihana\files\getBaseFileName;

// Basic example with simple extension
echo getBaseFileName('/path/to/image.png'); // 'image'

// With nested path and multi-part extension
echo getBaseFileName('/backups/2025-07-18.tar.gz'); // '2025-07-18'

// File with multiple dots, using default multi-part extensions
echo getBaseFileName('/views/template.blade.php'); // 'template'

// File with unknown multi-dot extension, fallback to last dot
echo getBaseFileName('/logs/system.debug.txt'); // 'system.debug'

// File without extension
echo getBaseFileName('/opt/bin/mybinary'); // 'mybinary'

// Windows-style path (backslashes will be normalized)
echo getBaseFileName('C:\\Users\\me\\file.tar.gz'); // 'file'

// Override default multi-part extensions
echo getBaseFileName('/path/to/file.custom.ext', ['.custom.ext']); // 'file'

// Edge case: dot file (no extension)
echo getBaseFileName('/path/.env'); // '.env'

// Throws exception: empty string
getBaseFileName('');

// Throws exception: path is a directory
getBaseFileName('/path/to/folder/');
see
FileExtension
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

The file name without its extension (e.g. 'archive' for 'archive.tar.gz').

getDirectory()

Normalises (and optionally validates) a directory path.

getDirectory(string|array<string|int, mixed>|null $path[, bool $assertable = true ][, bool $isReadable = true ][, bool $isWritable = false ]) : string
  • If $path is an array, empty segments and Char::EMPTY are removed, then the remaining parts are joined with DIRECTORY_SEPARATOR.
  • If $assertable is true (default), assertDirectory() ensures the resulting path exists and is readable.
  • Trailing separators are always stripped before return.
Parameters
$path : string|array<string|int, mixed>|null

Directory or segments to normalise.
Examples: '/tmp' or ['tmp','logs'].

$assertable : bool = true

Whether to validate the resulting path. Default: true.

$isReadable : bool = true

Whether to assert that the directory is readable. Default: true.

$isWritable : bool = false

Whether to assert that the directory is writable. Default: false.

Tags
throws
DirectoryException

If validation is enabled and the directory is invalid.

example

Basic use with a character string Validates that the system temporary directory exists and deletes the final separator.

$path = getDirectory( sys_get_temp_dir() . DIRECTORY_SEPARATOR );
// $path contient maintenant quelque chose comme '/tmp' ou 'C:\Users\...\Temp'.

Builds and validates a path from an array. Empty or null elements are ignored (assumes ‘/tmp/logs’ exists and is readable).

$parts = [sys_get_temp_dir(), '', 'logs', null];
$path = getDirectory($parts);
// $path contient maintenant quelque chose comme '/tmp/logs'.

Normalizes a path without validating it Ne lève pas d'exception si le chemin n'existe pas.

$path = getDirectory('/path/not/exist/', assertable: false);
// $path contains '/path/not/exist/'.

Validates that a directory is also writable.

try
{
    $path = getDirectory(sys_get_temp_dir(), isWritable: true);
    // The script continue if the directory is writable
}
catch ( DirectoryException $e )
{
    // Thrown an error
}
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

Normalized directory path.

getFileExtension()

Retrieves the file extension (including multipart extensions) from a given file path.

getFileExtension(string $file[, array<string|int, mixed>|null $multiplePartExtensions = null ][, bool $lowercase = true ]) : string|null

This function extracts the file extension from the filename portion of the path, supporting both simple extensions (e.g. .txt) and multipart extensions (e.g. .tar.gz, .blade.php). It relies on the getBaseFileName() function to determine the filename without its extension, then returns the remainder as the extension.

The function normalizes Windows-style backslashes (\) to forward slashes (/) before processing.

Parameters
$file : string

The full path or filename from which to extract the extension.

$multiplePartExtensions : array<string|int, mixed>|null = null

Optional array of multipart extensions to consider. If null, the default set from FileExtension::getMultiplePartExtensions() is used.

$lowercase : bool = true

Enforce the extension to be lowercase (default true).

Tags
example

Basic usage: extract extension from a file path.

use function oihana\files\getFileExtension;

echo getFileExtension('/path/to/archive.tar.gz');    // .tar.gz
echo getFileExtension('photo.JPG');                  // .jpg (lowercased by default)
echo getFileExtension('/some/file.txt');             // .txt
echo getFileExtension('/templates/home.blade.php');  // .blade.php
echo getFileExtension('script.min.js');              // .js

Using custom multipart extensions:

$custom = ['.custom.ext', '.tpl.php'];

echo getFileExtension('file.custom.ext', $custom);   // .custom.ext
echo getFileExtension('file.tpl.php', $custom);      // .tpl.php

Preserving original case:

echo getFileExtension('README.MD', null, false);     // .MD

Files with no extension:

echo getFileExtension('Makefile');                   // null
echo getFileExtension('.env');                       // null

Windows-style path normalization:

echo getFileExtension('C:\\projects\\demo.tar.bz2'); // .tar.bz2

Edge case: file with multiple dots and unknown multipart extension:

echo getFileExtension('data.backup.final.bak');      // .bak
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string|null

The file extension including the leading dot (e.g. .tar.gz), or null if the file has no extension.

getHomeDirectory()

Returns the current user’s home directory as a **canonical** path.

getHomeDirectory() : string

Resolution strategy – in order :

  1. Unix / macOS / Linux Uses the HOME environment variable if it is set and non‑empty.
  2. Windows (≥ XP) Combines HOMEDRIVE + HOMEPATH (e.g. C: + \Users\John) if both are available.
  3. Failure Throws a RuntimeException when no recognised combination is found.

The resulting string is passed through canonicalizePath() so that path separators are normalized (backslashes → slashes) and redundant slashes are removed.

Tags
throws
RuntimeException

When the home directory cannot be determined.

example
$home = getHomeDirectory(); // "/home/alice" or "C:/Users/Alice"
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

Canonical absolute path to the user’s home directory.

getRoot()

Extracts the root directory component of a given path.

getRoot(string $path) : string

This function identifies the root portion of a file system path, including handling of protocol schemes. ( e.g., "file://", "s3://" )

UNIX root ("/"), and Windows root ( e.g., "C:/" ).

It returns the canonical root as a string, or an empty string if the path is relative or empty.

Behavior:

  • "file:///usr/bin""file:///"
  • "/usr/bin""/"
  • "C:\\Windows\\System32""C:/"
  • "relative/path""" (empty string)
Parameters
$path : string

The input path, optionally with a scheme.

Tags
example
use function oihana\files\getRoot;

echo getRoot("file:///var/log");        // "file:///"
echo getRoot("/usr/local/bin");         // "/"
echo getRoot("C:\\Windows\\System32");  // "C:/"
echo getRoot("D:");                     // "D:/"
echo getRoot("some/relative/path");     // ""
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

The root component of the path, or an empty string if no root can be determined.

getSchemeAndHierarchy()

Split a filename or URI into its scheme (if any) and hierarchical part.

getSchemeAndHierarchy(string $filename) : array{0: ?string, 1: string}

Logic

  • Detect the first “://” only once – no array allocation if not present.
  • Accept schemes that match RFC‑3986 [A‑Za‑z][A‑Za‑z0‑9+\-.]*.
  • Return [$scheme, $hierarchy], where $scheme is null when absent.
Parameters
$filename : string

A path or URI such as file:///tmp/app.log or /etc/hosts.

Tags
throws
InvalidArgumentException

if the scheme is malformed (e.g. '1http://')

example
getSchemeAndHierarchy('s3://bucket/folder/img');    // ['s3',   'bucket/folder/img']
getSchemeAndHierarchy('/home/user/report.pdf');     // [null,  '/home/user/report.pdf']
getSchemeAndHierarchy('C:\\Windows\\notepad.exe');  // [null,  'C:\\Windows\\notepad.exe']
getSchemeAndHierarchy('file:///tmp/cache.db');      // ['file', '/tmp/cache.db']
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
array{0: ?string, 1: string}

getTemporaryDirectory()

Builds a path inside the system temporary directory.

getTemporaryDirectory([string|array<string|int, string>|null $path = null ][, bool $assertable = false ][, bool $isReadable = true ][, bool $isWritable = false ]) : string
Parameters
$path : string|array<string|int, string>|null = null

Optional sub‑path(s) to append inside sys_get_temp_dir().

$assertable : bool = false

Whether to validate the final directory path. Defaults to false because the directory may not exist yet.

$isReadable : bool = true

Check if the directory is readable (Default true).

$isWritable : bool = false

Check if the directory is writable (Default false).

Tags
throws
DirectoryException

If validation is enabled and the path is invalid.

example

Basic usage: get the system temp directory.

use function oihana\files\getTemporaryDirectory;

echo getTemporaryDirectory();
// e.g. "/tmp" on Unix, "C:\Windows\Temp" on Windows

Append a subdirectory path:

echo getTemporaryDirectory('myapp/cache'); // e.g. "/tmp/myapp/cache"
echo getTemporaryDirectory(['myapp', 'logs']); // e.g. "/tmp/myapp/logs"

Validate that the directory exists and is readable:

try
{
    $dir = getTemporaryDirectory('myapp/logs', true); // assertable = true
    echo $dir;
}
catch ( DirectoryException $e )
{
    // Handle error if directory does not exist or is not readable
}

Validate that the directory is writable:

try
{
   // assertable + readable + writable
   $dir = getTemporaryDirectory('myapp/uploads', true, true, true);
   echo $dir;
}
catch (DirectoryException $e)
{
   // Handle permission error
}

Using an absolute path (bypasses sys_get_temp_dir):

echo getTemporaryDirectory('/var/tmp/myapp'); // stays as is on Unix
echo getTemporaryDirectory('C:\\Temp\\custom'); // stays as is on Windows

Edge case: skip path argument to return system temp dir directly:

echo getTemporaryDirectory(null); // same as sys_get_temp_dir()
echo getTemporaryDirectory('');   // same as sys_get_temp_dir()
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

Normalised temporary directory path.

getTimestampedDirectory()

Get a timestamped file path using a formatted date and optional prefix/suffix.

getTimestampedDirectory([string|null $date = null ][, string $basePath = Char::EMPTY ][, string $prefix = Char::EMPTY ][, string $suffix = Char::EMPTY ][, string|null $timezone = 'Europe/Paris' ][, string|null $format = 'Y-m-dTH:i:s' ][, bool $assertable = true ]) : string

Combines a date/time string (or the current time) with optional *extension, prefix, suffix, and base path to generate a unique file name. The file is not created on disk.

Asserts by default if the file exist, you can disabled the behavior with the boolean assertable argument.

Parameters
$date : string|null = null

Optional date/time string to use. If null or invalid, the current date/time is used ("now").

$basePath : string = Char::EMPTY

Optional base path in which to place the directory. Defaults to the current directory.

$prefix : string = Char::EMPTY

Optional string to prepend to the directory name (e.g., "/hello-2025-12-01T14:00:00"").

$suffix : string = Char::EMPTY

Optional string to append to the directory name (e.g., "/2025-12-01T14:00:00-hello"").

$timezone : string|null = 'Europe/Paris'

Timezone identifier (e.g., 'Europe/Paris'). Defaults to 'Europe/Paris'.

$format : string|null = 'Y-m-dTH:i:s'

Date format compatible with DateTime::format(). Defaults to 'Y-m-d\TH:i:s'.

$assertable : bool = true

Whether to validate the path with assertDirectory(). Defaults to true.

Tags
throws
DirectoryException

If the directory path is invalid or assertion fails.

example
use function oihana\files\getTimestampedDirectory;

// Example 1: Generate directory path with current date/time, no prefix/suffix, current directory base
$dirPath = getTimestampedDirectory();
// e.g. "./2025-07-15T14:32:00"

// Example 2: Generate directory path with specific date, custom base path, and extension-like suffix
$dirPath = getTimestampedDirectory(
date: '2025-12-01 14:00:00',
basePath: '/var/backups',
suffix: '_archive'
);
// e.g. "/var/backups/2025-12-01T14:00:00_archive"

// Example 3: Add prefix and suffix, custom timezone and format, without assertion
$dirPath = getTimestampedDirectory
(
    prefix: 'backup_',
    suffix: '_final',
    timezone: 'UTC',
    format: 'Ymd_His',
    assertable: false
);
// e.g. "./backup_20250715_123200_final"
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

The full path of the generated directory.

getTimestampedFile()

Get a timestamped file path using a formatted date and optional prefix/suffix.

getTimestampedFile([string|null $date = null ][, string $basePath = Char::EMPTY ][, string|null $extension = null ][, string $prefix = Char::EMPTY ][, string $suffix = Char::EMPTY ][, string|null $timezone = 'Europe/Paris' ][, string|null $format = 'Y-m-dTH:i:s' ][, bool $assertable = true ]) : string|null

Combines a date/time string (or the current time) with optional *extension, prefix, suffix, and base path to generate a unique file name. The file is not created on disk.

Asserts by default if the file exist, you can disabled the behavior with the boolean assertable argument.

Parameters
$date : string|null = null

Optional date/time string to use. If null or invalid, the current date/time is used ("now").

$basePath : string = Char::EMPTY

Optional base path in which to place the file. Defaults to the current directory.

$extension : string|null = null

Optional extension to append to the file name (e.g., ".log", ".txt").

$prefix : string = Char::EMPTY

Optional string to prepend to the file name.

$suffix : string = Char::EMPTY

Optional string to append to the file name (e.g., "2025-12-01T14:00:00-hello"").

$timezone : string|null = 'Europe/Paris'

Timezone identifier (e.g., 'Europe/Paris'). Defaults to 'Europe/Paris'.

$format : string|null = 'Y-m-dTH:i:s'

Date format compatible with DateTime::format(). Defaults to 'Y-m-d\TH:i:s'.

$assertable : bool = true

Whether to validate the path with assertFile(). Defaults to true.

Tags
throws
FileException

If the file path is invalid.

example
use oihana\files\makeTimestampedFile;
use oihana\enums\Char;

// Example 1: file in the current directory using default format
$file = getTimestampedFile();
// e.g. ./2025-07-15T10:45:33

// Example 2: file inside /tmp with prefix and suffix
$file = getTimestampedFile
(
    date:     '2025-12-01 14:00:00',
    basePath: '/tmp',
    prefix:   'backup_',
    suffix:   '.sql'
);
// e.g. /tmp/backup_2025-12-01T14:00:00.sql

// Example 3: use a different timezone and format
$file = getTimestampedFile
(
    basePath : Char::EMPTY,
    prefix   : 'log_',
    suffix   : '.txt',
    timezone : 'UTC',
    format   : 'Ymd_His'
);
// e.g. ./log_20250715_084533.txt
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string|null

The full path of the generated file, or null on failure.

makeDirectory()

Creates a directory if it does not exist and returns the path of the directory.

makeDirectory(string|null $directory[, int $permissions = 0755 ][, bool $recursive = true ]) : string|null
Parameters
$directory : string|null

The path of the directory to create.

$permissions : int = 0755

The permissions to set for the directory (default: 0755).

$recursive : bool = true

If true, creates parent directories as needed (default: true).

Tags
throws
DirectoryException

If the directory cannot be created.

example

Basic usage: create a directory if it does not exist.

use function oihana\files\makeDirectory;

$dir = 'cache/files';
try
{
    makeDirectory($dir);
    echo "Directory created or already exists: $dir";
}
catch ( DirectoryException $e )
{
    // Handle error
}

Create a directory with custom permissions:

try
{
    makeDirectory('data/output', 0777);
}
catch ( DirectoryException $e )
{
    // Handle permission or creation error
}

Create a nested directory with recursive option:

try
{
    makeDirectory('var/log/myapp/debug', 0755, true); // parent folders created
}
catch ( DirectoryException $e )
{
    // Handle error
}

Handle failure when directory path is invalid or not writable:

try
{
   makeDirectory(''); // Throws exception: empty path
}
catch (DirectoryException $e)
{
    echo $e->getMessage(); // Directory path cannot be null or empty.
}

Check if the returned path is usable:

$path = makeDirectory('tmp/test');
file_put_contents( $path . '/sample.txt', 'content' ) ;
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string|null

Returns the path of the directory.

makeTemporaryDirectory()

Creates (or returns if already present) a directory inside the system temporary folder.

makeTemporaryDirectory(string|array<string|int, string>|null $path[, int $permission = 0755 ]) : string

The sub‑path is appended to sys_get_temp_dir() de la même manière que getTemporaryDirectory() :

  • null → the temp dir itself
  • 'cache'/tmp/cache
  • ['my', 'app']/tmp/my/app
Parameters
$path : string|array<string|int, string>|null

Optional sub‑directory path segments.

$permission : int = 0755

Octal mode for mkdir() (default: 0755).

Tags
throws
DirectoryException

If creation fails or the directory is still missing afterwards.

example
// 1) Ensure /tmp/reports exists
$reportsDir = makeTemporaryDirectory('reports');

// 2) Ensure /tmp/my/app/cache exists
$cacheDir = makeTemporaryDirectory(['my','app','cache'], 0700);

// 3) Just return /tmp itself
$tmp = makeTemporaryDirectory(null);
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string

Full path to the (existing or newly created) temporary directory.

makeTimestampedDirectory()

Creates a directory named with a formatted timestamp.

makeTimestampedDirectory([string|null $date = null ][, string $basePath = Char::EMPTY ][, string $prefix = Char::EMPTY ][, string $suffix = Char::EMPTY ][, string|null $timezone = 'Europe/Paris' ][, string|null $format = 'Y-m-dTH:i:s' ]) : string|null

Combines a date/time string (or the current time) with optional prefix, suffix, and base path to generate a unique directory name. The directory is created if it does not already exist.

Parameters
$date : string|null = null

Optional date/time string to use. If null or invalid, the current date/time is used ("now").

$basePath : string = Char::EMPTY

Optional base path in which to create the directory. Defaults to an empty string.

$prefix : string = Char::EMPTY

Optional string to prepend to the directory name.

$suffix : string = Char::EMPTY

Optional string to append to the directory name.

$timezone : string|null = 'Europe/Paris'

Timezone identifier (e.g., 'Europe/Paris'). Defaults to 'Europe/Paris'.

$format : string|null = 'Y-m-dTH:i:s'

Date format compatible with DateTime::format(). Defaults to 'Y-m-d\TH:i:s'.

Tags
throws
DirectoryException

If directory creation fails due to an error.

example

Example 1: simple directory in current path, using current date‑time

use oihana\\files\\createTimestampedDirectory;
use oihana\\enums\\Char;

$dir = createTimestampedDirectory();
// e.g. ./2025-07-15T10:30:12

Example 2 : directory inside /tmp with custom prefix/suffix and explicit date

$dir = createTimestampedDirectory
(
    date:     '2025-12-01 14:00:00',
    basePath: '/tmp',
    prefix:   'backup_',
    suffix:   '_v1'
);
// e.g. /tmp/backup_2025-12-01T14:00:00_v1

Example 3 : use a different timezone and format

$dir = createTimestampedDirectory
(
    date:     null,              // now
    basePath: Char::EMPTY,       // current directory
    prefix:   'log_',
    suffix:   Char::EMPTY,
    timezone: 'UTC',
    format:   'Ymd_His'          // 20250715_083012
);
// e.g. ./log_20250715_083012
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string|null

The full path of the created directory, or null on failure.

makeTimestampedFile()

Generates a timestamped file path if not exist. Using a formatted date and optional prefix/suffix.

makeTimestampedFile([string|null $date = null ][, string $basePath = Char::EMPTY ][, string|null $extension = null ][, string $prefix = Char::EMPTY ][, string $suffix = Char::EMPTY ][, string|null $timezone = 'Europe/Paris' ][, string|null $format = 'Y-m-dTH:i:s' ][, bool $mustExist = false ]) : string|null

Combines a date/time string (or the current time) with optional prefix, suffix, and base path to generate a unique file name. The file is not created on disk.

Parameters
$date : string|null = null

Optional date/time string to use. If null or invalid, the current date/time is used ("now").

$basePath : string = Char::EMPTY

Optional base path in which to place the file. Defaults to the current directory.

$extension : string|null = null

Optional extension to append to the file name (e.g., ".log", ".txt").

$prefix : string = Char::EMPTY

Optional string to prepend to the file name.

$suffix : string = Char::EMPTY

Optional string to append to the file name (e.g., "2025-12-01T14:00:00-hello"").

$timezone : string|null = 'Europe/Paris'

Timezone identifier (e.g., 'Europe/Paris'). Defaults to 'Europe/Paris'.

$format : string|null = 'Y-m-dTH:i:s'

Date format compatible with DateTime::format(). Defaults to 'Y-m-d\TH:i:s'.

$mustExist : bool = false

Whether the generated file must exist. If true, asserts the file exists. Defaults to false.

Tags
throws
FileException

If the file path is invalid, not writable, or must exist but does not.

example
use oihana\files\makeTimestampedFile;

// Example 1: Generate a file path with current datetime in default format, no prefix/suffix
$filePath = makeTimestampedFile();
// e.g. "./2025-07-15T10:45:33"

// Example 2: Generate a file path with a specific date and extension inside /tmp
$filePath = makeTimestampedFile(
    date: '2025-12-01 14:00:00',
    basePath: '/tmp',
    extension: '.log'
);
// e.g. "/tmp/2025-12-01T14:00:00.log"

// Example 3: Add prefix and suffix, use a custom timezone and date format
$filePath = makeTimestampedFile(
    prefix: 'backup_',
    suffix: '_final',
    timezone: 'UTC',
    format: 'Ymd_His'
);
// e.g. "./backup_20250715_084533_final"

// Example 4: Require that the generated file already exists (throws if not)
$filePath = makeTimestampedFile(mustExist: true);
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
string|null

The full path of the generated file, or null on failure.

recursiveFilePaths()

Recursively retrieves all .php files in a folder (and its subfolders).

recursiveFilePaths(string $directory[, array<string|int, mixed> $options = [] ]) : array<string|int, mixed>
Parameters
$directory : string

The base path of the file to be scanned.

$options : array<string|int, mixed> = []

The optional parameter to send in the function.

  • excludes (array) : The enumeration of all files to excludes
  • extensions (array) : The optional list of the extensions to use to scan the folder(s).
  • maxDepth (int) : The maximum allowed depth. Default -1 is used
  • sortable (bool) : Indicates if the list of file paths is sorted before returned.
Tags
example

Basic usage: list all PHP files in a directory (and its subdirectories).

use function oihana\files\recursiveFilePaths;

$files = recursiveFilePaths(__DIR__);
foreach ($files as $file) {
echo $file . PHP_EOL;
}

Include only files with certain extensions:

$files = recursiveFilePaths(__DIR__, [
'extensions' => ['php', 'inc'],
]);

Exclude specific filenames from the scan:

$files = recursiveFilePaths(__DIR__, [
'excludes' => ['ignore.php', 'test.php'],
]);

Limit maximum depth of traversal:

$files = recursiveFilePaths(__DIR__, [
'maxDepth' => 1, // Only scan current directory and its direct children
]);

Disable sorting of the resulting file list:

$files = recursiveFilePaths(__DIR__, [
'sortable' => false,
]);

Error handling when scanning an invalid directory:

try {
$files = recursiveFilePaths('invalid/path');
} catch (RuntimeException $e) {
echo "Error: " . $e->getMessage();
}
author

Marc Alcaraz (ekameleon)

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

The list of the full paths to all files found.

requireAndMergeArrays()

Requires multiple PHP files (each returning an array) and merges the results.

requireAndMergeArrays(array<string|int, mixed> $filePaths[, bool $recursive = true ]) : array<string|int, mixed>
Parameters
$filePaths : array<string|int, mixed>

An array of absolute or relative file paths to load.

$recursive : bool = true

Whether to perform a deep (recursive) merge (true) or a simple merge (false).

Tags
throws
RuntimeException

If a specified file is missing or does not return an array.

example
use function oihana\files\requireAndMergeArrays;

$paths = [
__DIR__ . '/config/default.php',
__DIR__ . '/config/override.php',
];

$config = requireAndMergeArrays($paths);
print_r($config);

Shallow merge (non-recursive):

$config = requireAndMergeArrays($paths, false);

Example of a required file:

// config/default.php
return
[
    'app' =>
    [
        'debug' => false,
        'timezone' => 'UTC',
    ],
];

// config/override.php
return
[
    'app' =>
    [
        'debug' => true,
    ],
];

Result with recursive merge:

[
    'app' =>
    [
        'debug'   => true,
        'timezone'=> 'UTC',
    ],
]

Error handling:

try
{
    $config = requireAndMergeArrays(['missing.php']);
}
catch ( RuntimeException $e )
{
    echo "Error: " . $e->getMessage();
}
author

Marc Alcaraz (ekameleon)

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

The merged array.

shouldExcludeFile()

Checks if a file path should be excluded based on an array of patterns.

shouldExcludeFile(string $filePath, array<string|int, string> $excludePatterns) : bool

This function supports two types of patterns:

  1. Glob patterns (e.g., '.log', 'config/.php'). These are matched using fnmatch().
  2. PCRE regular expressions (e.g., '/^temp-\d+.tmp$/i'). The function auto-detects regex patterns by checking if they are enclosed in matching delimiter characters.

For each pattern, the function attempts to match it against both the full file path and the basename of the file. The match is successful if any pattern matches. The glob matching is performed with the FNM_PATHNAME flag, meaning wildcards will not match directory separators (/).

Parameters
$filePath : string

The absolute or relative path to the file to check.

$excludePatterns : array<string|int, string>

An array of glob or PCRE patterns.

Tags
example
$patterns = [
'*.log',          // Exclude all .log files (matches basename)
'/^error_\d+/',   // Exclude files starting with error_... (regex)
'config/db.php'   // Exclude a specific file path (matches path suffix)
];

// Returns true (matches '*.log' on basename)
shouldExcludeFile('/var/www/app/logs/access.log', $patterns);

// Returns true (matches regex on basename)
shouldExcludeFile('/tmp/error_12345.txt', $patterns);

// Returns true (fnmatch matches '*config/db.php' against the full path)
shouldExcludeFile('/var/www/app/config/db.php', $patterns);

// Returns false (no pattern matches)
shouldExcludeFile('/var/www/index.php', $patterns);
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
bool

Returns true if the file path matches any of the exclusion patterns, false otherwise.

sortFiles()

Sorts an array of SplFileInfo objects.

sortFiles(array<string|int, SplFileInfo&$files, callable|string|array<string|int, mixed> $sort[, string|null $order = 'asc' ]) : void
Parameters
$files : array<string|int, SplFileInfo>

Array of files to sort (modified in‑place).

$sort : callable|string|array<string|int, mixed>

One of:

  • callable : custom compare function, ex: fn(SplFileInfo $a, SplFileInfo $b): int
  • string : single built‑in key
    'name' | 'ci_name' | 'extension' | 'size' | 'type' | 'atime' | 'ctime' | 'mtime'
  • array : ordered list of such keys for multi‑criteria sorting e.g. ['type', 'name'] or ['extension','size']
$order : string|null = 'asc'

The direction of the sort method 'asc' (default) or 'desc'.

Tags
examples
// 1) Sort by filename ascending
sortFiles($files, 'name');

// 2) Case‑insensitive filename descending
sortFiles($files, 'ci_name', 'desc');

// 3) Sort by extension then by size
sortFiles($files, ['extension', 'size']);

// 4) Custom comparator: modified time descending
sortFiles($files, fn($a, $b) => $a->getMTime() <=> $b->getMTime(), 'desc');

// 5) Type then case‑insensitive name
sortFiles($files, ['type', 'ci_name']);
author

Marc Alcaraz (ekameleon)

since
1.0.0

validateMimeType()

Validate the MIME type of a file against a list of allowed types.

validateMimeType(string $file, array<string|int, mixed> $allowedMimeTypes) : void
Parameters
$file : string

Path to the file to validate.

$allowedMimeTypes : array<string|int, mixed>

List of allowed MIME types. Can include strings or arrays of strings.

Tags
throws
FileException

If the MIME type is not allowed or cannot be determined.

example

Basic usage: validate that an uploaded file is a PDF or plain text file.

use function oihana\files\validateMimeType;
use oihana\files\exceptions\FileException;

$file = __DIR__ . '/example.txt';
file_put_contents($file, 'Some text content');

try
{
    validateMimeType($file, ['text/plain', 'application/pdf']);
    echo "File is valid.";
}
catch ( FileException $e )
{
    echo "Error: " . $e->getMessage();
}

unlink($file);

Accepting multiple MIME types (grouped by type):

$allowedTypes =
[
    ['image/png', 'image/jpeg'],
    ['application/pdf'],
];
validateMimeType('photo.jpg', $allowedTypes);

Error example:

try
{
    validateMimeType('fake.exe', ['image/png', 'image/jpeg']);
}
catch (FileException $e)
{
    echo "Validation failed: " . $e->getMessage();
}

Notes:

  • This function uses mime_content_type(), which relies on the system's file command or magic database.
  • For consistent results across platforms, ensure the PHP fileinfo extension is enabled.
author

Marc Alcaraz (ekameleon)

since
1.0.0

        
On this page

Search results