To create custom helper functions in Laravel 13, put them in a file such as app/helpers.php, wrap each one in if (! function_exists('name')), and register the file under autoload.files in composer.json. Run composer dump-autoload, and the functions are available everywhere: controllers, Blade views, jobs and tests.
This tutorial targets Laravel 13 (PHP 8.3 to 8.5). The code was written for this article and not executed in a live project, but only uses plain PHP and Composer features.
When should you use a helper function?
Helpers suit small, stateless utilities that you call from many places, such as formatting money or building a CSS class. If the logic needs dependencies, configuration or tests with mocks, create a service class or a Blade component instead. Many global functions make code harder to trace and risk name clashes with packages.
Step 1: How do you create the helpers file?
Create app/helpers.php. It is a plain PHP file, not a class.
<?php
use Illuminate\Support\Number;
use Illuminate\Support\Str;
if (! function_exists('money')) {
/**
* Format an amount stored in cents, e.g. 1999 => "$19.99".
*/
function money(int $cents, string $currency = 'USD'): string
{
return Number::currency($cents / 100, in: $currency);
}
}
if (! function_exists('initials')) {
/**
* Build initials from a full name, e.g. "Yasir Amin" => "YA".
*/
function initials(string $name, int $limit = 2): string
{
return collect(preg_split('/\s+/', trim($name)))
->filter()
->take($limit)
->map(fn ($part) => Str::upper(Str::substr($part, 0, 1)))
->implode('');
}
}
if (! function_exists('active_class')) {
/**
* Return a CSS class when the current route matches the pattern.
*/
function active_class(string $pattern, string $class = 'active'): string
{
return request()->routeIs($pattern) ? $class : '';
}
}The function_exists() guard prevents a fatal "cannot redeclare" error if a package defines a function with the same name or the file is loaded twice. Number::currency() needs the PHP intl extension; if it is missing, use number_format() instead.
Step 2: How do you register the file with Composer?
Open composer.json and add the file to autoload.files.
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
"app/helpers.php"
]
},Then regenerate the autoloader:
composer dump-autoloadComposer loads every file in files on each request, so keep the file small and free of heavy work.
Step 3: How do you use the helpers?
Call them like any built-in function.
// Controller or route
Route::get('/price', fn () => money(1999));
// Blade
<span>{{ money($order->total) }}</span>
<div class="avatar">{{ initials(auth()->user()->name) }}</div>
<a class="nav-link {{ active_class('dashboard') }}" href="{{ route('dashboard') }}">Dashboard</a>What is the alternative to global functions?
A static helper class loaded by PSR-4 needs no composer.json change and is easier to test and discover.
namespace App\Support;
use Illuminate\Support\Number;
class Format
{
public static function money(int $cents, string $currency = 'USD'): string
{
return Number::currency($cents / 100, in: $currency);
}
}
// usage
App\Support\Format::money(1999);In Blade you can import it with @use('App\Support\Format') and then call Format::money(...). Choose global functions for short, ubiquitous calls and classes for everything else.
How do you test a helper?
Create a unit test with php artisan make:test HelpersTest --unit.
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
class HelpersTest extends TestCase
{
public function test_initials_are_built_from_the_name(): void
{
$this->assertSame('YA', initials('Yasir Amin'));
$this->assertSame('A', initials(' ali ', 1));
}
}Because initials() uses Laravel's collect() and Str, run this as a feature-style test (extend Tests\TestCase) if the plain PHPUnit base class cannot find them in your setup.
Common mistakes
- Forgetting
composer dump-autoload. The function stays undefined until the autoloader is rebuilt. - No
function_existsguard. A name clash with a package causes a fatal error. - Generic names. Names such as
format()oruser()will collide eventually; prefix them if in doubt. - Heavy logic or database calls. Helpers should be tiny and predictable.
- Using the wrong path. The path in
composer.jsonis relative to the project root. - Not deploying the change. On the server, run
composer installordump-autoload --optimizeso the new file is registered.
How do you verify it works?
- Run
php artisan tinker. - Type
money(1999)and confirm the formatted price. - Type
initials('Yasir Amin')and confirmYA. - If you see "Call to undefined function", re-check the path and run
composer dump-autoloadagain.
FAQ
Where should I put the helpers file?
Anywhere Composer can reach. app/helpers.php is the usual choice.
Do I need a service provider?
No. Composer's files autoload is enough.
Can I use helpers in queued jobs?
Yes. Composer loads the file in every PHP process, including queue workers, but restart the workers after deploying changes.



