serendipity_hq/component-var-dumper-f
A Laravel component wrapper for Symfony VarDumper that gives you tidy, Blade-friendly dump and dd output in your views. Inspect variables with syntax highlighting and collapsible structure instead of messy var_dump results—handy for quick debugging.
composer require --dev serendipity_hq/component-var-dumper-f
The package ships no service provider and no config — it registers two global functions via Composer's files autoload, so requiring the autoloader is the entire setup:
<?php
require __DIR__.'/vendor/autoload.php';
dumpf($payload); // write to file, keep running
ddf($payload); // write to file, then exit
Where to look first: vendor/serendipity_hq/component-var-dumper-f/src/functions.php. That one file is the whole library. Read it before you use it — you need to know (a) the default target filename/path it uses, and (b) whether it accepts a path argument or reads a constant. Everything else in the package is a composer.json that pins a symfony/var-dumper range, which matters a lot given the package is archived.
First use case: a Symfony Console command or a plain CLI script whose stdout you actually care about. dump() to stdout corrupts machine-readable output (JSON, table rows, a pipe into jq), and in a while (true) worker it scrolls away instantly. dumpf() puts the value somewhere you can tail -f without touching stdout:
// src/Command/ImportCommand.php
protected function execute(InputInterface $input, OutputInterface $output): int
{
foreach ($this->reader->rows() as $i => $row) {
if ($row['sku'] === null) {
dumpf(['iteration' => $i, 'row' => $row], '/tmp/import-bad-rows.txt');
}
}
return Command::SUCCESS;
}
If you find yourself needing more than this, stop: the package is 2-star and archived, and the replacement is ~15 lines (see Gotchas).
Long-running workers and daemons. This is the strongest fit. In a worker, stdout is often captured by Supervisor/systemd, so dump() either bloats the log or gets swallowed. A file you can read after the fact is the difference between debugging and guessing.
while ($job = $queue->pop()) {
try {
$this->handle($job);
} catch (\Throwable $e) {
dd_file: dumpf(['job' => $job->id(), 'payload' => $job->payload(), 'ex' => $e]);
$queue->release($job);
}
}
Per-iteration / per-run filenames. Because you control the path, make each dump self-identifying instead of appending to one giant file:
$dump = sprintf('/tmp/dumps/%s-%d.txt', date('Ymd-His'), getmypid());
dumpf($state, $dump);
Cron and CI artifacts. Cron jobs have no attached terminal. Write into the build/workspace directory and upload it as an artifact — you get a real debug trail from a failed nightly import without redeploying instrumented code.
# .github/workflows/nightly.yml
- run: php bin/console app:nightly-import
- uses: actions/upload-artifact@v4
if: always()
with:
name: dumps
path: var/dumps/
Pair dumpf() with dump() while developing. Iterate interactively with dump(), then convert the ones you want to keep as dumpf() before committing. Keep the browser/console dumper for the fast loop and the file dumper for the paths you can't attach to.
Use ddf() only where exiting is safe. It is dd() semantics for a file target: dump then exit(1)-ish. That's perfect for a scratch CLI script, and a footgun in a command that holds open resources, inside a foreach you wanted to continue past, or anywhere inside a web request.
Wrap it in a project helper so the target directory is decided in one place rather than at 40 call sites:
// src/Dev/dumpf.php
function debug_to_file(mixed $value): void
{
static $path = null;
$path ??= rtrim($_SERVER['APP_DUMP_DIR'] ?? sys_get_temp_dir(), '/').'/app-dump.txt';
if (!is_dir(dirname($path))) {
mkdir(dirname($path), 0775, true);
}
dumpf($value, $path);
}
Reuse Symfony's dumper directly if you need control. The file dumper is just CliDumper writing to a stream, so you can bypass the package entirely when you need colors off, depth limits, or a custom handler:
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
$handle = fopen('/tmp/dump.txt', 'a');
(new CliDumper($handle))->dump((new VarCloner())->cloneVar($value));
It is archived. Treat it as vendored code, not a dependency. There will be no fix if a symfony/var-dumper major release breaks the pinned constraint — and since var-dumper is a transitive dep of the framework, a Symfony upgrade can fail composer update because of this package. Require it as --dev, and be prepared to drop it.
Global function autoload is the main risk. files autoload runs for every request, and dumpf/ddf occupy the global namespace with very generic names. Check for collisions before adding another helper package that does the same thing.
Pin down the default path. Relative paths resolve against the current working directory, which is not your project root when running under Supervisor, cron, or php -r. Always pass an absolute path.
ddf() halts the process. In a Symfony command that's usually fine; in a kernel.request listener, a Messenger handler, or a web request it is an outage. Grep for ddf( before merging.
No rotation, no truncation. Each call appends (or overwrites, depending on the package's file mode — verify in functions.php). Large objects, deep arrays, and objects holding a Doctrine\ORM\EntityManager will produce enormous dumps. CliDumper::setMaxItems/depth limits are your friend if you copy the mechanism yourself.
Write permissions in containers. /tmp is writable, the app directory usually is not (read-only root filesystem). Mount a var/dumps/ volume or write to sys_get_temp_dir().
.gitignore the output. dump.txt, var/dumps/, *.dump — somebody will otherwise commit a 40MB dump of a Doctrine entity graph.
Prefer dd()'s server-side alternatives where they fit. Symfony's dump() already supports VAR_DUMPER_FORMAT and a dump_server target, and symfony/var-dumper supports CliDumper to an arbitrary stream. If you're already on a modern Symfony, the framework can give you most of this without an archived dependency.
The 15-line replacement, if the constraint pin becomes a problem in CI:
// bootstrap/dump.php
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
if (!function_exists('dumpf')) {
function dumpf(mixed $value, string $file = '/tmp/dump.txt'): void
{
static $dumper = null;
$dumper ??= new CliDumper(fopen($file, 'a'));
$dumper->dump((new VarCloner())->cloneVar($value));
}
}
Verdict for day-to-day use: genuinely useful idea, trivially small surface, but archived with zero dependents. Adopt the pattern (file-backed VarDumper for CLI/worker debugging) confidently; adopt the dependency only in require-dev and only if composer why-not symfony/var-dumper shows no conflict. Budget the 15-line vendored helper as your exit path before you add the first dumpf() call.
How can I help you explore Laravel packages today?