请任何人都可以帮助我了解 Laravel Macroable trait 中的宏是什么,阅读此文档https://laravel.com/api/5.4/Illuminate/Support/Traits/Macroable.html只告诉我如何使用但我为什么要使用它,它是什么意思。
它用于在运行时动态地向类添加功能。
use Illuminate\Support\Collection;
Collection::macro('someMethod', function ($arg1 = 1, $arg2 = 1) {
return $this->count() + $arg1 + $arg2;
});
$coll = new Collection([1, 2, 3]);
echo $coll->someMethod(1, 2);
// 6 = 3 + (1 + 2)
echo $coll->someMethod();
// 5 = 3 + (1 + 1)
Run Code Online (Sandbox Code Playgroud)
我们已经“宏化”了名称为 的 Collection 类的一些功能someMethod。我们现在可以在 Collection 类上调用这个方法并使用它的功能。
我们只是在类中添加了一个以前不存在的方法,而无需接触任何源文件。
有关正在发生的事情的更多详细信息,请查看我关于 Laravel 中宏的文章:
它允许您添加新功能。一次调用即可::macro添加一项新功能。这可以在那些内部框架类上完成,这些类是Macroable.
将函数添加到类的这一操作是在运行时完成的。请注意,此操作已经存在一个完美的名称,而不是“宏”一词,我将在本文末尾对此进行解释。
问:你为什么要这样做?
答:如果您发现自己在处理这些内部类(例如请求和响应),向它们添加函数可能会使您的代码更具可读性。但与往常一样,任何抽象都会带来复杂性成本,因此只有在您感到痛苦时才这样做。
本文包含可以使用静态调用添加函数的类的列表"::macro"
不过,如果你读了那篇文章,请不要吞下“宏”这个词——如果你像我一样,它会让你消化不良。
因此,现在让我们向内部框架类添加一个额外的函数。这是我刚刚实现的示例:
RedirectResponse::macro('withoutQuery', function() {
return redirect()->to(explode('?', url()->previous())[0]);
});
Run Code Online (Sandbox Code Playgroud)
这使我能够在控制器中执行此操作:
redirect()->back()->withoutQuery();
Run Code Online (Sandbox Code Playgroud)
(你可以只执行 back() 但我添加了 redirect() 以使其清楚)。
这个例子是重定向回来,之前的路由是这样的:
http://myapp.com/home?something=something-else
此函数删除“?”之后的部分,以简单地重定向到:
http://myapp.com/home
我不必这样编码。实际上,实现此目的的另一种方法是将以下函数放入所有控制器都继承自 ( App\Http\Controllers\Controller) 的基类中。
public function redirectBackWithoutQuery()
{
return redirect()->to(explode('?',url()->previous())[0]);
}
Run Code Online (Sandbox Code Playgroud)
这意味着我可以在任何控制器中执行此操作:
return $this->redirectBackWithoutQuery();
Run Code Online (Sandbox Code Playgroud)
因此,在这种情况下,“宏”让您假装您的新函数是内部框架类的一部分,在本例中是 Illuminate/RedirectResponse 类。
就我个人而言,我喜欢你发现很难掌握“laravel 宏”。我认为因为这个名字,它们有一些神秘的东西。
第一点是您可能不经常需要它们。第二点是选择名称 ::macro 来表示“向类添加函数”
真正的宏是 Lisp 独有的概念。宏就像一个函数,但它构建并返回实际的代码,然后执行该代码。可以用其他语言编写一个函数,该函数返回一个字符串,然后您可以像代码一样执行该字符串,这几乎是相同的事情。但是,如果您考虑一下,那么您在执行此操作时就需要处理所有语法。Lisp 代码实际上是由列表构成的。如果 javascript 都写成实际的 json 的话,可以想象一下比较。然后你可以编写 javascript,它是 json,它返回 json,然后宏将执行它。但 lisp 的语法比 json 简单很多,所以它比你想象的要容易很多。所以,真正的 Lisp 宏是你能遇到的最美丽、最神奇的东西之一。
那么为什么Laravel 中这些附加功能的东西被称为宏呢?恐怕我不知道,你必须问作者,但我问自己他们到底在做什么,是否已经有一个名字了。
TL;DR laravel 的 :: 宏可以更准确地描述为猴子补丁
因此,如果使用 laravel ::macro 调用,我个人决定创建一个MonkeyPatchServiceProvider并将它们全部放在那里,以减少自己不必要的混乱。
我意识到这个名字可能听起来有点贬义,但这根本不是有意的。这只是因为已经有一个名称了,而且我们有这么多术语来处理为什么不使用现有的名称。