Caldera Storage is an storage abstraction layer.

As with the other Caldera components it has been built to be swappable and modular.


The easisest way to install it is to use Composer:

composer require vecode/caldera-storage


  • php: >=8.1
  • ext-mbstring: *

Basic usage

Getting started

To provide an useful abstraction of different storage providers, there is the AdapterInterface interface which must be implemented by the storage drivers. Out of the box two of them are included LocalAdapter for local, file-system backed storage and S3Adapter for S3-compatible cloud-based storage.

As is almost always the case with adapter-based classes, to create an instance of the Storage class you must pass an AdapterInterface instance, for example:

use Caldera\Storage\Storage;
use Caldera\Storage\Adapter\LocalAdapter;

$adapter = new LocalAdapter( dirname(__DIR__) . '/output' );
$storage = new Storage($adapter);

This way the root directory is set to dirname(__DIR__) . '/output' using the local, file-system adapter.

Once you've created your storage object you can start doing storage operations, but keep in mind that different adapters may support only a subset of the features, for example, the S3 adapter doesn't support creating or scanning directories.

The following operations are defined by the interface:

function exists(string $path): bool;
function read(string $path): string;
function write(string $path, string $contents, array $config = []): bool;
function delete(string $path): bool;
function size(string $path): int;
function lastModified(string $path): int;
function path(string $path): string;
function copy(string $from, string $to): bool;
function move(string $from, string $to): bool;
function files(string $directory, bool $recursive = false): array;
function directories(string $directory, bool $recursive = false): array;
function createDirectory(string $path): bool;
function deleteDirectory(string $path): bool;

As you may have guessed, exists checks for the existence of a file:

if ( $storage->exists('readme.md') ) {
    // Do something with readme.md

Accordingly, read and write allow you to get and set a file's contents:

// Write something
$storage->write('greetings.md', '# Hello world!');

// Read it back
$contents = $storage->read('greetings.md');

To get the size of file call size:

$size = $storage->size('greetings.md');

In some adapters you may also get the absolute path of the file with path (if not supported it will return the path relative to the root):

$path = $storage->path('greetings.md');

Other stat function is lastModified which will return a timestamp:

$last_modified = $storage->lastModified('greetings.md');

Improving on write, the append and prepend methods allow you to write at the beginning or at the end of a file:

// At the beginning
$result = self::$storage->append('greetings.md', '**Start**' . PHP_EOL);

// At the end
$result = self::$storage->append('greetings.md', PHP_EOL . '**End**');

Copying or moving a file is also straightforward:

// Copy 'greetings.md' to 'greetings_copy.md'
$storage->copy('greetings.md', 'greetings_copy.md');

// Move 'greetings.md' to 'strings/greetings.md'
$storage->move('greetings.md', 'strings/greetings.md');

To delete a file, simply call delete:


Again, some adapters may also let you list the contents of a directory with the files and directories methods:

// Recursive (include sub-directories)
$files = $storage->files('/', true);
// Non-recursive (only specified directory)
$files = $storage->files('/');

// Recursive (include sub-directories)
$directories = $storage->directories('/', true);
// Non-recursive (only specified directory)
$directories = $storage->directories('/');

And also create and delete directories:

// Create directory

// Delete directory

As has been mentioned earlier, there are two included adapters: LocalAdapter and S3Adapter.

To create an instance of LocalAdapter you just need to specify its root directory:

use Caldera\Storage\Storage;
use Caldera\Storage\Adapter\LocalAdapter;

$adapter = new LocalAdapter( dirname(__DIR__) . '/output' );
$storage = new Storage($adapter);

While for S3Adapter you must specify your S3 credentials:

use Caldera\Storage\Storage;
use Caldera\Storage\Adapter\S3Adapter;

$bucket = getenv('S3_BUCKET') ?: '';
$access_key = getenv('S3_ACCESS_KEY') ?: '';
$secret_key = getenv('S3_SECRET_KEY') ?: '';

$adapter = new S3Adapter($bucket, $access_key, $secret_key);
$storage = new Storage($adapter);

The S3 adapter does not support the following operations:

  • files
  • directories
  • createDirectory
  • deleteDirectory