集合 collection ¶
Testing Is Documentation
集合 collection
提供了一些实用方法,数据库查询的数据列表也会转换为集合数据类型。
Uses
<?php
use Leevel\Support\Collection;
基本使用 ¶
集合实现了 \IteratorAggregate
可以像普通数组一样遍历,也实现了 \ArrayAccess
接口,可以当做普通数组一样使用。
public function testBaseUse(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
foreach ($collection as $key => $val) {
switch ($key) {
case 0:
static::assertSame($val, 'hello');
break;
case 1:
static::assertSame($val, 'world');
break;
case 2:
static::assertSame($val, 'foo');
break;
case 3:
static::assertSame($val, 'bar');
break;
}
}
static::assertSame($collection[0], 'hello');
static::assertSame($collection[1], 'world');
static::assertSame($collection[2], 'foo');
static::assertSame($collection[3], 'bar');
static::assertTrue(isset($collection[0]));
static::assertTrue(isset($collection[1]));
static::assertTrue(isset($collection[2]));
static::assertTrue(isset($collection[3]));
static::assertFalse(isset($collection[4]));
}
静态方法 make 创建集合 ¶
可以使用 make
方法创建一个集合对象。
public function testMake(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = Collection::make($data);
foreach ($collection as $key => $val) {
switch ($key) {
case 0:
static::assertSame($val, 'hello');
break;
case 1:
static::assertSame($val, 'world');
break;
case 2:
static::assertSame($val, 'foo');
break;
case 3:
static::assertSame($val, 'bar');
break;
}
}
static::assertSame($collection[0], 'hello');
static::assertSame($collection[1], 'world');
static::assertSame($collection[2], 'foo');
static::assertSame($collection[3], 'bar');
static::assertTrue(isset($collection[0]));
static::assertTrue(isset($collection[1]));
static::assertTrue(isset($collection[2]));
static::assertTrue(isset($collection[3]));
static::assertFalse(isset($collection[4]));
}
集合支持迭代器 ¶
集合 collection
是一个标准的迭代器,支持迭代器的用法。
public function testIterator(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
static::assertSame('hello', $collection->current());
static::assertSame(0, $collection->key());
static::assertNull($collection->next());
static::assertSame('world', $collection->current());
static::assertSame(1, $collection->key());
static::assertNull($collection->next());
static::assertNull($collection->next());
static::assertSame('bar', $collection->current());
static::assertSame(3, $collection->key());
$collection->next();
static::assertFalse($collection->current());
static::assertNull($collection->key());
$collection->rewind();
static::assertSame(0, $collection->key());
static::assertSame('hello', $collection->current());
}
集合可统计 ¶
集合实现了 \Countable
可以像普通数组一样统计元素的个数。
public function testCountable(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
static::assertCount(4, $collection);
}
集合数据支持实现 \Leevel\Support\IArray 的对象 ¶
对象实现了 \Leevel\Support\IArray
可以转化为集合数据。
例子
namespace Tests\Support;
use Leevel\Support\IArray;
class TestArray implements IArray
{
public function toArray(): array
{
return [
'hello',
'world',
];
}
}
实现了
\Leevel\Support\IArray
的对象的方法toArray
返回集合的数据。
public function testGetArrayElements2(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestArray());
static::assertSame($collection->toArray(), $data);
}
集合数据支持实现 \Leevel\Support\IJson 的对象 ¶
对象实现了 \Leevel\Support\IJson
可以转化为集合数据。
例子
namespace Tests\Support;
use Leevel\Support\IJson;
class TestJson implements IJson
{
public function toJson(?int $option = null): string
{
if (null === $option) {
$option = JSON_UNESCAPED_UNICODE;
}
return json_encode([
'hello',
'world',
], $option);
}
}
实现了
\Leevel\Support\IJson
的对象的方法toJson
返回集合的数据。
public function testGetArrayElements3(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestJson());
static::assertSame($collection->toArray(), $data);
}
集合数据支持实现 \JsonSerializable 的对象 ¶
对象实现了 \JsonSerializable
可以转化为集合数据。
例子
namespace Tests\Support;
class TestJsonSerializable implements \JsonSerializable
{
public function jsonSerialize(): mixed
{
return [
'hello',
'world',
];
}
}
实现了
\JsonSerializable
的对象的方法jsonSerialize
返回集合的数据。
public function testGetArrayElements4(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestJsonSerializable());
static::assertSame($collection->toArray(), $data);
}
集合数据支持普通数据转化为数组 ¶
public function testGetArrayElements5(): void
{
$data = [
'hello',
];
$collection = new Collection('hello');
static::assertSame($collection->toArray(), $data);
}
集合数据支持 \stdClass 的对象 ¶
对象为 \stdClass
可以转化为集合数据。
\stdClass
的对象返回转化为数组作为集合的数据。
public function testGetArrayElementsWithStdClass(): void
{
$data = [
'hello' => 'world',
'foo' => 'bar',
];
$std = new \stdClass();
$std->hello = 'world';
$std->foo = 'bar';
$collection = new Collection($std);
static::assertSame($collection->toArray(), $data);
}
getValueTypes 集合数据支持值类型验证 ¶
比如下面的数据类型为 string
,只有字符串类型才能加入集合。
public function testGetValueTypesValidate(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data, ['string']);
static::assertSame($collection->toArray(), $data);
static::assertSame(['string'], $collection->getValueTypes());
}
getKeyTypes 集合数据支持键类型验证 ¶
public function testGetKeyTypesValidate(): void
{
$data = [
'hello' => 'world',
'world' => 'hello',
];
$collection = new Collection($data, ['string'], ['string']);
static::assertSame($collection->toArray(), $data);
static::assertSame(['string'], $collection->getKeyTypes());
}
集合数据支持类型验证不符合规则示例 ¶
比如下面的数据类型为 int
,字符串类型就会抛出异常。
public function testTypeValidateException(): void
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage(
'The value of a collection value type requires the following types `int`.'
);
$data = [
'hello',
'world',
];
new Collection($data, ['int']);
}
each 集合数据遍历元素项 ¶
使用闭包进行遍历,闭包的第一个参数为元素值,第二为元素键。
public function testEach(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$i = 0;
$collection->each(function ($item, $key) use (&$i): void {
$this->assertSame($i, $key);
if (0 === $i) {
$this->assertSame($item, 'hello');
} else {
$this->assertSame($item, 'world');
}
++$i;
});
}
each 集合数据遍历元素项支持中断 ¶
遍历元素项的时候返回 false
将会中断后续遍历操作。
public function testEachAndBreak(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$i = 0;
$collection->each(function ($item, $key) use (&$i) {
$this->assertSame($i, $key);
if (0 === $i) {
$this->assertSame($item, 'hello');
return false;
}
++$i;
});
static::assertSame($i, 0);
}
toJson 集合数据支持 JSON 输出 ¶
集合实现了 \Leevel\Support\IJson
接口,可以通过方法 toJson
输出 JSON 字符串。
public function testToJson(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$data = '["hello","world"]';
static::assertSame($data, $collection->toJson());
}
toJson 集合数据支持 JSON 输出默认不要编码 Unicode ¶
JSON_UNESCAPED_UNICODE 可以让有中文的 JSON 字符串更加友好地输出。
json_encode('中文', JSON_UNESCAPED_UNICODE);
public function testToJsonWithCn(): void
{
$data = [
'我',
'成都',
];
$collection = new Collection($data);
$data = '["我","成都"]';
static::assertSame($data, $collection->toJson());
}
toJson 集合数据支持 JSON 输出 ¶
集合实现了 \JsonSerializable
接口,可以通过方法 toJson
输出 JSON 字符串。
public function testJsonSerialize(): void
{
$std = new \stdClass();
$std->hello = 'world';
$std->foo = 'bar';
$data = [
new TestJsonSerializable(),
new TestArray(),
new TestJson(),
$std,
'foo',
'bar',
];
$collection = new Collection($data);
$data = <<<'eot'
[
[
"hello",
"world"
],
[
"hello",
"world"
],
[
"hello",
"world"
],
{
"hello": "world",
"foo": "bar"
},
"foo",
"bar"
]
eot;
static::assertSame(
$data,
$this->varJson(
$collection->jsonSerialize()
)
);
}
__toString 集合数据可以转化为字符串 ¶
集合实现了 __toString
方法,可以强制转化为字符串。
public function testGetSetString(): void
{
$data = [
'hello' => 'world',
'foo' => 'bar',
];
$collection = new Collection($data);
static::assertSame($collection->hello, 'world');
static::assertSame($collection->foo, 'bar');
$collection->hello = 'new world';
$collection->foo = 'new bar';
static::assertSame($collection->hello, 'new world');
static::assertSame($collection->foo, 'new bar');
static::assertSame((string) $collection, '{"hello":"new world","foo":"new bar"}');
}
__get,__set,__isset,__unset 魔术方法支持 ¶
public function testMagicMethod(): void
{
$data = [
'hello' => 'world',
'foo' => 'bar',
];
$collection = new Collection($data);
static::assertSame($collection->hello, 'world');
static::assertSame($collection->foo, 'bar');
$collection->hello = 'new world';
$collection->foo = 'new bar';
static::assertSame($collection->hello, 'new world');
static::assertSame($collection->foo, 'new bar');
static::assertTrue(isset($collection->hello));
static::assertFalse(isset($collection->hello2));
$collection->hello = null;
static::assertFalse(isset($collection->hello));
}
isEmpty 是否为空集合 ¶
public function testIsEmpty(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
static::assertFalse($collection->isEmpty());
$data = [];
$collection = new Collection($data);
static::assertTrue($collection->isEmpty());
}