Back in the day I used to load my helpers.php
file through composers files
array. That would still work absolutely fine, however I decided to move them in to the app directory and auto-load them with a service provider to take a more organizational approach.
This way I can organize my helpers by file name, and when I place them in my pre-configured directory I have global availability to the methods inside them.
So the first step is to create a new service provider called HelperServiceProvider
:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
class HelperServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function boot(): void
{
$rdi = new RecursiveDirectoryIterator(app_path('Helpers'.DIRECTORY_SEPARATOR.'Global'));
$it = new RecursiveIteratorIterator($rdi);
while ($it->valid()) {
if (
! $it->isDot() &&
$it->isFile() &&
$it->isReadable() &&
$it->current()->getExtension() === 'php' &&
strpos($it->current()->getFilename(), 'Helper')
) {
require $it->key();
}
$it->next();
}
}
}
Then create the directory which you have specified, in my case app/Helpers/Global
.
Now any file I place in app/Helpers/Global
will be auto-loaded for me, and will consist of specifically one-off functions, and not classes. Classes I would place in app/Helpers/XXXX
depending on the category. These would not be auto-loaded but are still good to have all in one place.
From there you want to load your new service provider in your app.php
service providers array:
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
...
App\Providers\HelperServiceProvider::class,
...
Finally, create your first helper file:
For example, I usually create a GeneralHelper for things I can't find another category for:
app/Helpers/Global/GeneralHelper.php
<?php
use Carbon\Carbon;
if (! function_exists('appName')) {
/**
* Helper to grab the application name.
*
* @return mixed
*/
function appName()
{
return config('app.name');
}
}
if (! function_exists('carbon')) {
/**
* Create a new Carbon instance from a time.
*
* @param $time
*
* @return Carbon
* @throws Exception
*/
function carbon($time)
{
return new Carbon($time);
}
}
From this file I have access to appName()
and carbon()
from anywhere without having to load any classes:
I definitely use this approach sparingly as I don't want to have too much extra overhead. However, I've had projects with dozens and have yet to notice a difference even on a $5 droplet.