比如 SlimPHP 中的 Request
实现。
public function withAttribute($name, $value)
{
$clone = clone $this;
$clone->attributes->set($name, $value);
return $clone;
}
with 的实现都涉及到 clone $object
,clone 就会申请新的变量空间。为什么不用 set 呢?一个请求过来一个 Request
对象就可以了吧。
public function setAttribute($name, $value)
{
$this->attributes->set($name, $value);
return $this;
}
好问题!
因为
PSR-7
规定,HTTP Message和URI都是值对象(value object
),值对象的一个特征是它的值决定了它的唯一性,也就是说如果两个值对象的所有值都是一样的,那它们也应该是同一个对象;反过来说,如果两个值对象有至少一个值不一样,那它们就应该算两个不同的对象。正因为这个原因,当遵循PSR-7而你要改变Request
一个属性时,你应该创建另一个对象,而不能在原来的对象上做修改,所以要用clone
而不能简单地赋值。所以,值对象是一种不可变(immutable
)的对象。那么,
PSR-7
为什么要选用不可变的值对象来规范HTTP Message呢?原因有以下几点:因为HTTP Message本身就应该是一个不可变的状态。当一个用户给你的程序发送请求,发送完成后请求的内容就已经固定,不会再变,只会有下一个相同或不同的请求。
值对象可以保存原始请求的一切状态,任何其他的程序都可以获得这种原始状态。
官方FIG提供了一段示范值对象好处的代码:
其实这些在PSR-7的Meta Document中都有说明
http://www.php-fig.org/psr/ps...