Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Compress Json Laravel Package

inkrot/php-compress-json

A lightweight PHP library that compresses and minifies JSON by stripping whitespace and redundant formatting, shrinking payloads for APIs, storage, and caching. Simple to install, framework-agnostic, and built to reduce JSON size without altering the underlying data.

Deep Wiki
Context7

Getting Started

1. Install and read the source (10 minutes). It's a single-purpose, low-star package, so vendor/inkrot/php-compress-json/src/ is almost certainly a handful of classes — read all of it before writing a line of application code. Confirm the exact namespace and whether the entry point is a static facade (CompressJson::compress()/decompress()) or an instantiable Compressor. Everything below assumes that shape; adjust names to match.

composer require inkrot/php-compress-json

2. Sanity-check it against your real data. Don't benchmark with {"a":1}. Pull one row from the table you intend to compress and measure:

$raw = json_encode($model->payload);
$packed = CompressJson::compress($model->payload);

printf("raw=%d packed=%d ratio=%.2f\n", strlen($raw), strlen($packed), strlen($packed) / strlen($raw));

If the ratio isn't below ~0.7 on your actual payloads, stop — the integration cost isn't worth it.

3. First use case: one fat json/longtext column. The classic fit is webhook payloads, third-party API snapshots, audit diffs, or settings blobs where rows are large, write-once, read-rarely, and never queried by their contents. Start with exactly one model and one column.

4. Check for a config/publish step. If there's no config/ directory, there's nothing to publish — don't go looking for php artisan vendor:publish.

Implementation Patterns

Eloquent cast — the default pattern. Wrap the package in a CastsAttributes so the rest of the app sees plain PHP arrays and never touches the compression API. This is the only place the package should be referenced.

class CompressedJson implements CastsAttributes
{
    public function get($model, $key, $value, $attributes): ?array
    {
        return $value === null ? null : CompressJson::decompress($value);
    }

    public function set($model, $key, $value, $attributes): ?string
    {
        return $value === null ? null : CompressJson::compress($value);
    }
}
protected $casts = ['payload' => CompressedJson::class];

Version the payload before you need to. The moment you change compression level or swap libraries, old rows become unreadable. Prefix with a scheme byte and branch on read:

return match ($value[0] ?? null) {
    '1' => CompressJson::decompress(substr($value, 1)),
    '{', '[' => json_decode($value, true), // legacy plain JSON
    default => throw new RuntimeException('Unknown payload encoding'),
};

Backfill with a queued, chunked command. Add the new column alongside the old one, dual-read ($model->payload_compressed ?? $model->payload), backfill via chunkById(500) dispatched as a job, then drop the old column in a later deploy. Never do a single UPDATE over the whole table on MySQL — it'll lock and blow up the binlog.

Keep the filterable fields out. Extract anything you'd ever where() on into real, indexed columns at write time. Compression is for the long tail of the payload, not for its queryable head.

$model->fill([
    'event' => $payload['type'],          // indexed, queryable
    'occurred_at' => $payload['created'], // indexed
    'payload' => $payload,                // compressed blob
]);

Queue and cache payloads. The same call is useful outside the DB: compressing a large array before dispatch() keeps your jobs table and Redis memory down, and Cache::put('snapshot:'.$id, CompressJson::compress($data), 3600) meaningfully reduces Redis footprint for large values.

Gotchas and Tips

  • Small payloads get bigger. Base64 and gzip headers add overhead; anything under roughly 1–2 KB may inflate. Add a size threshold inside the cast and store plain JSON (with the {/[ sniff from above) when compression would lose.
  • Base64 vs binary matters more than you think. If the package returns raw gzip bytes, do not put it in a TEXT column with a utf8 collation — MySQL will mangle it. Use LONGBLOB/BLOB and a binary cast, or force the package into base64 output if it supports it. Pick one and be consistent per column.
  • Don't double-encode. CompressJson::compress(json_encode($array)) is a common mistake — pass arrays if the package accepts them, and assert in tests that decompress round-trips to an identical array, not a JSON string.
  • You lose all JSON querying. whereJsonContains, ->path, generated columns over JSON paths, and MySQL JSON functions are all gone on this column. If you need any of that, this is the wrong tool for that column.
  • Debugging. When a read fails, log strlen($raw), strlen($packed), and the first 16 bytes of the column (bin2hex(substr($value,0,16))) — that instantly tells you base64 vs gzip (gzip starts 1f8b) vs plain JSON vs a truncated/corrupted row.
  • Check the compressor before you trust the ratio. If it turns out to be plain gzcompress, you can drop the dependency and call gzcompress(json_encode($data), 6) directly. Keep the package behind your own JsonCompressor interface so swapping it out later is a one-file change — a 10-star, single-author, BSD-2 dependency shouldn't be called from 30 places.
  • Exports and backups become unreadable. mysqldump is fine, but anyone doing SELECT in a SQL client sees noise. Document the encoding in the model or a README, and consider a small php artisan payload:decode {id} helper for support work.
  • No streaming, no partial reads. These columns buffer the whole decompressed payload into memory. Fine for a few KB; watch out if a handful of rows genuinely hit megabytes, especially on PHP-FPM memory_limit during a report that loads many of them.
  • Compression level is a config knob you probably can't reach. If the package hardcodes a level, that's acceptable; if it exposes one, set it to 6 and leave it — the CPU/latency tradeoff above that is rarely worth it for web request paths.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route