引言
Laravel有两种类型的集合:Illuminate\Support\Collection和Illuminate\Database\Eloquent\Collection。因为它们之间的差异不是很明显,并且它们共享许多常用方法,所以至少对于我来说,它不容易被注意到。
在大多数情况下,将它们视为相同的实例并不会出错。不过在编程中,脑海里时常清晰地区分出正在使用的是那个Collection,可以有效减少不必要的调用。
学习时间
通常,我们使用助手函数 collect 创建一个集合,其实返回的是 Illuminate\Support\Collection 的一个实例。而集合 Illuminate\Database\Eloquent\Collection 则是通过 eloquent 方法返回数据时创建的,这很有区别。
因为 Illuminate\Database\Eloquent\Collection 是从 Illuminate\Support\Collection 继承过来的,理所当然,拥有基类所没有的许多特性,比如 find 方法,keyBy 方法。
还有一些是没重写了的方法,比如 contains ,unique 。
这些细微的差别,在编程时需要避免,防止出现 method 不存在的故障。比如下图:
因为类 Illuminate\Support\Collection 并没有 find 方法,必然导致错误。find 是在模型中才能调用的集合的方法。
PHP 7 中的类型提示
PHP 7中的新功能是返回类型声明。它可以帮助开发人员查看和检查返回类型是否与期望的返回类型匹配。
由于 Illuminate\Database\Eloquent\Collection 和 Illuminate\Support\Collection 之间的关系,我们可以在函数返回值上显式声明返回类型。
比如下面的代码:
在方法 popular 中使用的是 EloquentCollection 的方法,而返回值我们则强制其为 BaseCollection。这样就完成了类型的转换。
单元测试
PHPUnit 提供了 assertInstanceOf() 方法用于甄别返回类。
测试结果表明,对于返回对象类型使用 assertInstanceOf 断言,就算是继承的类,也可以断言成功。而如果使用 assertEquals ,则通不过。
写在最后
由于这两个集合之间的可用功能不同,因此对于何时可以使用,或不能使用这些方法,可能会造成混淆(如上所述)。
简化的方法,是将结果全部归为一种类型。它可以是数组,BaseCollection 或 EloquentCollection。
EloquentCollection 应该放最后,不得已而用之,因为它真的不是那么通用。
首选项是什么呢?数组!一旦统一了返回类型,就不会担心在开发时这能用那不能用的混作一团了。
Happy coding :-)
我是 @程序员小助手 ,持续分享编程知识,欢迎关注。