$ show symfony/filesystem
The Symfony Filesystem component is a standalone PHP library (published on Packagist as symfony/filesystem) providing two primary utilities: the Filesystem class for filesystem operations — copy, mkdir, touch, remove, chmod/chown/chgrp, rename, symlink/hardlink, readlink, directory mirroring, tempnam, atomic dumpFile, appendToFile, and readFile — and the Path class for cross-platform path string manipulation: canonicalize, normalize, join, makeAbsolute/makeRelative, getLongestCommonBasePath, isBasePath, root/directory/extension extraction, and home-directory expansion. It targets PHP >= 8.4 and depends only on Symfony's deprecation-contracts plus ctype/mbstring polyfills, so it runs in any PHP project without framework baggage, with a small focused exception hierarchy (IOException, FileNotFoundException, InvalidArgumentException, RuntimeException). The craftsmanship lives in the details. dumpFile() writes via a private temporary file and an atomic rename, preserving existing file permissions and following symlinks to their real target; tempnam() uses fopen mode 'x+' to atomically check-and-create (eliminating TOCTOU races), forces umask(0o077) for secure default permissions, retries on collision, and supports stream wrappers like gs:// and file://. All native filesystem calls are routed through a box() wrapper that converts PHP warnings into structured IOException exceptions carrying the offending path. Path.php handles genuinely hard cases — Windows drive letters and the 'C:' special case, phar:// and other stream schemes, dot-segment collapse that preserves leading '..' on relative paths, and dotfile names when the base path is root — with a bounded memoization buffer to keep canonicalization fast. The architecture is deliberately minimal: no container, no services, no event system — just two well-factored classes backed by an exhaustive test suite. PathTest alone contains hundreds of data-provider cases covering UNIX, Windows, and stream-wrapper variants of every operation, and FilesystemTest exercises real filesystem behavior including permission edge cases, symlink privilege failures, read-only directories, and PHP bug workarounds. The component is the 8.2 development branch of Symfony, actively maintained with current dependency requirements and zero notable technical drift.
The LLM identified 4 files worth highlighting for reuse:
Self-contained final class of static methods for path string manipulation covering UNIX, Windows (drive letters, backslash/forward-slash mixing, the 'C:' special case), and stream wrappers (phar://, file://). canonicalize() collapses '.'/'..' segments while correctly preserving leading '..' on relative paths, expands '~' to the home directory, and caches results in a bounded 1250-entry buffer trimmed to 1000 to prevent memory leaks and performance decay. Other methods include join(), makeAbsolute()/makeRelative() with root/drive-letter validation, getLongestCommonBasePath(), isBasePath(), getDirectory() (fixing documented dirname() shortcomings), and extension handling. It imports only its own exception classes, so an engineer can copy it verbatim into any PHP project — it is a reference implementation for path-manipulation edge cases that PHP's built-in functions get wrong.
The tempnam() and dumpFile() methods form a production-grade safe file-writing pattern. tempnam() generates unique names via random_bytes, forces umask(0o077) so files are created private like native tempnam(), uses fopen mode 'x+' to atomically check existence and create in one step (eliminating TOCTOU vulnerabilities), retries up to 10 attempts on collision, and falls back to a loop for stream wrappers such as gs:// or file://. dumpFile() builds on this with write-to-temp-then-rename atomicity, symlink dereferencing to the real file, preservation of the target's existing permissions, and guaranteed temp-file cleanup in a finally block even on failure. This is directly reusable as a reference for crash-safe file persistence in any PHP application.
The private box() helper installs a scoped error handler around every native PHP filesystem call, capturing warnings/errors into a static lastError property and letting each public method throw a structured IOException that includes the offending path — instead of silently returning false or leaking PHP warnings. The companion assertFunctionExists() guard catches disabled functions (e.g., when symlink or link is disabled in php.ini) and produces an actionable message. This pattern of wrapping fallible C-level functions so all failures surface as typed, contextual exceptions is directly extractable for any PHP library wrapping native calls.
The remove()/doRemove() implementation solves the genuinely hard cases of deletion: it reverses input order so children are removed before parents, unlinks symlinks first so iterators never recurse into link targets, works around the Windows symlink unlink bug (PHP #52176) with an unlink-or-rmdir fallback, and handles read-only directories by renaming the target to a random hidden temp name before recursive deletion (restoring it if the final rmdir fails and re-checking file_exists to distinguish stale metadata from real errors). Permission-denied failures are detected and rethrown as IOException with the specific file path. Robust cross-platform deletion logic that most applications get wrong.