DEV Community

Cover image for Persist Large Object Graphs in PHP
Marvin Elia Hoppe
Marvin Elia Hoppe

Posted on

Persist Large Object Graphs in PHP

Tired of spinning up a DB for small tools? You can persist PHP objects to disk with lazy loading, TTLs, and safe writes using melia/object-storage. It’s fast to adopt, crash-safe, and keeps memory low.

What it is

  • File-backed storage for PHP objects
  • UUID-based references and lazy loading
  • Per-object TTL/expiration
  • Atomic writes and locking
  • Class stubs for fast listing by class
  • Optional in-memory cache

When to use

  • CLIs, daemons, small web apps, plugins
  • Prototypes or self-hosted tools with a writable directory
  • Complex object graphs without a full database

When not to

  • You need queries/joins across large datasets
  • Multi-host concurrent writes without a distributed lock

Quickstart

Install

composer require melia/object-storage
Enter fullscreen mode Exit fullscreen mode

Store and load

<?php
use meliaObjectStorageObjectStorage;

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

$note = (object)['title' => 'Hello', 'body' => 'World'];
$uuid = $storage->store($note);

$loaded = $storage->load($uuid);
echo $loaded->title; // Hello
Enter fullscreen mode Exit fullscreen mode

Lazy references

<?php
$owner = (object)['email' => 'owner@example.com'];
$ownerId = $storage->store($owner);

$team = (object)['name' => 'Team', 'owner' => $owner];
$teamId = $storage->store($team);

$loaded = $storage->load($teamId);
$ownerObj = $loaded->owner->getObject(); // resolved on access
Enter fullscreen mode Exit fullscreen mode

TTL and expiration

<?php
$session = (object)['user' => 'alice'];
$id = $storage->store($session, ttl: 60); // 60s
$storage->setExpiration($id, new DateTimeImmutable('+10 minutes'));
Enter fullscreen mode Exit fullscreen mode

List by class

<?php
foreach ($storage->list(SomeClassName::class) as $uuid) {
    // handle UUIDs of that class
}
Enter fullscreen mode Exit fullscreen mode

Searching objects

<?php
foreach ($storage->match(function (object $object) {
    return true;
}) as $uuid => $object) {
    // handle UUIDs of that class
}
Enter fullscreen mode Exit fullscreen mode

How it works

  • Graphs become JSON + metadata with UUID pointers
  • Lazy references load only when needed
  • Atomic writes + locks reduce corruption
  • Checksums avoid unnecessary rewrites

Practical tips

  • Use a fast, writable storage directory
  • Run a periodic GC for expired objects
  • Single host by default; add a distributed lock for multi-host
  • Inject a PSR-16 cache for hot objects

Takeaway For small and embedded PHP apps, file-backed object storage with lazy refs and TTLs can replace a database. Install, store, load—done.

Top comments (4)

Collapse
 
xwero profile image
david duymelinck • Edited

I see you put a lot of effort in the library.

I'm wondering if you have considered SQLite as an option, before starting the library?
I can understand you don't want a Postgresql or a Redis or a MongoDB.
SQLite is just one file, with all the benefits that come with using SQL.

Collapse
 
melia72 profile image
Marvin Elia Hoppe

Hello david,
thank you for taking your time writing a feedback.

Yes i thought about using SQLLite too. But the main idea behind my library is to store / load any object without creating a schema or care about hydration.
I know my library is risky for schema drifts and indxing is also not supported.
But i think this can be solved somehow in future.

I also wanted to challenge me and see what is possible. Maybe some developers like to use it for their prototypes or something else.

I just like to share what i have done, since i think the code quality is decent and the library itself useful.

Best regards
Elia

Collapse
 
xwero profile image
david duymelinck

I understand you want to challenge yourself, and you are proud of your accomplishment.

I just see more potential problems with files than with sqlite.

Thread Thread
 
melia72 profile image
Marvin Elia Hoppe

Thats partially true. When you think about databases and solid libraries. All started from scratch. They have been improved over time. I want this for my library too.
You would be right to say, you should consider using it for production. This of course i would not recommend too since its in an early stage and needs more tests and hardening.