请任何人帮助我了解Laravel Macroable特性中的宏,阅读本文档https://laravel.com/api/5.4/Illuminate/Support/Traits/Macroable.html仅告诉我如何使用,但为什么我使用它,这意味着什么。
答案 0 :(得分:2)
用于在运行时动态地向类添加功能。
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)
我们以名称someMethod
将某些功能“宏化”到了Collection类。现在,我们可以在Collection类上调用此方法并使用其功能。
我们只是在类中添加了一个以前不需要触摸任何源文件的方法。
有关正在发生的事情的更多详细信息,请查看我有关Laravel中的宏的文章:
答案 1 :(得分:1)
它允许您添加新功能。对::macro
的一次调用增加了一个新功能。这可以在内部框架类Macroable
上完成。
此功能添加到类的操作是在运行时完成的。请注意,此操作已经/已经存在一个非常好的名称,而不是“宏”一词,我将在本文结尾处进行解释。
问:你为什么要这样做?A。如果您发现自己在使用这些内部类,例如 请求和响应,向他们 添加功能 可能会使您的代码更加 可读的。 但是与往常一样,任何 抽象,所以只有在感到疼痛时才这样做。
This article包含可以使用静态调用"::macro"
不过,如果您读过那篇文章,请不要吞下“宏”一词-如果您像我一样,那将给您带来很大的消化不良的感觉。
所以,现在让我们 向内部框架类添加一个额外的功能 。这是我刚刚实现的示例:
RedirectResponse::macro('withoutQuery', function() {
return redirect()->to(explode('?', url()->previous())[0]);
});
这使我可以在控制器中执行以下操作:
redirect()->back()->withoutQuery();
(您可以只执行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]);
}
这意味着我可以在任何控制器中执行此操作:
return $this->redirectBackWithoutQuery();
因此,在这种情况下,“宏”让您假装新函数是内部框架类的一部分,在本例中是Illuminate / RedirectResponse类。
我个人喜欢您发现很难掌握“ laravel宏”。我以为,由于名字的缘故,它们有些神秘。
第一点是您可能不需要经常使用它们。 第二点是选择:: macro来表示“将函数添加到类”
真正的宏是Lisp特有的概念。宏就像一个函数,但是它生成并返回实际代码,然后执行该代码。可以用其他语言编写一个函数,该函数返回一个字符串,然后像执行代码一样执行该字符串,这几乎是同一件事。但是,如果考虑到这一点,那么当您执行此操作时,便拥有所有语法。 Lisp代码实际上是在列表中构造的。如果将javascript全部编写为实际的json,可以想象一个比较。然后,您可以编写javascript,它是json,它返回json,然后该宏就会执行。但是lisp在语法上比json简单得多,因此比您想象的要简单得多。因此,真正的Lisp宏是您可能遇到的最美丽,最神奇的事物之一。
那么为什么在laravel中这些 添加功能 称为宏? 恐怕我不知道这件事,您不得不问一下作者,但是我问自己他们到底在做什么,并且已经有个名字了。
TL; DR laravel的:: macro可以更准确地描述为monkey patch
因此,如果使用laravel :: macro调用,我个人决定创建一个MonkeyPatchServiceProvider
并将其全部放置,以减少对我自己造成的不必要的混乱。
我知道这个名字听起来有点贬义,但这根本不是故意的。 仅仅是因为已经有了一个名称,并且我们有太多的术语来处理为什么不使用现有名称。
答案 2 :(得分:0)
我认为,阅读此内容对您会更好。它很美丽。希望您读懂此内容后,您的想法会明白。您还将学习如何在laravel中使用宏类。