Search by

melia / object-storage

melia

Lightweight PHP file-based object store with UUID persistence, lazy-loading references, in-memory cache, file locking, safe mode, and a simple viewer UI.

Package info

github.com/marvinGitHub/object-storage

pkg:composer/melia/object-storage

Statistics

Installs: 35

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

0.0.10 2026-10-28 18:57 UTC

This package is auto-updated.

Last update: 2026-11-05 09:32:14 UTC


README

Object Storage

ObjectStorage

Store PHP objects as they are — whole object graphs, by UUID, in plain files. No database, no schema, no mapping.

$uuid = $storage->store($order);          // the order, its customer and all its lines
$order = $storage->load($uuid);           // related objects are loaded lazily when you touch them
echo $order->customer->name;

ObjectStorage is a file-based object store for PHP. It persists your objects including everything they reference, loads related objects only when they are accessed, and keeps the data safe against crashes and concurrent access.

When to use it

  • Prototypes and small to medium applications that want to persist domain objects without designing tables first.
  • Caches and snapshots of computed or fetched data, with a lifetime per object.
  • Tools, CLI applications and background jobs that need durable state without running a database server.
  • Document-like data (configurations, drafts, workflow state) that is mostly loaded and stored as a whole.

It is not a replacement for a database when you need indexes, joins or ad-hoc queries over large amounts of data: queries are PHP callbacks that scan the stored objects of a class.

Features

Object graphs Stores an object and everything it references; every object gets its own UUID, shared and circular references are kept.
Lazy loading Referenced objects are loaded on first access and then replace their placeholder transparently.
Querying List and count objects per class, filter them with PHP callbacks, refine results step by step.
Lifetime Optional time-to-live per object, e.g. for caches.
Concurrency Shared and exclusive locks per object, based on symfony/lock (files, Redis, Memcached, databases, …).
Durability Crash-safe writes with checksums; interrupted writes are recovered, corrupted data puts the storage into a read-only safe mode.
Caching In-memory cache by default, any PSR-16 cache (APCu, Redis, …) can be plugged in.
Events Hooks for every operation, e.g. for audit logs, indexes or metrics.
Refactoring support Renamed classes can be mapped, unknown classes still load.
Tooling A CLI for inspection and maintenance, and a small web viewer for development.

Requirements

  • PHP 8.5 or newer with ext-json
  • Symfony 8 (symfony/console, symfony/cache, symfony/lock), installed with the package
  • A writable directory for the storage

Installation

composer require melia/object-storage

Quick start

<?php

use melia\ObjectStorage\ObjectStorage;
use melia\ObjectStorage\UUID\AwareInterface;
use melia\ObjectStorage\UUID\AwareTrait;

require __DIR__ . '/vendor/autoload.php';

class Customer implements AwareInterface
{
    use AwareTrait; // lets the storage write the UUID back into the object

    public function __construct(public string $name) {}
}

class Order implements AwareInterface
{
    use AwareTrait;

    /** @var string[] */
    public array $items = [];

    public function __construct(public mixed $customer) {}
}

$storage = new ObjectStorage(__DIR__ . '/var/storage');

// store: the order and the customer are stored as two objects
$order = new Order(new Customer('Ada'));
$order->items = ['keyboard', 'mouse'];
$uuid = $storage->store($order);

// load: the customer is loaded on first access
$order = $storage->load($uuid);
echo $order->customer->name; // Ada

// update and delete
$order->items[] = 'monitor';
$storage->store($order);
$storage->delete($uuid);

Continue with Getting started for the details of storing, loading and identifying objects.

Documentation

Topic What you will find
Getting started Creating a storage, storing, loading, updating and deleting objects, UUIDs
Concepts Object graphs, lazy loading, caching and what is stored on disk
Querying Listing, counting and filtering objects
Unique indexes Values no two objects of a class may share, like a UNIQUE constraint; finding objects by them
Search indexes Full-text search, filters and facets with exchangeable engines (Loupe included), managed in the viewer
Lifetime Expiring objects, e.g. for caches
Copying and moving Copying and moving objects between storages, in code, the CLI and the viewer
Concurrency Locks, read-modify-write, lock backends, multiple processes
Durability and safe mode Crash-safe writes, checksums, recovery and safe mode
Configuration Constructor options, caches, strategy and persistence policies
Events Reacting to storage operations
Serialization Which objects can be stored, hooks, renamed classes
Maintenance and tools CLI, viewer, rebuilding indexes, migrations
Internals For contributors: how loading and storing work, the naming of the methods

Examples

Complete scenarios, each runnable as is:

Changelog and license

Changes are documented in the Changelog. The library is licensed under the Apache License 2.0.