laravel 中 所有的模型会继承自模型基类
    当调用一个模型不存在的属性时,会调用基类模型的__get方法(php中的魔术方法,读取不可访问属性的值时,__get()会被调用)
    model类中的方法

    1. public function __get($key)
    2. {
    3. return $this->getAttribute($key); //调用 model 类的 getAttribute 方法
    4. }
    5. .......
    6. public function getAttribute($key)
    7. {
    8. if (array_key_exists($key, $this->attributes) || $this->hasGetMutator($key)) {
    9. return $this->getAttributeValue($key);
    10. }
    11. //$this->attributes是当前实例模型的属性关联数组 false
    12. //method_exists 和 function_exists 差不多 ,一个是检查是否有此 function, 一个是检查当前类是否有成员方法 method
    13. //如果都没有会当成关联模型,尝试获取关联关系
    14. return $this->getRelationValue($key);
    15. }
    16. .......
    17. public function hasGetMutator($key)
    18. {
    19. //method_exists 和 function_exists 差不多 ,一个是检查是否有此 function, 一个是检查当前类是否有成员方法 method
    20. //在当前 类实例中存在 getXxxAttribute方法
    21. return method_exists($this, 'get'.Str::studly($key).'Attribute');
    22. }
    23. ........
    24. public function getAttributeValue($key)
    25. {
    26. $value = $this->getAttributeFromArray($key);
    27. // If the attribute has a get mutator, we will call that then return what
    28. // it returns as the value, which is useful for transforming values on
    29. // retrieval from the model to a form that is more useful for usage.
    30. //如果当前属性有修改器,调用修改器
    31. if ($this->hasGetMutator($key)) {
    32. return $this->mutateAttribute($key, $value);
    33. }
    34. // If the attribute exists within the cast array, we will convert it to
    35. // an appropriate native PHP type dependant upon the associated value
    36. // given with the key in the pair. Dayle made this comment line up.
    37. //如果有映射转换关系,数据库int 转 布尔值, json 转数组
    38. if ($this->hasCast($key)) {
    39. return $this->castAttribute($key, $value);
    40. }
    41. // If the attribute is listed as a date, we will convert it to a DateTime
    42. // instance on retrieval, which makes it quite convenient to work with
    43. // date fields without having to create a mutator for each property.
    44. //不是时间戳
    45. if (in_array($key, $this->getDates()) && ! is_null($value)) {
    46. return $this->asDateTime($value);
    47. }
    48. //返回值
    49. return $value;
    50. }

    如果实例模型设置了$appends属性,并且模型没有这个属性(假设为name),laravel 会自动调用getNameAttribute方法
    有个问题就是每次都会自动调用,有时候只想在某些情况下调用的话,可以取消$appends属性,获取模型时手动调用setAppends方法

    1. $user=User::find(1)->setAppends(['wage','info']);

    但是 setAppends方法对collection不生效,也就是说用get,all方法都不生效,可以在 AppServiceProvider中为collection添加宏

    1. Collection::macro('setAppends', function ($attributes) {
    2. return $this->map(function ($item) use ($attributes) {
    3. return $item->setAppends($attributes);
    4. });
    5. });
    6. $users = User:all();
    7. $users->setAppends([
    8. 'info'
    9. ]);

    也可以利用 collection 的高阶消息传递

    1. $users->each->setAppends([
    2. 'info'
    3. ]);