开始
collection类的方法解析了,可能会相互依赖,一旦有就先直接略过...
1. 构造函数__construct()
/**
* 构造:新建一个集合
*
* @param mixed $items
* @return void
*/
public function __construct($items = [])
{
// 调用 getArrayableItems 方法来将传递的 $item 变形
$this->items = $this->getArrayableItems($items);
}
/**
* 对传递的数据$items 进行处理
*
* @param mixed $items
* @return array
*/
protected function getArrayableItems($items)
{
// 如果$items是数组,那么直接返回即可
if (is_array($items)) {
return $items;
// 如果$items是该集合的实例或者继承该集合的实例,就用它的 all 方法来 返回整个存储成员属性$items
// 可看下面的 all() 方法
} elseif ($items instanceof self){
return $items->all();
// 如果 $items 是某个实现了Arrayable 接口的类的实例,或者是更多的继承
// 不过该接口有toArray()的方法,故而可以直接调用toArray()方法
// 下面会以collection类介绍 toArray 方法, 其他继承Arrayable接口,基本都是这么玩的
} elseif ($items instanceof Arrayable) {
return $items->toArray();
// 如果 $items 是某个实现了Jsonable接口的类的实例,或者是更多的继承
// 接口有 toJson方法,故而可以直接调用该方法
// 下面会以collection类介绍该方法
} elseif ($items instanceof Jsonable) {
// 最终各种转化递归遍历,全部成了数组的格式
return json_decode($items->toJson(), true);
// 如果 $items 是某个实现了JsonSerializable接口的类的实例,或者是更多的继承
} elseif ($items instanceof JsonSerializable) {
return $items->jsonSerialize();
// 如果是属于迭代器的实例
} elseif ($items instanceof Traversable) {
// 转化为数组
return iterator_to_array($items);
}
// 不是实例的话 直接强制转化为数组
return (array) $items;
}
为了解释上面getArrayableItems的...
/**
* 获取集合里存储的所有的 items
*
* @return array
*/
public function all()
{
return $this->items;
}
/**
* 获取集合里存储的所有的 items
*
* @return array
*/
public function toArray()
{
return $this->all();
}
/**
* 以json格式获取collection的items
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{ // 将 $this->jsonSerialize() 的结果进行json编码
return json_encode($this->jsonSerialize(), $options);
}
public function jsonSerialize()
{
// array_map 就不多说了,遍历数组,其中每个都作为参数,执行闭包。
return array_map(function($value) {
// 如果$value 是某个实现implements了JsonSerializable接口类的实例,
// 或者是往下继承的...反正是可以调用这个方法的实例。
if ($value instanceof JsonSerializable) {
// 继续递归下去,得一一找到才行。
return $value->jsonSerialize();
// 如果$value是某个实现implements了Jsonable接口类的实例,
} elseif ($value instanceof Jsonable) {
// 无限转化,搞成数组
return json_decode($value->toJson(), true);
// 如果$value是某个实现implements了Jsonable接口类的实例
} elseif ($value instanceof Arrayable) {
//直接获取这个类的储存的数据
return $value->toArray();
}
// 如果都不是 直接返回
return $value;
}, $this->items);
}
总结:说白了,除了可以简单的数组什么的存放到 collection 集合的 $items 里存储起来,调用里面的各种方法,得到想要的数据格式。还有将各个类实例存放在里面,比如,laravel 里面从数据库查询出来的结果,都是集合 collection 实例。哇...越想越可怕。
2.static方法 make
/**
* 创建一个新的 Collection 实例
*
* @param mixed $items
* @return static
*/
public static function make($items = [])
{
return new static($items);
}
// new static() 也是实例化,与new self() 的区别是:
// new static() 是哪个类调用make方法,那么new出的这个实例就是那个类的,可以用get_class看
// 而new self() 是这个make方法在哪个类里出现,那么new出的对象就是哪个类的。
3.static方法 wrap
/**
* 用来包裹已经是集合实例的方法
*
* @param mixed $value
* @return static
*/
public static function wrap($value)
{
//如果已经是集合实例
return $value instanceof self
// 将其丢到构造进行实例化,而 $value instanceof self肯定是true的
// 所以会返回 $value->all() 根据返回结果,最后 return $this->items;
? new static($value)
// 否则 将这个数组的wrap方法,强制变为数组,再进行实例化。
: new static(Arr::wrap($value))
}
// 用法示例:
$collection = Collection::wrap(123);
dd($collection) //走的是new static(Arr::wrap($value))
/*
Collection {#173 ▼
#items: array:1 [▼
0 => 123
]
}
*/
$collection = Collection::wrap(collect([1,2,3]));
dd($collection); // 走的new static($value)
/*
Collection {#168 ▼
#items: array:3 [▼
0 => 1
1 => 2
2 => 3
]
}
*/