PHP8新功能之WeakMap类

作者: 温新

分类: 【PHP基础】

阅读: 2618

时间: 2022-01-26 09:40:49

什么是WeakMap

WeakMap是将对象作为key来访问的map。也就是说,WeakMap中的是存储另一个对象的引用,一旦另一个对象被删除,该WeakMap的key的引用也会断开。

官方手册:https://www.php.net/manual/zh/class.weakmap.php

不使用WeakMap的案例

<?php

// 房子
class House
{
	public function __construct(public array $rooms = [])
	{
	}

	// 添加人
	public function addPerson(Person $person)
	{
		$this->rooms[$person->name] = $person;
	}
}

// 人
class Person
{
	public function __construct(public string $name)
	{
	}
}


$house = new House();
$lucy = new Person('lucy');
$jony = new Person('jony');

// 为房子添加人
$house->addPerson($lucy);
$house->addPerson($jony);

echo count($house->rooms); // 2人
unset($lucy); // 删除1人
echo count($house->rooms); // 还是2人

// 这个人还在
$lucyObj = $house->rooms['lucy'];
echo $lucyObj->name; // lucy

简单理解:

1)有一个2室一厅的房子,叫House类;

2)有2个人,lucy和jony要去租房子,经过一番寻找,终于找到了这个叫House的房子,决定一人租一间;

3)$house房东为$lucy$jony这两个人签了租房合同,合同中有他们两人的信息,存放在$house房东那里。就这样两人成功入住了;

4)半年后,$lucy因工作调用,不在这个城市了,决定把房子退掉。办理完退房和,这间房子已经空着了;

5)但是当房东去查房时,发现$lucy还在,并没有走。

问题:这里就存在一个问题,$lucy退完房子后,这个房子不在于属于它了,她的东西都应该不存在的。现在相反的是,她退了房子,她和她的东西都还在。要解决这个问题,使用WeakMap,也就是,你走了,你和你的东西都要走。

注意点:使用 & 传值会存在同样的问题

class House
{
	public function __construct(public array $rooms = [])
	{
	}

	// 添加人。注意是,变成了 & 传值
	public function addPerson(Person &$person)
	{
		$this->rooms[$person->name] = $person;
	}
}

WeakMap的使用

WeakMap解决问题,不租了,你和你的东西都要走。

1)解决lucy走的问题

class House
{
	public WeakMap $rooms;

	public function __construct()
	{
		// 实例化 WeakMap
		$this->rooms = new WeakMap();
	}

	public function addPerson(Person $person)
	{
        // 注意,这里的键一定是要一个对象
		$this->rooms[$person] = $person->name;
	}
}

class Person
{
	public function __construct(public string $name)
	{
	}
}

// 房东
$house = new House();
// 租房的人
$lucy = new Person('lucy');
$jony = new Person('jony');

// 租房并给要钥匙
$house->addPerson($lucy);
$house->addPerson($jony);

// 查看租房人数
echo count($house->rooms); // 2人
// lucy不租了(删除引用)
unset($lucy);
// 再次查看租房人数
echo count($house->rooms); // 1人

$lucyObj = $house->rooms['lucy'];
// 报错,lucy这个人已经走了
print_r($lucyObj);

2)查看租客信息

解决了lucy不租了的问题,那么现在想查看剩余租客的信息怎么办?WeakMap提供了迭代器来解决这个问题,详情见官方手册。

// 通过调用WeakMap中提供的迭代器方法来查看其他租客信息
foreach ($house->rooms->getIterator() as $k => $v) {
	print_r($k);
}

我是温新

每天进步一点,就一点点

请登录后再评论