在 Laravel 中创建自己的辅助函数 helpers
Laravel 提供了很多优秀的辅助函数,让诸如数组、文件路径、字符串、路由等的使用更加便利。比如,dd()
函数。
通过 Composer 自动引入,你也可以为你的 Laravel 应用和 PHP 包定义一套辅助函数。
如果你是 Laravel 或者 PHP 新手,让我们一起看看如何通过 Laravel 自动加载创建自己的 helper 函数。
在 Laravel 应用中创建一个 Helpers 文件
你需要做的第一步是在 Laravel 应用中引入 helper 函数。取决于你自己的偏好,你可以自己组织你 helper 文件的位置。尽管如此,这是一些建议位置:
- app/helpers.php
- app/Http/helpers.php
我个人偏向于将其放在应用命名空间的根目录之下.
自动加载
使用 PHP 辅助函数,你需要在运行时将其加载到你的程序中。在早些年,在文件的顶部使用这样的代码引入是比较普遍的:
require_once ROOT . '/helpers.php';
PHP 函数不会被自动加载。然而,比起使用 require
和 require_once
, 我们有一个更好的解决方法,即使用 composer 。
在 Laravel 项目的 composer.json
文件中, 你会看到 autoload
和 autoload-dev
键:
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
如果你想添加辅助函数文件,composer 有一个 files 键(文件路径数组) ,你可以在 autoload
里面定义:
"autoload": {
"files": [
"app/helpers.php"
],
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
一旦你在 files 数组中添加了新的路径,你需要 dump autoload
对自动加载进行更新:
composer dump-autoload
现在每个请求,helpers.php
文件都会被自动加载。因为 Laravel 在 public/index.php
中 引入 Composer 自动加载器:
require __DIR__.'/../vendor/autoload.php';
定义函数
虽然有很多需要警惕的事项, helpers 中定义函数还是很容易的。为了避免函数定义冲突,所有的 Laravel helper 文件都使用如下代码包裹:
if (! function_exists('env')) {
function env($key, $default = null) {
// ..
}
}
这样有时候会有些棘手,你可能会遇到这样的情况:你所使用的函数可能不是你自定义的、而是来自于第一次定义的。
我倾向于在我的应用的 helpers 中使用 function_exists
检查,如果你在应用的上下文环境中定义 helpers, 你可以忽略function_exists
检查。跳过这步检查,你每次重定义函数的时候都会看到冲突。
真实的实践中,冲突并不会那么常见,你应该确保你定义的函数名不会过于通用。你也可以给你的函数名加上前缀,以减少和其他依赖包冲突的可能。
Helper 实例
我喜欢对定义路径及 URL 的辅助函数。比如,photos 资源路由可以暴露路由辅助函数如 new_photo_path
, edit_photo_path
等。
当我在 Laravel 中使用资源路由时,我喜欢添加一些 helper 函数,让模板中的路由定义更容易一些。在我的实现中,我会使用 URL 帮助函数,方便通过传 Eloquent 模型获取资源路由,比如:
create_route($model);
edit_route($model);
show_route($model);
destroy_route($model);
在 app/helpers.php
文件中,你可以这样定义 show_route
:
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);
}
}
plural_from_model()
函数是 helper 路由函数用来预测路由资源名称的代码重用, 使用短横线隔开式复数调用模型。
比如,以下是模型资源名:
$model = new App\LineItem;
plural_from_model($model);
=> line-items
plural_from_model(new App\User);
=> users
使用这样的约定,你可以在 routes/web.php
中像这样定义资源路由:
Route::resource('line-items', 'LineItemsController');
Route::resource('users', 'UsersController');