覆盖 Laravel 5 辅助函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28474640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overwrite laravel 5 helper function
提问by guidsen
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).
我response()
经常使用帮助程序,我只是将数据与一条消息一起返回给用户。现在我还必须包含 http 状态代码,但我不想更改每个响应(无论如何这可能很糟糕)。
So I'm trying to overwrite the response()
helper function by creating my own helpers.php
within app/Http/helpers.php
.
所以我试图response()
通过helpers.php
在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.
当我将它添加到我的 Composer 文件时,它会首先从框架自动加载当前的 helpers.php,当我在 autload include in 之前添加它时,bootstrap/global.php
我将无法使用app()
和其他 Laravel 函数。
How would I be able to solve this issue? I just want to include the status code as well in the response array.
我将如何解决这个问题?我只想在响应数组中包含状态代码。
回答by Marty Aghajanyan
All Laravel helper functions written with this logic
所有 Laravel 辅助函数都用这个逻辑编写
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.
首先 Laravel 检查这个函数是否存在,如果存在,Laravel 不会再次定义这个函数(否则会抛出致命错误)。因此,如果您将在自动加载器包含vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
文件之前定义您的函数 ,您可以定义您的自定义响应函数。
Unfortunately there is no way to say composer load first your autoload.files
section, then laravel autoload.files
. But you can do small hack ...
不幸的是,没有办法说 composer 先加载你的autoload.files
部分,然后是 laravel autoload.files
。但是你可以做一些小黑客......
open bootstrap/autoload.php
file and include your file before autoloader
打开bootstrap/autoload.php
文件并在自动加载器之前包含您的文件
// file with your custom helper functions
require __DIR__.'/../app/app/Http/helpers.php';
require __DIR__.'/../vendor/autoload.php';
回答by Daniel Buckmaster
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 adviceof creating app/Http/helpers.php
and then adding it to bootstrap/autoload.php
like so:
我只需要这样做以覆盖now()
帮助程序,这样我就可以控制运行测试时的明显时间。我遵循了创建然后将其添加到这样的常规建议:app/Http/helpers.php
bootstrap/autoload.php
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.
这通常有效,因为正如 Marty 所说,只有在没有具有该名称的现有函数时才定义所有助手。所以上面两行加载你的自定义助手,然后执行所有供应商自动加载,包括 Laravel 的助手,你已经定义的函数优先。
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-filespackage. To quote from its readme:
但不幸的是,autoload.php
在用 Behat 测试时似乎没有使用,这就是我正在使用的。所以我需要一个替代解决方案。长话短说,确保文件在供应商文件之前自动加载的唯一简单方法是使用https://github.com/funkjedi/composer-include-files包。引用自述文件:
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.
在过去,简单地修改
bootstrap/autoload.php
以包含助手就足够了。然而,新版本的 PHPUnit 在执行 PHPUnit 引导文件之前包括 Composer Autoloader。因此,这种覆盖帮助程序的方法不再可行,因为它会在包含引导文件时触发致命错误。
So I installed this package using composer require funkjedi/composer-include-files
and then added this to composer.json
:
所以我安装了这个包composer require funkjedi/composer-include-files
,然后将它添加到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!
完成后,运行composer dump-autoload
以重新生成自动加载文件。现在覆盖在常规应用程序操作期间和运行测试时都有效!
回答by lukasgeiter
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)
我不打算直接回答您的问题,因为我不知道是否有解决方案(无需更改 Laravelhelpers.php
或重命名您的函数)
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');