We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
还记得那个《高速修车》的陈年老梗吗:
公司的业务呢,就像跑在高速路上的车,车不能停,但是新需求和修bug也不能停。
这里要跟大家扒代码的 Macroable 呢,有点像上面这个悖论的出路;但其实也不是,因为他没有实现 修 且不停,只实现了 增 且不停。请原谅我这尴尬的幽默。
Macroable
修
增
网上很多教程都是提及了,Laravel 绝大部分类,都可以扩展方法。比如这个例子:
use Illuminate\Support\Collection; Collection::macro('bcsum', function () { $sum = 0; foreach ($this as $item) { $sum = bcadd($sum, $item, 2); } return $sum; }); dump((new Collection([1,2,3,4]))->bcsum()); // it says "10.00"
我们可以看到,在不改变代码的前提下,我们在使用的过程中给 Illuminate\Support\Collection 扩充了 bcsum 的功能。就如同在其中加入了如下代码:
Illuminate\Support\Collection
bcsum
<?php class Collection ... { public function bcsum() { $sum = 0; foreach ($this as $item) { $sum = bcadd($sum, $item, 2); } return $sum; } }
laravel/vendor/laravel/framework/src/Illuminate/Support/Collection.php
Lines 42 to 44 in d081c91
我们看到,Illuminate\Support\Collection 使用了 Illuminate\Support\Traits\Macroable 这个 trait。
Illuminate\Support\Traits\Macroable
macro
作用是将闭包存进static::$macros
static::$macros
laravel/vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php
Lines 19 to 30 in d081c91
在调用我们的方法时,按名字匹配出来,参数传入触发。
Lines 64 to 112 in d081c91
这里之所以定义了两个方法,__call 和 __callStatic,是因为 laravel 很多类,部分可以静态调用,部分可以动态调用。macroable 如果要能被这两种类可用,那么就需要定义两个魔术方法。
__call
__callStatic
laravel
macroable
一. 魔术一个魔术方法,不可行
我们现在知道了 Macroable 的神奇,但是其实Macroable 也有失灵的时候。举个例子:
<?php class JoeDoe { use \Illuminate\Support\Traits\Macroable; } JoeDoe::macro('__toString', function () { return '123'; }); echo new JoeDoe();
而运行时,其还是报了这个错:
PHP Recoverable fatal error: Object of class JoeDoe could not be converted to string
但是如果我们在 JoeDoe 这个类中手工硬编码 __toString 这个方法却是可以运行的的; 为什么?
JoeDoe
__toString
其实道理很简单,因为 echo JoeDoe 对象时候,php 内核检查其中有没有 __toString 这个方法时,就已经报错了,根本还来不及走到 __call 这个魔术方法。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
还记得那个《高速修车》的陈年老梗吗:
这里要跟大家扒代码的
Macroable
呢,有点像上面这个悖论的出路;但其实也不是,因为他没有实现修
且不停,只实现了增
且不停。请原谅我这尴尬的幽默。从陈年教程入手
网上很多教程都是提及了,Laravel 绝大部分类,都可以扩展方法。比如这个例子:
我们可以看到,在不改变代码的前提下,我们在使用的过程中给
Illuminate\Support\Collection
扩充了bcsum
的功能。就如同在其中加入了如下代码:代码解析
laravel/vendor/laravel/framework/src/Illuminate/Support/Collection.php
Lines 42 to 44 in d081c91
我们看到,
Illuminate\Support\Collection
使用了Illuminate\Support\Traits\Macroable
这个 trait。macro
的代码作用是将闭包存进
static::$macros
laravel/vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php
Lines 19 to 30 in d081c91
魔术方法
在调用我们的方法时,按名字匹配出来,参数传入触发。
laravel/vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php
Lines 64 to 112 in d081c91
这里之所以定义了两个方法,
__call
和__callStatic
,是因为laravel
很多类,部分可以静态调用,部分可以动态调用。macroable
如果要能被这两种类可用,那么就需要定义两个魔术方法。经验分享
失灵的情况
一. 魔术一个魔术方法,不可行
我们现在知道了
Macroable
的神奇,但是其实Macroable
也有失灵的时候。举个例子:而运行时,其还是报了这个错:
但是如果我们在
JoeDoe
这个类中手工硬编码__toString
这个方法却是可以运行的的;为什么?
其实道理很简单,因为 echo
JoeDoe
对象时候,php 内核检查其中有没有__toString
这个方法时,就已经报错了,根本还来不及走到__call
这个魔术方法。The text was updated successfully, but these errors were encountered: