PHP Toolkit

Filesystem

One Filesystem interface across local disk, in-memory trees, SQLite databases, and ZIP archives. Forward-slash paths everywhere — even on Windows — so the same code runs in tests, in production, and inside read-only ZIP-backed trees.

composer require wp-php-toolkit/filesystem

Code that touches the filesystem is hard to test, hard to port to Windows, and impossible to point at non-disk storage without rewriting it. Swap LocalFilesystem for InMemoryFilesystem in tests and your suite stops touching /tmp; swap it for SQLiteFilesystem when the sqlite3 extension is available and your "files" become rows in a portable database; swap it for ZipFilesystem and you can read inside an archive with the same calls.

Every backend uses forward slashes regardless of host OS. No DIRECTORY_SEPARATOR juggling, no Windows-only test failures, no surprises when a path moves between backends.

In-memory tree

The fastest backend. No disk I/O, no cleanup, no test-isolation problems.

Test code without touching disk

Code that takes a Filesystem parameter, instead of calling file_get_contents() directly, can be tested against an InMemoryFilesystem. The test sets up files in memory, exercises the function, and asserts on what got written — no temp directories, no cleanup.

Local disk with a chrooted root

LocalFilesystem::create($root) is implicitly chrooted: every path resolves relative to $root and a ../ cannot escape. Reach for it when a request path or CLI argument names a file inside one project directory.

SQLite as a portable file store

The whole tree lives in one SQLite database file. Use it for self-contained scratch storage that survives process boundaries without leaving loose files behind. This backend requires PHP's sqlite3 extension.

Copy a tree across backends

The killer composability move: copy_between_filesystems() streams files chunk-by-chunk from any source to any target. Pull a ZIP into SQLite, snapshot SQLite to disk, mirror disk into RAM — all the same call, with the relevant backend extensions available.

Atomic write via tempfile rename

Write to a sibling tempfile, then rename — that's how you avoid leaving a half-written file on crash. rename() is atomic within a single filesystem.

Path helpers that behave the same on Windows

Unix path semantics apply on every host OS. This matters for abstract paths such as a SQLite key or a ZIP entry name because those paths do not live on a real drive.

See also