Filesystem Library for PHP
  • PHP 99.7%
  • Makefile 0.3%
Find a file
netkas 50ea0218d6
Some checks failed
CI / check-phpunit (push) Failing after 1s
CI / check-phpdoc (push) Failing after 1s
CI / release-artifacts (push) Has been skipped
CI / test (push) Has been skipped
CI / generate-phpdoc (push) Has been skipped
CI / release-documentation (push) Has been skipped
CI / debug (push) Failing after 1s
CI / release (push) Failing after 1s
Add $normalizePath parameter to IO functions for path normalization
2026-01-23 13:03:48 -05:00
.forgejo/workflows Initial Commit 2026-01-15 13:09:43 -05:00
.github/workflows Initial Commit 2026-01-15 13:09:43 -05:00
src/fslib Add $normalizePath parameter to IO functions for path normalization 2026-01-23 13:03:48 -05:00
tests Updated tests 2026-01-15 13:13:33 -05:00
.gitignore Initial Commit 2026-01-15 13:09:43 -05:00
CHANGELOG.md Add $normalizePath parameter to IO functions for path normalization 2026-01-23 13:03:48 -05:00
LICENSE Initial Commit 2026-01-15 13:09:43 -05:00
Makefile Initial Commit 2026-01-15 13:09:43 -05:00
phpdoc.dist.xml Initial Commit 2026-01-15 13:09:43 -05:00
phpunit.xml Initial Commit 2026-01-15 13:09:43 -05:00
project.yml Add $normalizePath parameter to IO functions for path normalization 2026-01-23 13:03:48 -05:00
README.md Initial Commit 2026-01-15 13:09:43 -05:00

fslib

fslib (Filesystem Library) is a lightweight and reliable library for handling file system operations in PHP applications, designed to simplify tasks such as file reading, writing, copying, moving, and deleting across different operating systems.

This library is meant to replace builtin PHP file system functions with a more consistent and user-friendly API that handles edge cases and errors gracefully.

Features

  • Cross-platform compatibility (Windows, Linux, macOS)
  • Simplified API for common file operations
  • Error handling with exceptions
  • Edge case management (e.g., symbolic links, permissions)

Table of contents

Building from Source

To build fslib from source, ensure you have PHP and ncc installed. Then run the following command in the project root:

ncc build -c release

This will compile the library and place the output in the target/ directory where you will see the produced ncc package.

Installation

You can install fslib via ncc. Run the following command in your project directory:

ncc install --package="target/release/net.nosial.fslib.ncc"

Using fslib as a Dependency

To use fslib in your PHP project, include it as a dependency in your ncc project configuration. Here is an example of how to include it:

dependencies:
  net.nosial.fslib: nosial/fslib@n64

You can also use @github or @codeberg as the repository source if you prefer.

Using fslib

The library provides two approaches for filesystem operations: static methods via the IO class and object-oriented wrappers via FileInfo, DirectoryInfo, PathInfo, and DiskInfo classes.

Path Operations

To handle path manipulations, use the following static methods from the IO class:

normalizePath

Normalizes a path to use the correct directory separator for the current OS and removes redundant separators. This method converts all path separators to the platform-specific separator (/ on Unix-like systems, \ on Windows) and collapses multiple consecutive separators into a single separator, ensuring consistent path formatting across different platforms.

\fslib\IO::normalizePath(string $path): string

Arguments:

  • $path - The path to normalize

Returns: Normalized path string

Example:

$normalized = \fslib\IO::normalizePath('/path//to///file.txt');
// Result: /path/to/file.txt

resolvePath

Resolves a path to an absolute path. Relative paths are resolved against the current working directory. This method converts relative paths (like ../file.txt or ./config.json) into their absolute equivalents by combining them with the current working directory, making it useful for ensuring consistent path references regardless of where your script is executed from.

\fslib\IO::resolvePath(string $path): string

Arguments:

  • $path - The path to resolve

Returns: Absolute path string

Example:

$absolute = \fslib\IO::resolvePath('relative/path/file.txt');
// Result: /current/working/directory/relative/path/file.txt

isAbsolutePath

Checks if a path is absolute. Handles both Windows (C:\ or UNC paths) and Unix (/) formats. On Windows, absolute paths start with a drive letter (C:) or UNC notation (\server\share), while on Unix-like systems they start with a forward slash (/). This method correctly identifies absolute paths regardless of the platform you're running on.

\fslib\IO::isAbsolutePath(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if absolute, false otherwise

Example:

$isAbs = \fslib\IO::isAbsolutePath('/usr/local/bin');  // true on Unix
$isAbs = \fslib\IO::isAbsolutePath('C:\\Windows');     // true on Windows
$isAbs = \fslib\IO::isAbsolutePath('relative/path');   // false

joinPaths

Joins path components intelligently. If an absolute path is encountered in the parts, it replaces all previous components. This method combines multiple path segments into a single path string, automatically handling separators and normalization. When an absolute path appears in the middle of the arguments, it discards all previous segments and starts fresh from that absolute path, mimicking how paths work in real filesystems.

\fslib\IO::joinPaths(string ...$parts): string

Arguments:

  • ...$parts - Variable number of path components to join

Returns: Joined and normalized path

Example:

$path = \fslib\IO::joinPaths('/base', 'sub', 'file.txt');
// Result: /base/sub/file.txt

getBasename

Gets the basename of a path, optionally removing a suffix. The basename is the final component of a path (typically the filename). When a suffix is provided, it will be stripped from the end of the basename if it matches exactly. This is particularly useful for getting filenames without their extensions or removing common suffixes from paths.

\fslib\IO::getBasename(string $path, ?string $suffix = null): string

Arguments:

  • $path - The input path
  • $suffix - Optional suffix to remove from basename

Returns: The basename

Example:

$base = \fslib\IO::getBasename('/path/to/file.txt');        // file.txt
$base = \fslib\IO::getBasename('/path/to/file.txt', '.txt'); // file

getDirname

Gets the directory name component of a path. This method extracts the parent directory portion of a path, removing the final component (basename). For example, from /path/to/file.txt it returns /path/to. This is useful for obtaining the containing directory of a file or for navigating up the directory tree.

\fslib\IO::getDirname(string $path): string

Arguments:

  • $path - The path

Returns: The directory name

Example:

$dir = \fslib\IO::getDirname('/path/to/file.txt');
// Result: /path/to

getExtension

Gets the file extension without the dot. This method extracts the extension from a filename by finding the last dot in the basename and returning everything after it (excluding the dot itself). For files without extensions or hidden files starting with a dot, it returns an empty string. Useful for determining file types or filtering files by extension.

\fslib\IO::getExtension(string $path): string

Arguments:

  • $path - The path

Returns: The file extension

Example:

$ext = \fslib\IO::getExtension('/path/to/file.txt');
// Result: txt

getFilename

Gets the filename without its extension. This method returns the basename of a path with the extension removed, giving you just the name portion. For example, file.txt becomes file, and document.tar.gz becomes document.tar (only the final extension is removed). This is useful when you need to work with file names independently of their type.

\fslib\IO::getFilename(string $path): string

Arguments:

  • $path - The path

Returns: The filename without extension

Example:

$name = \fslib\IO::getFilename('/path/to/file.txt');
// Result: file

File and Directory Checks

exists

Checks if a file or directory exists. This method verifies whether a path points to an existing filesystem entry, regardless of whether it's a file, directory, symbolic link, or other type. It returns true if the path exists and false otherwise. This is typically the first check you should perform before attempting to read, write, or manipulate filesystem entries.

\fslib\IO::exists(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if exists, false otherwise

Example:

if (\fslib\IO::exists('/path/to/file.txt')) {
    // File exists
}

isFile

Checks if a path is a file. This method returns true only if the path exists and is a regular file (not a directory, symbolic link, device file, or other special file type). Use this to verify that a path points to an actual file before attempting file-specific operations like reading its contents or checking its size.

\fslib\IO::isFile(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if path is a file, false otherwise

Example:

if (\fslib\IO::isFile('/path/to/file.txt')) {
    // Path is a file
}

isDirectory

Checks if a path is a directory. This method returns true only if the path exists and is a directory. It returns false for files, symbolic links (even if they point to directories), and non-existent paths. Use this to verify that a path is a directory before performing directory operations like listing contents or creating subdirectories.

\fslib\IO::isDirectory(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if path is a directory, false otherwise

Example:

if (\fslib\IO::isDirectory('/path/to/dir')) {
    // Path is a directory
}

isReadable

Checks if a path is readable. This method verifies whether the current user/process has permission to read from the specified path. It returns true if the path exists and is readable, false otherwise. Always check this before attempting to read files or list directory contents to avoid permission-related errors.

\fslib\IO::isReadable(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if readable, false otherwise

Example:

if (\fslib\IO::isReadable('/path/to/file.txt')) {
    $content = \fslib\IO::readFile('/path/to/file.txt');
}

isWritable

Checks if a path is writable. This method determines whether the current user/process has permission to write to or modify the specified path. For files, this means the ability to modify contents; for directories, the ability to create, rename, or delete entries within. Returns true if writable, false otherwise.

Check this before writing to files or modifying directory contents.

\fslib\IO::isWritable(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if writable, false otherwise

Example:

if (\fslib\IO::isWritable('/path/to/file.txt')) {
    \fslib\IO::writeFile('/path/to/file.txt', 'New content');
}

isExecutable

Checks if a file is executable. This method returns true if the path exists, is a file, and has execute permissions for the current user. On Unix-like systems, this checks the executable bit; on Windows, it typically checks file extensions (.exe, .bat, .cmd, etc.). Use this to verify whether a file can be executed as a program or script.

\fslib\IO::isExecutable(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if executable, false otherwise

Example:

if (\fslib\IO::isExecutable('/usr/bin/php')) {
    // File is executable
}

Checks if a path is a symbolic link. This method returns true only if the path is a symbolic link (symlink), regardless of whether the link target exists or is valid. Returns false for regular files, directories, and non-existent paths. Use this to identify symlinks before following them or to handle them specially in your application logic.

\fslib\IO::isSymlink(string $path): bool

Arguments:

  • $path - The path to check

Returns: True if path is a symbolic link, false otherwise

Example:

if (\fslib\IO::isSymlink('/path/to/link')) {
    $target = \fslib\IO::readSymlink('/path/to/link');
}

isDirectoryEmpty

Checks if a directory is empty. This method verifies whether a directory contains no files or subdirectories (excluding the special . and .. entries). Returns true if the directory exists and contains no entries, false if it contains any files or subdirectories. Throws an exception if the path doesn't exist or isn't a directory. Useful before deleting directories or deciding whether to perform cleanup operations.

\fslib\IO::isDirectoryEmpty(string $path): bool

Arguments:

  • $path - The directory path

Returns: True if directory is empty, false otherwise

Throws: IOException if path does not exist or is not a directory

Example:

if (\fslib\IO::isDirectoryEmpty('/path/to/dir')) {
    \fslib\IO::delete('/path/to/dir');
}

File Operations

readFile

Reads the entire contents of a file. This method loads the complete file contents into memory as a single string, making it convenient for working with text files or small binary files. The method validates that the path exists, is a file, and is readable before attempting to read. For large files, consider using streaming approaches or readFileLines() for line-by-line processing to avoid memory issues.

\fslib\IO::readFile(string $path): string

Arguments:

  • $path - The file path

Returns: File contents as string

Throws: IOException if file does not exist, is not a file, is not readable, or read fails

Example:

$content = \fslib\IO::readFile('/path/to/file.txt');

readFileLines

Reads a file into an array of lines. This method reads the entire file and splits it into an array where each element represents one line from the file. By default, newline characters (\n, \r\n) are removed from each line for cleaner processing. Set $trimNewlines to false if you need to preserve the original line endings. This is more memory-efficient than readFile() when processing line-by-line and provides easier iteration over file contents.

\fslib\IO::readFileLines(string $path, bool $trimNewlines = true): array

Arguments:

  • $path - The file path
  • $trimNewlines - Whether to trim newline characters from each line (default: true)

Returns: Array of lines

Throws: IOException if file does not exist, is not a file, is not readable, or read fails

Example:

$lines = \fslib\IO::readFileLines('/path/to/file.txt');
foreach ($lines as $line) {
    // Process each line
}

writeFile

Writes content to a file. Creates parent directories if necessary. This method writes the provided string content to the specified file path, either replacing existing content (default) or appending to it when $append is true. If the file doesn't exist, it will be created along with any missing parent directories. The method validates that the path is writable and handles error conditions gracefully. Use append mode for log files or when adding to existing data, and overwrite mode (default) when replacing file contents entirely.

\fslib\IO::writeFile(string $path, string $content, bool $append = false): void

Arguments:

  • $path - The file path
  • $content - The content to write
  • $append - Whether to append to the file instead of overwriting (default: false)

Throws: IOException if parent directory is not writable, path exists but is not a file, or write fails

Example:

\fslib\IO::writeFile('/path/to/file.txt', 'Hello, World!');
\fslib\IO::writeFile('/path/to/log.txt', 'New entry', true); // Append mode

copy

Copies a file or directory to a destination. This method creates a copy of the source at the destination path, preserving file contents and attempting to preserve metadata where possible. For files, it performs a simple file copy. For directories, when $recursive is true (default), it recursively copies all contents including subdirectories and files, recreating the entire directory structure. Non-recursive mode requires the source directory to be empty. The method validates permissions and handles edge cases like overwriting existing files.

\fslib\IO::copy(string $source, string $destination, bool $recursive = true): void

Arguments:

  • $source - The source path
  • $destination - The destination path
  • $recursive - Whether to copy directories recursively (default: true)

Throws: IOException if source does not exist, is not readable, or copy fails

Example:

\fslib\IO::copy('/source/file.txt', '/dest/file.txt');
\fslib\IO::copy('/source/dir', '/dest/dir', true); // Recursive directory copy

move

Moves (renames) a file or directory. This method relocates a filesystem entry from the source path to the destination path, effectively renaming or moving it. Unlike copy, this is a single atomic operation when source and destination are on the same filesystem. The source entry is removed after the move completes successfully. Works for both files and directories. The destination must not already exist, and parent directories must have write permissions. This is more efficient than copy-then-delete for reorganizing files.

\fslib\IO::move(string $source, string $destination): void

Arguments:

  • $source - The source path
  • $destination - The destination path

Throws: IOException if source does not exist, destination already exists, parent directories are not writable, or move fails

Example:

\fslib\IO::move('/old/path/file.txt', '/new/path/file.txt');

delete

Deletes a file or directory. This method removes the specified filesystem entry. For files and symbolic links, deletion is straightforward. For directories, the $recursive parameter controls behavior: when false (default), only empty directories can be deleted; when true, the entire directory tree including all contents is removed recursively. The method silently succeeds if the path doesn't exist, making it safe to call without checking existence first. Always use recursive deletion carefully as it cannot be undone.

\fslib\IO::delete(string $path, bool $recursive = false): void

Arguments:

  • $path - The path to delete
  • $recursive - Whether to delete directories recursively (default: false)

Throws: IOException if parent directory is not writable, or delete fails

Behavior: If path does not exist, the method returns without error. For directories, recursive must be true if the directory is not empty.

Example:

\fslib\IO::delete('/path/to/file.txt');
\fslib\IO::delete('/path/to/directory', true); // Recursive directory deletion

touch

Touches a file, creating it if it doesn't exist or updating its modification time. This method mimics the Unix touch command: if the file doesn't exist, it creates an empty file; if it exists, it updates the modification and/or access timestamps. The $time parameter sets the modification time (defaults to current time), and $atime sets the access time (defaults to same as modification time). Useful for creating placeholder files, updating timestamps for caching mechanisms, or signaling file changes.

\fslib\IO::touch(string $path, ?int $time = null, ?int $atime = null): void

Arguments:

  • $path - The file path
  • $time - Modification time as Unix timestamp (default: current time)
  • $atime - Access time as Unix timestamp (default: same as $time)

Throws: IOException if parent directory is not writable or touch fails

Example:

\fslib\IO::touch('/path/to/file.txt');
\fslib\IO::touch('/path/to/file.txt', time() - 3600); // Set to 1 hour ago

File Information

getFileSize

Gets the file size in bytes. This method returns the exact size of the file in bytes as an integer. It works only on regular files and throws an exception if the path doesn't exist, isn't a file, or if the size cannot be determined. For directories, use getDirectorySize() instead. The returned value represents the actual bytes stored on disk, useful for validating file uploads, calculating storage usage, or implementing size-based file handling logic.

\fslib\IO::getFileSize(string $path): int

Arguments:

  • $path - The file path

Returns: File size in bytes

Throws: IOException if file does not exist, is not a file, or size cannot be determined

Example:

$size = \fslib\IO::getFileSize('/path/to/file.txt');
print("File size: $size bytes");

getModifiedTime

Gets the last modification time of a file. This method returns the Unix timestamp (seconds since epoch) indicating when the file or directory was last modified. Modification time updates when file contents change or when directory entries are added/removed. The timestamp can be converted to human-readable format using PHP's date() function.

Useful for caching decisions, synchronization logic, or displaying when files were last updated.

\fslib\IO::getModifiedTime(string $path): int

Arguments:

  • $path - The path

Returns: Unix timestamp of last modification

Throws: IOException if path does not exist or time cannot be determined

Example:

$mtime = \fslib\IO::getModifiedTime('/path/to/file.txt');
print("Last modified: " . date('Y-m-d H:i:s', $mtime) . PHP_EOL);

getAccessTime

Gets the last access time of a file. This method returns the Unix timestamp indicating when the file was last accessed (read). Note that many modern filesystems mount with noatime or relatime options for performance, which may affect the accuracy of access times. Access time updates when file contents are read but not when metadata is queried. Useful for identifying unused files or implementing access-based cleanup policies, though modification time is generally more reliable.

\fslib\IO::getAccessTime(string $path): int

Arguments:

  • $path - The path

Returns: Unix timestamp of last access

Throws: IOException if path does not exist or time cannot be determined

Example:

$atime = \fslib\IO::getAccessTime('/path/to/file.txt');
print("Last accessed: " . date('Y-m-d H:i:s', $atime) . PHP_EOL);

getRealPath

Gets the real path of a file, resolving symbolic links. This method returns the absolute canonical path with all symbolic links resolved to their ultimate targets, . and .. references eliminated, and the path normalized. If the path includes symlinks, they are followed to find the actual file location. Throws an exception if the path doesn't exist or cannot be resolved. Essential for security checks, avoiding symlink loops, and determining the actual location of files in complex directory structures with multiple symlinks.

\fslib\IO::getRealPath(string $path): string

Arguments:

  • $path - The path

Returns: Real path with symlinks resolved

Throws: IOException if path does not exist or real path cannot be determined

Example:

$realPath = \fslib\IO::getRealPath('/path/to/symlink');
// Result: /actual/target/file.txt

Directory Operations

createDirectory

Creates a directory, optionally creating parent directories. This method creates a new directory at the specified path with the given permissions (Unix only; Windows ignores the mode parameter). When $recursive is false (default), the parent directory must already exist. When true, all missing parent directories are created automatically, similar to mkdir -p. If the directory already exists, the method succeeds without error. Throws an exception if the path exists but is not a directory or if creation fails due to permissions.

\fslib\IO::createDirectory(string $path, int $mode = 0755, bool $recursive = false): void

Arguments:

  • $path - The directory path to create
  • $mode - Permissions in octal format (Unix only, default: 0755)
  • $recursive - Whether to create parent directories (default: false)

Throws: IOException if path exists but is not a directory, parent does not exist (when not recursive), or creation fails

Example:

\fslib\IO::createDirectory('/path/to/new/dir');
\fslib\IO::createDirectory('/path/to/nested/dirs', 0755, true); // Recursive

listDirectory

Lists the contents of a directory. This method returns an array of entry names (files and subdirectories) contained within the specified directory. Returns only the names, not full paths - combine with the directory path if you need absolute paths. The $includeHidden parameter controls whether files starting with . are included (default: true). Always excludes the special . and .. directory entries. Throws an exception if the path doesn't exist, isn't a directory, or isn't readable. For object-based results, see DirectoryInfo::listAsObjects().

\fslib\IO::listDirectory(string $path, bool $includeHidden = true): array

Arguments:

  • $path - The directory path
  • $includeHidden - Whether to include hidden files starting with . (default: true)

Returns: Array of filenames (not full paths). Excludes . and .. entries.

Throws: IOException if directory does not exist, is not a directory, is not readable, or listing fails

Example:

$items = \fslib\IO::listDirectory('/path/to/directory');
foreach ($items as $item) {
    // Process each item
}

getDirectorySize

Gets the directory size recursively in bytes. This method calculates the total size of all files within the directory and its subdirectories, recursively traversing the entire tree structure. The result includes all regular files but excludes directory entries themselves (which typically have negligible size). This operation can be slow for large directory trees as it must stat every file. Useful for quota enforcement, storage reporting, or determining space requirements before copying. Symbolic links are not followed to avoid counting files multiple times.

\fslib\IO::getDirectorySize(string $path): int

Arguments:

  • $path - The directory path

Returns: Total size in bytes

Throws: IOException if directory does not exist, is not a directory, or is not readable

Example:

$size = \fslib\IO::getDirectorySize('/path/to/dir');
print("Directory size: " . round($size / 1024 / 1024, 2) . " MB" . PHP_EOL);

Creates a symbolic link. This method creates a symlink at the $link path that points to $target. The target can be a relative or absolute path and doesn't need to exist at symlink creation time (dangling symlinks are allowed). On Unix-like systems, symlinks are fully supported; on Windows, symlink creation requires administrator privileges or Developer Mode enabled. Throws an exception if the link path already exists or if creation fails. Useful for creating shortcuts, version aliases, or maintaining backward compatibility with moved files.

\fslib\IO::createSymlink(string $target, string $link): void

Arguments:

  • $target - The target path the symlink points to
  • $link - The path of the symlink to create

Throws: IOException if link path already exists, parent directory is not writable, or creation fails

Example:

\fslib\IO::createSymlink('/actual/file.txt', '/link/to/file.txt');

Reads the target of a symbolic link. This method returns the path that the symlink points to, exactly as stored in the symlink (which may be relative or absolute). It does not resolve the target or verify that it exists - it simply reads the link's value. To get the final resolved path, use getRealPath() instead. Throws an exception if the path doesn't exist or isn't a symbolic link. Useful for analyzing symlink chains, verifying link targets, or implementing custom symlink resolution logic.

\fslib\IO::readSymlink(string $path): string

Arguments:

  • $path - The symlink path

Returns: The target path

Throws: IOException if symlink does not exist, is not a symbolic link, or read fails

Example:

$target = \fslib\IO::readSymlink('/link/to/file.txt');
// Result: /actual/file.txt

Permissions

chmod

Changes the permissions of a file or directory. This method sets the Unix permission bits using octal notation (e.g., 0755, 0644). On Unix-like systems, this fully controls read, write, and execute permissions for owner, group, and others. On Windows, functionality is limited - it can only set or remove the read-only flag. The operation fails if you don't have sufficient privileges to change permissions. Common modes: 0644 (rw-r--r--) for files, 0755 (rwxr-xr-x) for directories and executables. Throws an exception if the path doesn't exist or the operation fails.

\fslib\IO::chmod(string $path, int $mode): void

Arguments:

  • $path - The path
  • $mode - Permissions in octal format (Unix only, limited functionality on Windows)

Throws: IOException if path does not exist or permission change fails

Example:

\fslib\IO::chmod('/path/to/file.txt', 0644);
\fslib\IO::chmod('/path/to/script.sh', 0755);

chown

Changes the owner of a file or directory. This method changes the user ownership of the specified path on Unix-like systems. Accepts either a username string or a numeric user ID. Typically requires root/superuser privileges unless changing to your own UID. On Windows, this operation is not supported and will fail. Useful for setting proper ownership after creating files as root, deploying applications, or managing multi-user environments. Throws an exception if the path doesn't exist, the owner is invalid, or the operation fails due to insufficient privileges.

\fslib\IO::chown(string $path, string|int $owner): void

Arguments:

  • $path - The path
  • $owner - Username or user ID

Throws: IOException if path does not exist or owner change fails (Unix only)

Example:

\fslib\IO::chown('/path/to/file.txt', 'www-data');
\fslib\IO::chown('/path/to/file.txt', 1000);

chgrp

Changes the group of a file or directory. This method changes the group ownership of the specified path on Unix-like systems. Accepts either a group name string or a numeric group ID. You must be the owner of the file and a member of the target group, or have superuser privileges. On Windows, this operation is not supported. Useful for managing shared file access in multi-user environments, setting up group-based permissions, or deployment scenarios.

Throws an exception if the path doesn't exist, the group is invalid, or the operation fails due to insufficient privileges.

\fslib\IO::chgrp(string $path, string|int $group): void

Arguments:

  • $path - The path
  • $group - Group name or group ID

Throws: IOException if path does not exist or group change fails (Unix only)

Example:

\fslib\IO::chgrp('/path/to/file.txt', 'www-data');
\fslib\IO::chgrp('/path/to/file.txt', 1000);

Disk Space

getDiskFreeSpace

Gets the disk free space for a path. This method returns the amount of available disk space in bytes on the filesystem containing the specified path. The value represents space available to the current user, which may be less than the total free space if disk quotas are in effect. Works on both files and directories - it queries the filesystem, not the specific entry. Useful for validating available space before large write operations, implementing disk space warnings, or monitoring storage capacity. The returned float can represent very large values exceeding PHP_INT_MAX.

\fslib\IO::getDiskFreeSpace(string $path): float

Arguments:

  • $path - The path

Returns: Free space in bytes

Throws: IOException if path does not exist or space cannot be determined

Example:

$free = \fslib\IO::getDiskFreeSpace('/home');
print("Free space: " . round($free / 1024 / 1024 / 1024, 2) . " GB" . PHP_EOL);

getDiskTotalSpace

Gets the total disk space for a path. This method returns the total capacity in bytes of the filesystem containing the specified path. This represents the entire filesystem size, not just the space available to the current user. Works on both files and directories as it queries the underlying filesystem. Combined with getDiskFreeSpace(), you can calculate used space and usage percentages. Useful for storage monitoring, capacity planning, and displaying disk usage statistics. The returned float can represent very large values exceeding integer limits on 32-bit systems.

\fslib\IO::getDiskTotalSpace(string $path): float

Arguments:

  • $path - The path

Returns: Total space in bytes

Throws: IOException if path does not exist or space cannot be determined

Example:

$total = \fslib\IO::getDiskTotalSpace('/home');
print("Total space: " . round($total / 1024 / 1024 / 1024, 2) . " GB" . PHP_EOL);

Object-Oriented API

getFileInfo

Creates a FileInfo object for a file. This method returns an object-oriented wrapper around a file path, providing access to all file operations and metadata through method calls on the object. The FileInfo instance encapsulates the path and offers a fluent, convenient API for file manipulation without needing to pass the path to every static method. The object is created immediately but doesn't verify the file exists - call exists() on it to check. This is the entry point for using the object-oriented API with files.

\fslib\IO::getFileInfo(string $path): \fslib\Objects\FileInfo

Arguments:

  • $path - The file path

Returns: FileInfo object

Example:

$file = \fslib\IO::getFileInfo('/path/to/file.txt');
$size = $file->getSize();

getDirectoryInfo

Creates a DirectoryInfo object for a directory. This method returns an object-oriented wrapper around a directory path, providing a rich API for directory operations like listing contents, getting subdirectories, creating, copying, and more. The DirectoryInfo instance encapsulates the path and provides convenient methods for directory manipulation and traversal. The object is created immediately without verifying existence - use exists() to check. Ideal for working with directories in an object-oriented style, especially when performing multiple operations on the same directory.

\fslib\IO::getDirectoryInfo(string $path): \fslib\Objects\DirectoryInfo

Arguments:

  • $path - The directory path

Returns: DirectoryInfo object

Example:

$dir = \fslib\IO::getDirectoryInfo('/path/to/dir');
$files = $dir->getFiles();

getPathInfo

Creates a PathInfo object for a path. This method returns an object focused on path manipulation and information, regardless of whether the path exists or what type of filesystem entry it represents. PathInfo provides methods for working with path components (basename, dirname, extension), normalization, resolution, and conversion to other info types. It's particularly useful for path string manipulation before actually creating or accessing files, or when you need to work with paths abstractly without caring about their current filesystem state.

\fslib\IO::getPathInfo(string $path): \fslib\Objects\PathInfo

Arguments:

  • $path - The path

Returns: PathInfo object

Example:

$path = \fslib\IO::getPathInfo('/path/to/file.txt');
$absolute = $path->getAbsolutePath();

getDiskInfo

Creates a DiskInfo object for a path. This method returns an object providing comprehensive disk space information for the filesystem containing the specified path. The DiskInfo object offers convenient methods for getting free, used, and total space in various units (bytes, KB, MB, GB), calculating usage percentages, and formatting values for display. The path can point to any file or directory - the object queries the underlying filesystem.

Useful for monitoring storage, displaying disk usage in UIs, or implementing storage quota checks with a clean object-oriented interface.

\fslib\IO::getDiskInfo(string $path): \fslib\Objects\DiskInfo

Arguments:

  • $path - The path

Returns: DiskInfo object

Example:

$disk = \fslib\IO::getDiskInfo('/home');
print("Free: " . $disk->getFreeSpaceFormatted());

FileInfo Class

Object-oriented wrapper for file operations. The FileInfo class encapsulates a file path and provides instance methods for all file-related operations, offering a more intuitive and fluent API compared to static method calls. Once created, the object represents a specific file path, and methods can be chained for convenient operations. This class is ideal for scenarios where you perform multiple operations on the same file or when working with file collections.

$file = new \fslib\Objects\FileInfo('/path/to/file.txt');

Methods:

  • getPath(): string - Gets the normalized file path
  • getAbsolutePath(): string - Gets the absolute path
  • getRealPath(): string - Gets the real path (resolving symlinks)
  • exists(): bool - Checks if file exists
  • isFile(): bool - Checks if path is a file
  • isDirectory(): bool - Checks if path is a directory
  • isReadable(): bool - Checks if file is readable
  • isWritable(): bool - Checks if file is writable
  • isExecutable(): bool - Checks if file is executable
  • isSymlink(): bool - Checks if path is a symbolic link
  • getSize(): int - Gets file size in bytes
  • getModifiedTime(): int - Gets last modification time
  • getAccessTime(): int - Gets last access time
  • getBasename(?string $suffix = null): string - Gets the basename
  • getDirname(): string - Gets the directory name
  • getExtension(): string - Gets the file extension
  • getFilename(): string - Gets the filename without extension
  • getParentDirectory(): DirectoryInfo - Gets parent directory as DirectoryInfo
  • read(): string - Reads file contents
  • readLines(bool $trimNewlines = true): array - Reads file as lines
  • write(string $content, bool $append = false): void - Writes content to file
  • copyTo(string $destination): FileInfo - Copies file to destination
  • moveTo(string $destination): FileInfo - Moves file to destination
  • delete(): void - Deletes the file
  • touch(?int $time = null, ?int $atime = null): void - Touches the file
  • chmod(int $mode): void - Changes file permissions
  • chown(string|int $owner): void - Changes file owner
  • chgrp(string|int $group): void - Changes file group
  • readSymlink(): string - Reads symlink target

Example:

$file = new \fslib\Objects\FileInfo('/path/to/file.txt');
if ($file->exists() && $file->isReadable()) 
{
    $content = $file->read();
    $lines = $file->readLines();
    $size = $file->getSize();
}

DirectoryInfo Class

Object-oriented wrapper for directory operations. The DirectoryInfo class encapsulates a directory path and provides a comprehensive set of instance methods for directory manipulation, traversal, and querying. It offers convenient methods for listing contents as objects, filtering files vs. directories, recursive operations, and navigation. The class makes working with directory hierarchies more intuitive than repeatedly calling static methods, especially when you need to perform multiple operations or traverse directory trees. Methods often return new Info objects, enabling fluent chaining.

$dir = new \fslib\Objects\DirectoryInfo('/path/to/directory');

Methods:

  • getPath(): string - Gets the normalized directory path
  • getAbsolutePath(): string - Gets the absolute path
  • getRealPath(): string - Gets the real path (resolving symlinks)
  • exists(): bool - Checks if directory exists
  • isDirectory(): bool - Checks if path is a directory
  • isReadable(): bool - Checks if directory is readable
  • isWritable(): bool - Checks if directory is writable
  • isSymlink(): bool - Checks if path is a symbolic link
  • isEmpty(): bool - Checks if directory is empty
  • getSize(): int - Gets directory size recursively in bytes
  • getModifiedTime(): int - Gets last modification time
  • getAccessTime(): int - Gets last access time
  • getBasename(): string - Gets the basename
  • getDirname(): string - Gets the parent directory name
  • getParentDirectory(): DirectoryInfo - Gets parent directory as DirectoryInfo
  • list(bool $includeHidden = true): array - Lists directory contents as filenames
  • listAsObjects(bool $includeHidden = true): array - Lists as FileInfo/DirectoryInfo objects
  • getFiles(bool $includeHidden = true): array - Gets all files as FileInfo objects
  • getDirectories(bool $includeHidden = true): array - Gets all subdirectories as DirectoryInfo objects
  • create(int $mode = 0755, bool $recursive = false): void - Creates the directory
  • copyTo(string $destination): DirectoryInfo - Copies directory to destination
  • moveTo(string $destination): DirectoryInfo - Moves directory to destination
  • delete(bool $recursive = false): void - Deletes the directory
  • chmod(int $mode): void - Changes directory permissions
  • chown(string|int $owner): void - Changes directory owner
  • chgrp(string|int $group): void - Changes directory group
  • readSymlink(): string - Reads symlink target
  • getFile(string $filename): FileInfo - Gets a file in this directory
  • getDirectory(string $dirname): DirectoryInfo - Gets a subdirectory

Example:

$dir = new \fslib\Objects\DirectoryInfo('/path/to/directory');
if ($dir->exists()) 
{
    $files = $dir->getFiles();
    foreach ($files as $file) 
    {
        print($file->getPath() . PHP_EOL);
    }
    
    $subdirs = $dir->getDirectories();
    $size = $dir->getSize();
}

PathInfo Class

Provides detailed information about a path. The PathInfo class is designed for path manipulation and analysis independent of filesystem state. Unlike FileInfo and DirectoryInfo which focus on existing filesystem entries, PathInfo excels at working with path strings - parsing components, normalizing, resolving relative paths, joining segments, and converting between different representations. It's particularly valuable when constructing paths dynamically, analyzing user input, or working with paths that may not yet exist on the filesystem. Methods never throw exceptions for non-existent paths.

$path = new \fslib\Objects\PathInfo('/path/to/file.txt');

Methods:

  • getPath(): string - Gets the original path
  • getNormalizedPath(): string - Gets the normalized path
  • getAbsolutePath(): string - Gets the absolute path
  • isAbsolute(): bool - Checks if path is absolute
  • getBasename(?string $suffix = null): string - Gets the basename
  • getDirname(): string - Gets the directory name
  • getExtension(): string - Gets the file extension
  • getFilename(): string - Gets the filename without extension
  • getParent(): PathInfo - Gets parent directory as PathInfo
  • join(string ...$parts): PathInfo - Joins this path with other components
  • exists(): bool - Checks if path exists
  • toFileInfo(): FileInfo - Converts to FileInfo object
  • toDirectoryInfo(): DirectoryInfo - Converts to DirectoryInfo object
  • toDiskInfo(): DiskInfo - Converts to DiskInfo object

Example:

$path = new \fslib\Objects\PathInfo('relative/path/file.txt');
print($path->getAbsolutePath() . PHP_EOL);
print($path->getExtension() . PHP_EOL);
print($path->getFilename() . PHP_EOL);

$newPath = $path->join('..', 'other', 'file.dat');

DiskInfo Class

Provides disk space information for a path. The DiskInfo class encapsulates disk/filesystem statistics for the volume containing a specified path, offering convenient methods to query space in multiple units, calculate usage percentages, and format values for display. It automatically calculates derived metrics like used space and percentages from the filesystem's free and total space. The class is particularly useful for implementing storage monitoring, displaying usage statistics in applications, validating available space before operations, or creating disk usage warnings. All space queries are performed when methods are called, reflecting current disk state.

$disk = new \fslib\Objects\DiskInfo('/path/to/check');

Methods:

  • getPath(): string - Gets the path
  • getFreeSpace(): float - Gets free disk space in bytes
  • getTotalSpace(): float - Gets total disk space in bytes
  • getUsedSpace(): float - Gets used disk space in bytes
  • getUsedPercentage(): float - Gets percentage of disk space used (0-100)
  • getFreePercentage(): float - Gets percentage of disk space free (0-100)
  • getFreeSpaceKB(): float - Gets free space in kilobytes
  • getFreeSpaceMB(): float - Gets free space in megabytes
  • getFreeSpaceGB(): float - Gets free space in gigabytes
  • getTotalSpaceKB(): float - Gets total space in kilobytes
  • getTotalSpaceMB(): float - Gets total space in megabytes
  • getTotalSpaceGB(): float - Gets total space in gigabytes
  • getUsedSpaceKB(): float - Gets used space in kilobytes
  • getUsedSpaceMB(): float - Gets used space in megabytes
  • getUsedSpaceGB(): float - Gets used space in gigabytes
  • getFreeSpaceFormatted(int $precision = 2): string - Gets formatted free space
  • getTotalSpaceFormatted(int $precision = 2): string - Gets formatted total space
  • getUsedSpaceFormatted(int $precision = 2): string - Gets formatted used space
  • static formatBytes(float $bytes, int $precision = 2): string - Formats bytes to human-readable format

Example:

$disk = new \fslib\Objects\DiskInfo('/home');
print("Free: " . $disk->getFreeSpaceFormatted() . PHP_EOL);
print("Total: " . $disk->getTotalSpaceFormatted() . PHP_EOL);
print("Used: " . $disk->getUsedPercentage() . '%' . PHP_EOL);

Exception Handling

All methods that can fail throw IOException with detailed error messages. Always wrap potentially failing operations in try-catch blocks. The IOException includes both a descriptive message explaining what went wrong and the path that caused the error (accessible via getPath()). This consistent error handling makes it easy to diagnose filesystem issues and provide meaningful feedback to users. Exception messages are designed to be informative, indicating the specific problem (e.g., "file not found", "permission denied", "not a directory") rather than generic errors, helping developers quickly identify and resolve issues.

use fslib\IOException;
use fslib\IO;

try 
{
    $content = IO::readFile('/path/to/file.txt');
}
catch (IOException $e) 
{
    print("Error: " . $e->getMessage() . PHP_EOL);
    print("Path: " . $e->getPath() . PHP_EOL);
}

License

The fslib library is licensed under the MIT License, see the LICENSE file for more information.