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 melia∖ObjectStorage∖ObjectStorage;

$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(Some∖ClassName::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.