Laravel has many great features that make it easy to work with arrays, paths, strings, routes, and other things — for example, your favorite dd()
function.
You can create your own functions for your Laravel application and PHP package using Composer to automatically import them.
If you are new to Laravel or PHP, let's go through the whole process of creating your own PHP functions that will be automatically loaded into Laravel.
To begin, you must include functions in the context of your Laravel application. Depending on your preferences, you can organize the storage of your files with functions where you want, here are a few suggested places:
app/helpers.php
app/Http/helpers.php
I prefer to store them so app/helpers.php
in the root of the application namespace.
To use your functions, you need to load them into runtime (application life cycle). At the beginning of my career, I often saw this code at the beginning of the file:
require_once ROOT . '/helpers.php';
PHP functions cannot be automatically loaded. However, we have a better solution using Composer than using require
or require_once
.
If you create a new Laravel project, you will see the autoload
and autoload-dev
parameters in the composer.json
file:
"autoload": { "classmap": [ "database/seeds", "database/factories" ], "psr-4": { "App\\": "app/" } }, "autoload-dev": { "psr-4": { "Tests\\": "tests/" } },
If we want to add our own file with functions, then Composer for this is the files
parameter (which consists of an array of file paths) which you can define inside the autoload
parameter:
"autoload": { "files": [ "app/helpers.php" ], "classmap": [ "database/seeds", "database/factories" ], "psr-4": { "App\\": "app/" } },
When you add a new path to the files
parameter, you need to update the auto-loader by running:
composer dump-autoload
Now, with each request, the helpers.php
file will be loaded automatically as Laravel loads the Composer auto downloader into public/index.php
:
require __DIR__.'/../vendor/autoload.php';
The definition of functions is not a difficult task, although there are a few caveats. All functions in Laravel are wrapped in a special check that excludes the possibility of collisions:
if (! function_exists('env')) { function env($key, $default = null) { // ... } }
Although there may be a catch, because we can perform a function in a situation when it was already defined, before we assigned it.
I prefer to use function_exists
to test my functions, but if you assign a function in the context of your application, you can opt out of function_exists
for testing.
If you skip the check, you will see a collision always, when your function overrides another, this can be useful.
In practice, collisions do not occur as often as you might think, but you must be sure that the name of your function is not very common. In addition, you can add a prefix to the name of your function, which will lower the chance of collisions.
I always liked how RoR (Ruby on Rails) made functions for paths and links if you defined a route for a resource. For example, the new_photo_path
, edit_photo_path
, etc. functions will be added to the photos
resource.
When I use resource routing in Laravel, I add several features that make it easier to work with routes in templates. In my implementation, I add functions that I transfer to the Eloquent model and that return the route to the resource, for example:
create_route($model); edit_route($model); show_route($model); destroy_route($model);
Here is how you can define the show_route
function in your app/helpers.php
(others will look like):
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 a code that helps to get the name of a resource based on naming conventions.
For example, here we get the name of the resource based on the model:
$model = new App\LineItem; plural_from_model($model); => line-items plural_from_model(new App\User); => users
Using these conventions, you can define routes for resources in the routes/web.php
:
Route::resource('line-items', 'LineItemsController'); Route::resource('users', 'UsersController');
After that in your template you can use functions like this:
<a href="{{ show_route($lineItem) }}"> {{ $lineItem->name }} </a>
And at the output you will receive the following HTML code:
<a href="http://localhost/line-items/1"> Line Item #1 </a>
Your Composer packages can also use your function file, for any functions you want to make available, in the project your package is used.
You will use the same approach for the composer.json
file, defining the files
parameter as an array of your function files.
Be sure to add function_exists()
to the test of your function so that the project using your code does not break due to a coliseum of names.
You must use the correct names for your functions, which will be unique, so you should consider using a short prefix if you are afraid that the name of your functions is too general.
Source: https://habr.com/ru/post/344342/
All Articles