Laravel 源码 Collection(集合)请教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OMGZui
V2EX    PHP

Laravel 源码 Collection(集合)请教

  •  
  •   OMGZui 2018-06-07 11:45:47 +08:00 3433 次点击
    这是一个创建于 2695 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Collection.php

    /** * @property-read HigherOrderCollectionProxy $average * @property-read HigherOrderCollectionProxy $avg * @property-read HigherOrderCollectionProxy $contains * @property-read HigherOrderCollectionProxy $each * @property-read HigherOrderCollectionProxy $every * @property-read HigherOrderCollectionProxy $filter * @property-read HigherOrderCollectionProxy $first * @property-read HigherOrderCollectionProxy $flatMap * @property-read HigherOrderCollectionProxy $groupBy * @property-read HigherOrderCollectionProxy $keyBy * @property-read HigherOrderCollectionProxy $map * @property-read HigherOrderCollectionProxy $max * @property-read HigherOrderCollectionProxy $min * @property-read HigherOrderCollectionProxy $partition * @property-read HigherOrderCollectionProxy $reject * @property-read HigherOrderCollectionProxy $sortBy * @property-read HigherOrderCollectionProxy $sortByDesc * @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $unique * * Class Collection */ /** * The methods that can be proxied. * * @var array */ protected static $proxies = [ 'average', 'avg', 'contains', 'each', 'every', 'filter', 'first', 'flatMap', 'groupBy', 'keyBy', 'map', 'max', 'min', 'partition', 'reject', 'sortBy', 'sortByDesc', 'sum', 'unique', ]; /** * Dynamically access collection proxies. * * @param string $key * @return mixed * * @throws \Exception */ public function __get($key) { if (! in_array($key, static::$proxies)) { throw new Exception("Property [{$key}] does not exist on this collection instance."); } return new HigherOrderCollectionProxy($this, $key); } 

    HigherOrderCollectionProxy.php

     /** * Create a new proxy instance. * * @param \Illuminate\Support\Collection $collection * @param string $method * @return void */ public function __construct(Collection $collection, $method) { $this->method = $method; $this->collection = $collection; } /** * Proxy accessing an attribute onto the collection items. * * @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}; }); } /** * Proxy a method call onto the collection items. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->collection->{$this->method}(function ($value) use ($method, $parameters) { return $value->{$method}(...$parameters); }); } 

    我的问题是这里为什么要用 HigherOrderCollectionProxy 来代理,有什么好处?这些方法都是 public 形式的,直接调用方法不好吗?

    9 条回复    2018-06-08 15:55:07 +08:00
    websterq
        1
    websterq  
       2018-06-07 12:09:18 +08:00
    链式调用,Laravel 里挺常见的设计吧,这样设计也是为了方便、流程的 Code 体验
    crystom
        2
    crystom  
       2018-06-07 12:12:57 +08:00
    User 类有 sendEmail 方法
    则可以用这样的写法:
    $users->each->sendEmail();
    等价于$users->each(function($user){$user->sendEmail()});
    OMGZui
        3
    OMGZui  
    OP
       2018-06-07 14:07:44 +08:00
    @websterq 老哥,我确定这不是链式调用,比如(new Collection([1, 2]))->max()->min(),这样是不行的。
    DavidNineRoc
        4
    DavidNineRoc  
       2018-06-07 14:41:54 +08:00   3
    看文档呀,这个是 高阶函数调用,简单的来说就是本来你的 User 对象有一个 toArray 方法,
    这时候你有一集合 User 对象都要调用 toArray 方法可以
    $users->each->toArray();
    echo 是集合的方法,toArray 是 User 的方法;这样子高阶代理使用非常简单,不然你得这样操作
    $usersArray = new HigherOrderCollectionProxy($users, 'toArray');

    ## 想要链式调用的时候就不能了,
    $users->tap()->map()->each->toArray();
    上面的操作,如果不用高阶代理函数,就要拆成两部分了
    OMGZui
        5
    OMGZui  
    OP
       2018-06-07 15:08:05 +08:00
    @DavidNineRoc 老哥,我大概是懂了。
    xxstop
        6
    xxstop  
       2018-06-07 22:06:21 +08:00
    战略性 mark
    OMGZui
        7
    OMGZui  
    OP
       2018-06-08 15:09:04 +08:00
    @xxstop 兄弟,这也 mark 啊
    xxstop
        8
    xxstop  
       2018-06-08 15:53:54 +08:00
    @OMGZui #7 感动。你这么一说,我在网上找到一篇很棒的文章。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3220 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 10:46 PVG 18:46 LAX 03:46 JFK 06:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86