Laravel集合探学系列——高阶消息传递实现(二)

栏目: 编程语言 · PHP · 发布时间: 7年前

内容简介:何谓 高阶消息传递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()方法么
    // 其实就是这样 啊哈哈哈哈。
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机体系结构

计算机体系结构

John L. Hennessy、David A. Patterson / 机械工业出版社 / 2012-1 / 138.00元

编辑推荐 “本书之所以成为永恒的经典,是因为它的每一次再版都不仅仅是更新补充,而是一次全面的修订,对这个激动人心且快速变化领域给出了最及时的信息和最独到的解读。对于我来说,即使已有二十多年的从业经历,再次阅读本书仍自觉学无止境,感佩于两位卓越大师的渊博学识和深厚功底。” ——Luiz André Barroso,Google公司 内容简介 本书堪称计算机系统结构学科的“圣经......一起来看看 《计算机体系结构》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具