内容简介:何谓 高阶消息传递Higher Order Messages(HOM) 其实就是个叫法,我也不太清楚。比如先简单说说它怎么个用法,官方文档是有的,拿过来介绍一下。以上,就属于高阶用法的实例。将
何谓 高阶消息传递Higher Order Messages(HOM) 其实就是个叫法,我也不太清楚。比如 each
方法,就属于集合的高阶消息的方法内,要求应该就是参数可传一个闭包,可以这么理解。
1. 示例
先简单说说它怎么个用法,官方文档是有的,拿过来介绍一下。
// 在某控制器的方法里 $users = User::where('votes', '>', 500)->get(); $users->each->markAsVip(); // user模型里 public function markAsVip() { // 这里假设就是这么更改,有is_vip这个字段 $this->update('is_vip', 1); } 复制代码
以上,就属于高阶用法的实例。将 user
表里的 votes
数大于500的标记为vip会员。
如果是正常写法,那铁定就是,将 $users
进行 foreach
遍历 然后进行逐条更新。相比集合高阶用法。就不必多说了吧。
2. Collection 里 涉及高阶消息源码解析
/** * 可以被作为高阶消息传递的方法 * * @var array */ protected static $proxies = [ 'average', 'avg', 'contains', 'each', 'every', 'filter', 'first', 'flatMap', 'keyBy', 'map', 'partition', 'reject', 'sortBy', 'sortByDesc', 'sum', 'unique', ]; /** * 添加自定义高阶方法 * * @param string $method * @return void */ public static function proxy($method) { static::$proxies[] = $method; } public function __get($key) { // 就是如果传的 $key 在高阶方法数组里都不存在,那么报错 if (! in_array($key, $static::$proxies)) { throw new Exception("Property [{$key}] does not exist on this collection instance.") } // 否则, 将Collection实例和这个方法名以参数 // 传给 HigherOrderCollectionProxy 实例化 return new HigherOrderCollectionProxy($this, $key); } 复制代码
上面,就是定义了静态变量,存放高阶方法名,还有可自定义的方法,和利用魔术方法 __get()
来跳转到 HigherOrderCollectionProxy
类里得以实现。
3.HigherOrderCollectionProxy 类解析
- 成员变量和构造方法
class HigherOrderCollectionProxy { /** * 存储 collection类实例 * * @var \Illuminate\Support\Collection */ protected $collection; /** * 存储 高阶方法名 * * @var string */ protected $method; /** * 构造接收传过来的 collection类实例, 高阶方法名 * * @param \Illuminate\Support\Collection $collection * @param string $method * @return void */ public function __construct(Collection $collection, $method) { // 简单初始化赋值存储 $this->method = $method; $this->collection = $collection; } 复制代码
-
__get
方法解析
/** * 用来 针对属性 高阶传递调用 * * @param string $key * @return mixed */ public function __get($key) { return $this->collection->{$this->method}(function ($value) use ($key) { return is_array($value) ? $value[$key] : $value->{$key}; }); } // 说明:为了某些集合方法的参数-闭包里 传属性的东东 // 举例: 将下列数组按年龄正序排序 $arr = [ [ 'name' => '小明', 'age' => 23, 'sex' => '男' ], [ 'name' => '小鑫', 'age' => 21, 'sex' => '女' ] [ 'name' => '小hu', 'age' => 22, 'sex' => '男' ] ]; collect($arr)->sortBy->age; // 将__get 解析一下: $age = 'age' collect($arr)->sortBy(function($value) use ($age) { return $value['age'] }) // 这样就清晰明了了。 复制代码
-
__call()
方法解析
/** * 针对方法的 高阶消息传递 * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->collection->{$this->method}($value) use ($method, $parameters) { return $value->{$method}(...$parameters); } } // 说明: 针对高阶集合调用方法,继续举例子 // 举例:再把第一节的例子拿来 // 在某控制器的方法里 $users = User::where('votes', '>', 500)->get(); $users->each->markAsVip(); // user模型里 public function markAsVip() { // 这里假设就是这么更改,有is_vip这个字段 $this->update('is_vip', 1); } // 按__call()方法解析后 $this->collection 就是 $users $this->method 就是 'each' $method 就是 'markAsVip' $parameters 就是 空的 // 所以呢 $method = 'markAsVip' $users->each(function($value) use ($method) { return $value->$method(); }) // 这样不就是用each将$users遍历 然后调用User模型里的markAsVip()方法么 // 其实就是这样 啊哈哈哈哈。 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图论——一个迷人的世界
本杰明,查特兰,张萍 / 机械工业出版社 / 2001-1-1
本书介绍了图论的基本概念,解释了图论中各种经典问题。例如,熄灯的问题、小生成树问题、哥尼斯堡七桥问题、中国邮递员问题、国际象棋中马的遍历问题和路的着色问题等等。书中也给出了各种类型的图,例如,二部图、欧拉图、彼得森图和树;等等。每一章都为读者设置了练习题,包含了具有挑战性的探索性问题。一起来看看 《图论——一个迷人的世界》 这本书的介绍吧!