view.blade.php
<p>Foo Formated text: {{ fooFormatText($text) }}</p>
它们基本上是文本格式化函数。我应该如何定义全局可用的辅助函数,例如fooFormatText()
?
view.blade.php
<p>Foo Formated text: {{ fooFormatText($text) }}</p>
它们基本上是文本格式化函数。我应该如何定义全局可用的辅助函数,例如fooFormatText()
?
helpers.php
文件,并使用composer加载它:"autoload": {
"classmap": [
...
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/helpers.php" // <---- ADD THIS
]
},
composer.json
文件中添加后,运行以下命令:composer dump-autoload
helpers.php
文件放在app
目录下(因为它不是PSR-4命名空间类文件),你可以像laravel.com
网站一样将其存储在bootstrap
目录中。记得在composer.json
文件中设置它:in the bootstrap directory。"files": [
"bootstrap/helpers.php"
]
此答案适用于 Laravel 中的一般自定义类。有关更 Blade 特定的答案,请参见Laravel 5中的自定义 Blade 指令。
步骤1:创建您的 Helpers(或其他自定义类)文件,并为其提供相匹配的命名空间。编写您的类和方法:
<?php // Code within app\Helpers\Helper.php
namespace App\Helpers;
class Helper
{
public static function shout(string $string)
{
return strtoupper($string);
}
}
第二步: 创建别名:
<?php // Code within config/app.php
'aliases' => [
...
'Helper' => App\Helpers\Helper::class,
...
第三步:在项目根目录下运行composer dump-autoload
第四步:在您的Blade模板中使用它:
<!-- Code within resources/views/template.blade.php -->
{!! Helper::shout('this is how to use autoloading correctly!!') !!}
额外加分项:可以在你的 Laravel 应用程序中的任何地方使用这个类:
<?php // Code within app/Http/Controllers/SomeController.php
namespace App\Http\Controllers;
use Helper;
class SomeController extends Controller
{
public function __construct()
{
Helper::shout('now i\'m using my helper class in a controller!!');
}
...
来源: http://www.php-fig.org/psr/psr-4/
原因: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/ClassLoader.php
自动加载的起源: http://php.net/manual/en/language.oop5.autoload.php
composer dump-autoload
命令之前,您需要运行:php artisan config:cache
来清除文件 config/app.php
的缓存。然后它就会起作用。 - Axel Paris我的最初想法也是使用composer自动加载,但这对我来说并不像Laravel 5。Laravel 5大量使用服务提供者(Service Providers),它可以引导您的应用程序。
首先,在我的app
目录中创建了一个名为Helpers
的文件夹。然后在Helpers
文件夹中添加了我想要添加的函数文件。拥有多个文件的文件夹可以避免一个过长且难以管理的大文件。
接下来,我通过运行artisan命令创建了一个HelperServiceProvider.php
文件:
php artisan make:provider HelperServiceProvider
register
方法中,我添加了这段代码片段。public function register()
{
foreach (glob(app_path().'/Helpers/*.php') as $filename){
require_once($filename);
}
}
config/app.php
中。'providers' => [
'App\Providers\HelperServiceProvider',
]
现在你的Helpers
目录中的任何文件都已加载并准备好使用。
更新于2016-02-22
这里有很多好的选择,但如果我的答案适合您,我已经为包含这种方式的帮助程序制作了一个软件包。您可以使用该软件包进行灵感,也可以随意使用Composer下载它。它具有一些我经常使用的内置助手(默认情况下全部未激活),并允许您使用简单的Artisan生成器创建自己的自定义助手。它还解决了一个回答者提出的使用映射器的建议,并允许您明确定义要加载的自定义助手,或者默认情况下自动加载helper目录中的所有PHP文件。非常感谢您的反馈和PR!
composer require browner12/helpers
Github: browner12/helpers
GitHub: browner12/helpers
start.php
文件中注册文件(这并不是很好,但暂时起到了作用)。您是否有关于加载多个文件的其他建议? - Andrew Brown这是 JeffreyWay
在这个Laracasts讨论中提出的建议。
app/Http
目录下创建一个 helpers.php
文件并添加你的函数。composer.json
的 autoload
块中添加 "files": ["app/Http/helpers.php"]
。composer dump-autoload
。app/helpers.php
或app/Helpers/
似乎更合适。 - sepehrcomposer dump-autoload
的选项,那该怎么办呢? - user3201500composer dump-autoload
,您可以按照此操作:http://developed.be/2014/08/29/composer-dump-autoload-laravel/ - itsazzad在SO和Google上筛选了各种答案后,我仍然找不到最佳方法。大多数答案建议我们离开应用程序,依赖于第三方工具Composer来完成这项工作,但我不相信为了包含一个文件而将应用程序与工具进行耦合是明智的。
Andrew Brown的回答 最接近我认为应该采取的方法,但是(至少在5.1中),服务提供商步骤是不必要的。Heisian的回答 强调了使用PSR-4
,让我们更近了一步。这是我在视图中实现帮助器的最终方式:
首先,在应用目录中的任何位置创建一个帮助器文件,并指定名称空间:
namespace App\Helpers;
class BobFinder
{
static function bob()
{
return '<strong>Bob?! Is that you?!</strong>';
}
}
接下来,在config\app.php
文件中的aliases
数组中为你的类取别名:
Next, alias your class in config\app.php
, in the aliases
array:
'aliases' => [
// Other aliases
'BobFinder' => App\Helpers\BobFinder::class
]
这应该就是你需要做的全部内容了。 PSR-4
和别名会将 Helper 暴露给你的视图,因此在视图中,如果你输入:
{!! BobFinder::bob() !!}
它应该输出:
<strong>Bob?! Is that you?!</strong>
{!! bob() !!}
。我将继续搜索并查看是否可能实现。 - heisianbob()
成为真正的全局函数并不明智。命名空间是有其存在的意义的,我们不应该将bob()
与基本的PHP函数混在一起调用。我会将你的别名代码添加到我的代码中 - 谢谢! - heisian是的,还有另一种方法可以实现这个功能!
步骤1: 注册一个自定义的Blade指令:
<?php // code in app/Providers/AppServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Blade; // <-- This is important! Without it you'll get an exception.
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// Make a custom blade directive:
Blade::directive('shout', function ($string) {
return trim(strtoupper($string), '(\'\')');
});
// And another one for good measure:
Blade::directive('customLink', function () {
return '<a href="#">Custom Link</a>';
});
}
...
第二步:使用您的自定义 Blade 指令:
<!-- // code in resources/views/view.blade.php -->
@shout('this is my custom blade directive!!')
<br />
@customLink
输出:
这是我的自定义 Blade 指令!
自定义链接
来源:https://laravel.com/docs/5.1/blade#extending-blade
更多阅读:https://mattstauffer.co/blog/custom-conditionals-with-laravels-blade-directives
如果您想学习如何最好地制作可以在任何地方使用的自定义类,请参见Laravel 5 中的自定义类,简单易行的方法
这是我的HelpersProvider.php文件:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class HelperServiceProvider extends ServiceProvider
{
protected $helpers = [
// Add your helpers in here
];
/**
* Bootstrap the application services.
*/
public function boot()
{
//
}
/**
* Register the application services.
*/
public function register()
{
foreach ($this->helpers as $helper) {
$helper_path = app_path().'/Helpers/'.$helper.'.php';
if (\File::isFile($helper_path)) {
require_once $helper_path;
}
}
}
}
您应该在app
文件夹下创建一个名为Helpers
的文件夹,然后在其中创建一个名为whatever.php
的文件,并将字符串whatever
添加到$helpers数组中。
完成!
我不再使用此选项,我目前正在使用composer来加载静态文件,例如帮助程序。
您可以直接添加帮助程序:
...
"autoload": {
"files": [
"app/helpers/my_helper.php",
...
]
},
...
glob()
加载目录中的所有文件,为什么要创建映射器呢?
如果您想指定要包含的文件,为什么不像Joseph Silber所写的那样在composer.json
中指定文件以进行自动加载?
为什么您更喜欢这种解决方案?
我不是说这是一个糟糕的解决方案,我只是很好奇。 - Pelmeredcomposer.json
文件中映射文件并没有太大区别,除了两点-首先,它将映射保留在应用程序本身内,而不是元数据文件;其次,它不需要每次更改要加载的文件列表时重新运行 composer dump-autoload
。 - Dan Hunsakerinclude
或 require
,Laravel 已经内置了 PSR-4 自动加载功能:http://www.php-fig.org/psr/psr-4/ - heisian由于OP要求最佳实践,我认为我们还缺少一些好的建议。
一个单独的helpers.php文件远非良好实践。首先,因为您混合了许多不同种类的函数,所以您违反了良好的编码原则。此外,这可能不仅会损害代码文档,还会损害代码指标,如Cyclomatic复杂性、可维护性指数和Halstead体积。函数越多,情况就越糟。
使用像phpDocumentor这样的工具,代码文档将是可以理解的,但是使用Sami时,它无法呈现过程性文件。 Laravel API文档就是这种情况-没有辅助函数文档:https://laravel.com/api/5.4
可以使用PhpMetrics等工具分析代码指标。使用PhpMetrics版本1.x来分析Laravel 5.4框架代码,将会得到非常糟糕的CC/MI/HV指标,适用于src/Illuminate/Foundation/helpers.php和src/Illuminate/Support/helpers.php文件。
多个上下文帮助文件(例如string_helpers.php,array_helpers.php等)肯定会改善这些糟糕的指标,从而使代码更易于维护。根据所使用的代码文档生成器,这已经足够好了。
通过使用具有静态方法的帮助器类,可以进一步改进它们,以便可以使用命名空间进行上下文化。就像 Laravel 已经在 Illuminate\Support\Str
和 Illuminate\Support\Arr
类中所做的一样。这将改善代码指标/组织和文档。可以使用类别名使它们更易于使用。
使用类结构使代码组织和文档更好,但另一方面,我们最终失去了那些优秀的简短易记的全局函数。我们可以通过为这些静态类方法创建函数别名来进一步改进这种方法。这可以手动或动态地完成。
Laravel 内部使用第一种方法,通过在过程性帮助器文件中声明函数来映射到静态类方法。这可能不是理想的事情,因为您需要重新声明所有内容(文档块/参数)。
我个人使用动态方法,在执行时创建这些函数的 HelperServiceProvider
类:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class HelperServiceProvider extends ServiceProvider
{
/**
* The helper mappings for the application.
*
* @var array
*/
protected $helpers = [
'uppercase' => 'App\Support\Helpers\StringHelper::uppercase',
'lowercase' => 'App\Support\Helpers\StringHelper::lowercase',
];
/**
* Bootstrap the application helpers.
*
* @return void
*/
public function boot()
{
foreach ($this->helpers as $alias => $method) {
if (!function_exists($alias)) {
eval("function {$alias}(...\$args) { return {$method}(...\$args); }");
}
}
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
对于我 Laravel 项目中的自定义助手库,我已经在 Laravel/App
目录下创建了一个名为 Libraries
的文件夹,并在 Libraries 文件夹中为不同的助手库创建了各种文件。
创建完我的助手文件后,我只需要像这样在我的 composer.json 文件中包含所有这些文件:
...
"autoload": {
"classmap": [
"database"
],
"files": [
"app/Libraries/commonFunctions.php"
],
"psr-4": {
"App\\": "app/"
}
},
...
并执行
composer dump-autoload
composer dump-autoload
和 composer dumpautoload
都可以使用,实际上 composer du
也可以。 - Akshay Khale不需要包含您的自定义帮助类,您实际上可以在别名下将其添加到您的config/app.php
文件中。
应该是这样的。
'aliases' => [
...
...
'Helper' => App\Http\Services\Helper::class,
]
然后在你的控制器中,使用方法 'use Helper' 包含 Helper类,这样你就可以简单地调用 Helper 类中的某些方法。
eg. Helper::some_function();
或者在资源视图中,您可以直接调用 Helper 类。
eg. {{Helper::foo()}}
但这仍然是开发者编码风格的方法,我们可能有不同的解决问题方式,我只是想与初学者分享我的经验。