Laravel macorable
macroable 的作用是 在一个类 a 中访问另一个 b 类的方法不需要在 a 类中增加方法代码#
<?php
namespace Illuminate\Support\Traits;
use Closure;
use ReflectionClass;
use ReflectionMethod;
use BadMethodCallException;
trait Macroable
{
/**
* The registered string macros.
*
* @var array
*/
protected static $macros = [];
/**
* Register a custom macro.
*
* @param string $name
* @param object|callable $macro
*
* @return void
*/
public static function macro($name, $macro)
{
static::$macros[$name] = $macro;
}
/**
* Mix another object into the class.
*
* @param object $mixin
* @param bool $replace
* @return void
*
* @throws \ReflectionException
*/
public static function mixin($mixin, $replace = true)
{
$methods = (new ReflectionClass($mixin))->getMethods(
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
);
foreach ($methods as $method) {
if ($replace || ! static::hasMacro($method->name)) {
$method->setAccessible(true);//把protecte方法设置为可以访问不然无法执行
static::macro($method->name, $method->invoke($mixin));//执行这个方法
}
}
}
/**
* Checks if macro is registered.
*
* @param string $name
* @return bool
*/
public static function hasMacro($name)
{
return isset(static::$macros[$name]);
}
/**
* Dynamically handle calls to the class.
*
* @param string $method
* @param array $parameters
* @return mixed
*
* @throws \BadMethodCallException
*/
public static function __callStatic($method, $parameters)
{
if (! static::hasMacro($method)) {
throw new BadMethodCallException(sprintf(
'Method %s::%s does not exist.', static::class, $method
));
}
if (static::$macros[$method] instanceof Closure) {
return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters);
}
return call_user_func_array(static::$macros[$method], $parameters);
}
/**
* Dynamically handle calls to the class.
*
* @param string $method
* @param array $parameters
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{
if (! static::hasMacro($method)) {
throw new BadMethodCallException(sprintf(
'Method %s::%s does not exist.', static::class, $method
));
}
$macro = static::$macros[$method];
if ($macro instanceof Closure) {
return call_user_func_array($macro->bindTo($this, static::class), $parameters);
}
return call_user_func_array($macro, $parameters);
}
}
给出几个例子来理解 这个 trait 的作用
class Father
{
public function say()
{
return function () {
echo 'say';
};
}
public function show()
{
return function () {
echo 'show';
};
}
protected static function eat()
{
return 'Test::getName';
return function () {
var_dump(static::$name);
echo 'eat';
};
}
}
class Test{
public static function getName(){
echo 'ddddddd';
}
public function __invoke(){
echo 'test';
}
}
Child::mixin(new Father);
//Child::macro('show',new Test);
$child = new Child;
// 输出:say
$child->say();
// 输出:show
//$child->show();
// 输出:eat
$child::eat();
本作品采用《CC 协议》,转载必须注明作者和本文链接