calebporzio/laravel-helpers-file
A grab-bag of handy Laravel helper functions packed into one file by Caleb Porzio. Drop it into any project for shortcuts to common tasks, cleaner code, and less boilerplate—lightweight, framework-native utilities you can call right away.
Read the source before you install. The package's own marketing copy is wrong — it does not ship file-system helpers. Its entire job is registering a project-level helpers.php with Composer's autoload.files array via a service provider. The first thing to do is open the provider in vendor/calebporzio/laravel-helpers-file/src/ and answer three questions:
app/helpers.php? helpers.php at the root?)?file_exists-guard before requiring, or hard-require?Those answers determine everything below. If the guard is missing, a missing file becomes a boot-time fatal.
Minimal steps.
composer require calebporzio/laravel-helpers-file
# create the file at whatever path the provider expects
composer dump-autoload -o
Auto-discovery registers the provider — no config/app.php edit on Laravel 5.5+.
Verify it actually loaded before writing any real code:
php -r "require 'vendor/autoload.php'; var_dump(function_exists('your_test_helper'));"
First use case. A formatting helper you call from Blade and from a couple of controllers — the classic money() / initials() / ordinal() trio that doesn't justify a class:
<?php // app/helpers.php
if (! function_exists('money')) {
function money(int $cents, string $symbol = '$'): string
{
return $symbol . number_format($cents / 100, 2);
}
}
{{ money($invoice->total_cents) }}
That's the whole value proposition: no use statement, no facade, no service. Reach for it when the function is genuinely cross-cutting and trivially pure — and stop there.
Keep the file pure and dependency-free. This is the single most important pattern. The file is required by Composer before Laravel boots, so anything at file scope runs on every HTTP request, every queue worker, every scheduler tick, and every artisan invocation — with no container, no config, no DB.
// NEVER at file scope
$rate = config('billing.tax_rate'); // container not booted
putenv('HELPER_LOADED=1'); // side effect on every process
// Fine — the body runs later, after boot, when actually called
function tax_rate(): float
{
return (float) config('billing.tax_rate', 0.0);
}
Function bodies execute lazily at call time, when the container is fully available. Function declarations and top-level statements execute at autoload. Keep the two mentally separate.
Guard every declaration with function_exists(). Always — not just for names you think are unusual. Two packages declaring str_slug() is a fatal error with no stack trace that makes sense, and the file is loaded so early that nothing catches it.
Respect the one-file constraint. If the provider hardcodes a single path, that's your organizational limit. If helpers outgrow one file:
"autoload": { "files": ["app/helpers/formatting.php", "app/helpers/strings.php"] }
helpers.php that require_onces siblings — but then you're maintaining the wiring the package was meant to save you.Treat composer.json (or the vendor provider) as the source of truth, not the file. A new dev adding app/helpers.php without composer require gets a silent no-op. Make the dependency visible in the README, or better, put a one-line comment at the top of helpers.php explaining how it gets loaded.
Bake the dump into the build. CI and Dockerfiles that run composer install --no-dev will regenerate the autoloader; make sure helpers.php is committed and present at that moment.
COPY . /app
RUN composer install --no-dev --optimize-autoloader
Give static analysis something to chew on. Functions in a files-autoloaded file are invisible to PHPStan/Psalm/PHPStorm unless you tell them:
# phpstan.neon
parameters:
scanFiles:
- app/helpers.php
Otherwise you get a wall of false "undefined function" errors and developers start adding @phpstan-ignore lines.
Testing is free. Because Composer's files entries load with vendor/autoload.php, helpers are available in every PHPUnit/Pest test — including ones that don't boot the framework. Just call them.
This package is archived (last release 2020-09-08, "Support Laravel 8") with zero dependents. No compatibility testing against Laravel 10/11/12 or PHP 8.2+, no security response path, no maintainer. For a long-lived app, the honest recommendation is to skip it and put one line in composer.json:
"autoload": { "files": ["app/helpers.php"] }
That is functionally identical, survives framework upgrades unconditionally, and adds zero supply-chain surface. If you've found this package in an existing app, replacing it is a ten-minute PR. If you're evaluating it fresh, the value is the pattern, not the artifact — and the pattern is one line.
Silent no-op is the default failure mode. Installed but file at the wrong path → helpers never load → the error surfaces days later as Call to undefined function. The fix is always composer dump-autoload -o, because Composer snapshots the files list at dump time — creating helpers.php after install does nothing until you re-dump. Write that sentence into your onboarding doc now.
Boot-path blast radius is total. A syntax error, a duplicate declaration, or a stray use statement at the top of helpers.php takes down HTTP, queues, scheduler, and artisan simultaneously. A ~60-line file causes a full outage. Mitigate with:
php -l app/helpers.php # in CI, and in a pre-commit hook
Don't namespace the functions. The entire point is global availability; App\Helpers\money() defeats it. But do pick distinctive names — money(), ordinal(), initials() are fine; format(), str(), value() will collide with something.
Missing file at require time is a hard fatal, not a warning — Composer's generated autoloader just requires the path. If your deploy pipeline ever excludes app/helpers.php (a .dockerignore typo, a bad rsync filter), the app dies at bootstrap with a stack trace pointing into vendor/composer/. The smoke test in Getting Started catches this in one second; run it in CI.
The service provider is the extension point — and it's also the thing to delete. If the package's path is wrong for your project layout, subclassing or copying the provider to change it is more work than inlining the files entry. Only bother if you're vendoring the package wholesale for policy reasons, in which case pin the tag, mirror it privately, and record an exit condition in an ADR.
Debugging checklist, in order:
composer show calebporzio/laravel-helpers-file # installed + which tag
grep -r "helpers" vendor/composer/autoload_files.php # is the entry registered?
composer dump-autoload -o # if not, or if stale
php -r "require 'vendor/autoload.php'; \
var_dump(function_exists('money'));" # does it actually load?
The organizational gotcha outlasts the technical ones. A helpers file grows monotonically because adding a global function is frictionless. Set the norm while the file is small: pure, prefixed, guarded, one file, and anything that needs the container or a dependency becomes a class instead. Laravel's Str, Arr, Collection, and once() already cover most of what people reach for — check those first.
How can I help you explore Laravel packages today?