覆盖 laravel 5 辅助函数
Posted
技术标签:
【中文标题】覆盖 laravel 5 辅助函数【英文标题】:Overwrite laravel 5 helper function 【发布时间】:2015-04-13 00:31:12 【问题描述】:我经常使用response()
助手,我只是将数据和消息一起返回给用户。现在我还必须包含 http 状态代码,但我不想更改每个响应(无论如何这可能很糟糕)。
所以我试图通过在app/Http/helpers.php
中创建我自己的helpers.php
来覆盖response()
辅助函数。
当我将它添加到我的作曲家文件时,它会首先从框架中自动加载当前的 helpers.php,当我在 bootstrap/global.php
中的 autload 包含之前添加它时,我将无法使用 app()
和其他 Laravel功能。
我该如何解决这个问题?我只想在响应数组中包含状态代码。
【问题讨论】:
【参考方案1】:在 Laravel 5.5+ 中,laravel 没有 bootstrap/autoload.php
你必须使用像https://github.com/funkjedi/composer-include-files这样的包
怎么做:
第一次运行命令
composer require funkjedi/composer-include-files
然后在 composer.json 中添加你的辅助函数文件路径
"extra":
"include_files": [
"/path/to/file/you/want/to/include",
"/path/to/another/file/you/want/to/include"
]
,
那就做吧
composer dump-autoload
【讨论】:
查看相关的laravel想法问题:github.com/laravel/ideas/issues/1569【参考方案2】:我只需要这样做才能覆盖now()
帮助器,这样我就可以控制运行测试时的明显时间。我按照 regular advice 创建 app/Http/helpers.php
然后将其添加到 bootstrap/autoload.php
如下:
require __DIR__.'/../app/Http/helpers.php'; // added
require __DIR__.'/../vendor/autoload.php';
这通常是有效的,因为正如 Marty 所说,只有在没有具有该名称的现有函数时才定义所有帮助程序。所以上面两行加载了你的自定义助手,然后执行所有供应商自动加载,包括 Laravel 的助手,你已经定义的函数优先。
但不幸的是,autoload.php
在使用 Behat 进行测试时似乎没有被使用,这正是我正在使用的。所以我需要一个替代解决方案。长话短说,确保在供应商文件之前自动加载文件的唯一简单方法是使用 https://github.com/funkjedi/composer-include-files 包。引用自述文件:
在过去,只需修改
bootstrap/autoload.php
以包含帮助程序就足够了。然而,新版本的 PHPUnit 在执行 PHPUnit 引导文件之前包含 Composer Autoloader。因此,这种覆盖帮助程序的方法不再可行,因为在包含引导文件时会触发致命错误。
所以我使用composer require funkjedi/composer-include-files
安装了这个包,然后将它添加到composer.json
:
"extra":
"include_files": [
"app/Http/helpers.php"
]
,
完成后,运行composer dump-autoload
以重新生成自动加载文件。现在,覆盖在常规应用操作期间和运行测试时都有效!
【讨论】:
这是我能够强制 Lumen 中的url()
助手生成 https URL 的唯一可能方式。【参考方案3】:
使用此逻辑编写的所有 Laravel 辅助函数
if ( ! function_exists('response'))
function response($content = '', $status = 200, array $headers = array())
// function body
Laravel 首先检查这个函数是否存在,如果存在,Laravel 将不再定义这个函数(否则会抛出致命错误)。
因此,如果您要在自动加载器包含 vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
文件之前定义您的函数,
您可以定义您的自定义响应函数。
不幸的是,没有办法说作曲家首先加载你的 autoload.files
部分,然后是 laravel autoload.files
。但是你可以做一些小技巧......
打开bootstrap/autoload.php
文件并在自动加载器之前包含您的文件
// file with your custom helper functions
require __DIR__.'/../app/app/Http/helpers.php';
require __DIR__.'/../vendor/autoload.php';
【讨论】:
您可以在函数中使用应用实例,因为您稍后会在应用实例存在时调用函数。【参考方案4】:我不打算直接回答您的问题,因为我不知道是否有解决方案(无需更改 Laravel helpers.php
或重命名您的函数)
但是,对于这个常见的用例,框架有一个解决方案。 Response Macros
您可以定义一个宏(这是在服务提供者中完成的)
Response::macro('foo', function($value)
// do some stuff
return Response::make($value);
);
你可以这样使用它:
return response()->foo('bar');
【讨论】:
如果您需要更多帮助来编写实际的宏,我需要知道它到底应该做什么...... 嗯,我知道可以这样做,但我想知道是否有人有解决方案,而不是仅仅更改每种方法或创建另一种方法。 Laravel 对于这类东西应该是灵活的.. 无论哪种方式,这都是解决问题的好方法。像这样的助手对于大多数使用 Laravel 的人来说是无关紧要的。响应门面和具体的响应类比助手要好得多。以上是关于覆盖 laravel 5 辅助函数的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5.4 和 WordPress 4.7 的辅助函数 __() 冲突