Creating Your Own PHP Helpers in a Laravel Project

Published on by

Laravel provides many excellent helper functions that are convenient for doing things like working with arrays, file paths, strings, and routes, among other things like the beloved dd() function.

You can also define your own set of helper functions for your Laravel applications and PHP packages, by using Composer to import them automatically.

If you are new to Laravel or PHP, let’s walk through how you might go about creating your own helper functions that automatically get loaded by Laravel.

Creating a Helpers file in a Laravel App

The first scenario you might want to include your helper functions is within the context of a Laravel application. Depending on your preference, you can organize the location of your helper file(s) however you want, however, here are a few suggested locations:

  • app/helpers.php
  • app/Http/helpers.php

I prefer to keep mine in app/helpers.php in the root of the application namespace.

Autoloading

To use your PHP helper functions, you need to load them into your program at runtime. In the early days of my career, it wasn’t uncommon to see this kind of code at the top of a file:

require_once ROOT . '/helpers.php';

PHP functions cannot be autoloaded. However, we have a much better solution through Composer than using require or require_once.

If you create a new Laravel project, you will see an autoload and autoload-dev keys in the composer.json file:

"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},

If you want to add a helpers file, composer has a files key (which is an array of file paths) that you can define inside of autoload:

"autoload": {
"files": [
"app/helpers.php"
],
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},

Once you add a new path to the files array, you need to dump the autoloader:

composer dump-autoload

Now on every request the helpers.php file will be loaded automatically because Laravel requires Composer’s autoloader in public/index.php:

require __DIR__.'/../vendor/autoload.php';

Defining Functions

Defining functions in your helpers class is the easy part, although, there are a few caveats. All of the Laravel helper files are wrapped in a check to avoid function definition collisions:

if (! function_exists('env')) {
function env($key, $default = null) {
// ...
}
}

This can get tricky, because you can run into situations where you are using a function definition that you did not expect based on which one was defined first.

I prefer to use function_exists checks in my application helpers, but if you are defining helpers within the context of your application, you could forgo the function_exists check.

By skipping the check, you’d see collisions any time your helpers are redefining functions, which could be useful.

In practice, collisions don’t tend to happen as often as you’d think, and you should make sure you’re defining function names that aren’t overly generic. You can also prefix your function names to make them less likely to collide with other dependencies.

Helper Example

I like the Rails path and URL helpers that you get for free when defining a resourceful route. For example, a photos resource route would expose route helpers like new_photo_path, edit_photo_path`, etc.

When I use resource routing in Laravel, I like to add a few helper functions that make defining routes in my templates easier. In my implementation, I like to have a URL helper function that I can pass an Eloquent model and get a resource route back using conventions that I define, such as:

create_route($model);
edit_route($model);
show_route($model);
destroy_route($model);

Here’s how you might define a show_route in your app/helpers.php file (the others would look similar):

if (! function_exists('show_route')) {
function show_route($model, $resource = null)
{
$resource = $resource ?? plural_from_model($model);
 
return route("{$resource}.show", $model);
}
}
 
if (! function_exists('plural_from_model')) {
function plural_from_model($model)
{
$plural = Str::plural(class_basename($model));
 
return Str::kebab($plural);
}
}

The plural_from_model() function is just some reusable code that the helper route functions use to predict the route resource name based on a naming convention that I prefer, which is a kebab-case plural of a model.

For example, here’s an example of the resource name derived from the model:

$model = new App\LineItem;
plural_from_model($model);
// => line-items
 
plural_from_model(new App\User);
// => users

Using this convention you’d define the resource route like so in routes/web.php:

Route::resource('line-items', 'LineItemsController');
Route::resource('users', 'UsersController');

And then in your blade templates, you could do the following:

<a href="{{ show_route($lineItem) }}">
{{ $lineItem->name }}
</a>

Which would produce something like the following HTML:

<a href="http://localhost/line-items/1">
Line Item #1
</a>

Packages

Your Composer packages can also use a helpers file for any helper functions you want to make available to projects consuming your package.

You will take the same approach in the package’s composer.json file, defining a files key with an array of your helper files.

It’s imperative that you add function_exists() checks around your helper functions so that projects using your code don’t break due to naming collisions.

You should choose proper function names that are unique to your package, and consider using a short prefix if you are afraid your function name is too generic.

Learn More

Check out Composer’s autoloading documentation to learn more about including files, and general information about autoloading classes.

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Asymmetric Property Visibility in PHP 8.4 image

Asymmetric Property Visibility in PHP 8.4

Read article
Access Laravel Pulse Data as a JSON API image

Access Laravel Pulse Data as a JSON API

Read article
Laravel Forge adds Statamic Integration image

Laravel Forge adds Statamic Integration

Read article
Transform Data into Type-safe DTOs with this PHP Package image

Transform Data into Type-safe DTOs with this PHP Package

Read article
PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell image

PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell

Read article
Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3 image

Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3

Read article