I'm using the response()
helper very often and I just return the data with a message to the user. Now I have to include the http status code as well, but I don't want to change every response (which is likely bad anyway).
So I'm trying to overwrite the response()
helper function by creating my own helpers.php
within app/Http/helpers.php
.
When I add it to my composer files, it does autoload the current helpers.php from the framework first and when I add it before the autload include in bootstrap/global.php
I wont be able to use the app()
and other Laravel functions.
How would I be able to solve this issue? I just want to include the status code as well in the response array.
All Laravel helper functions written with this logic
if ( ! function_exists('response'))
{
function response($content = '', $status = 200, array $headers = array())
{
// function body
}
}
for first Laravel check is this function exists, if it exists, Laravel will not define this function again(otherwise it will throw fatal error).
So if you will define your function before autoloader include vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
file,
you can define your custom response function.
Unfortunately there is no way to say composer load first your autoload.files
section, then laravel autoload.files
. But you can do small hack ...
open bootstrap/autoload.php
file and include your file before autoloader
// file with your custom helper functions
require __DIR__.'/../app/app/Http/helpers.php';
require __DIR__.'/../vendor/autoload.php';
I'm not going to directly answer your question since I don't know if there's a solution (without changing Laravels helpers.php
or renaming your function)
However there is a solution from the framework for this common use case. Response Macros
You can define a macro (this is done in a service provider)
Response::macro('foo', function($value){
// do some stuff
return Response::make($value);
});
And you can use it like this:
return response()->foo('bar');
I've just had to do this in order to override the now()
helper so I can control the apparent time when running tests. I followed the regular advice of creating app/Http/helpers.php
and then adding it to bootstrap/autoload.php
like so:
require __DIR__.'/../app/Http/helpers.php'; // added
require __DIR__.'/../vendor/autoload.php';
This usually works because as Marty says, all helpers are only defined if there's not an existing function with that name. So the two lines above load your custom helpers, then perform all vendor autoloading, which includes Laravel's helpers, and your already-defined function takes precedence.
But unfortunately, autoload.php
doesn't seem to be used when testing with Behat, which is what I'm using. So I needed an alternative solution. Long story short, the only easy way to ensure that files get autoloaded before vendor files is by using the https://github.com/funkjedi/composer-include-files package. To quote from its readme:
In the past simply modifying bootstrap/autoload.php
to include helpers was sufficient. However new versions of PHPUnit include the Composer Autoloader prior to executing the PHPUnit bootstrap file. Consequently this method of overriding helpers is no longer viable as it will trigger a fatal error when your bootstrap file is included.
So I installed this package using composer require funkjedi/composer-include-files
and then added this to composer.json
:
"extra": {
"include_files": [
"app/Http/helpers.php"
]
},
Once that's done, run composer dump-autoload
to regenerate the autoload files. Now the overrides work both during regular app operation, and when running tests!