自动检查两个对象是否相等?
Auto-check equality of two objects?
我需要检查两个 PHP 对象是否相等。当然,我可以轻松地将 isEqualTo(...)
方法添加到 class 来比较所有相关值。然而,具体的 class 将在不久的将来发生变化,我想知道是否有任何自动化的方法可以做到这一点。
示例:
class Contact {
private name; // String
private phone; // Int
private someObject; // Custom Object
public function getName() {
return $this->name;
}
public function setName($newName) {
$this->name = $newName;
}
public function getPhone() {
return $this->phone;
}
public function setPhone($newPhone) {
$this->phone = $newPhone;
}
public function getSomeObject() {
return $this->someObject;
}
public function setSomeObject($newObj) {
$this->someObject = $newObj;
}
// Manual Solution
public function isEqualTo($contact) {
result = $this->name == $contact->getName();
result &= $this->phone == $contact->getPhone();
result &= $this->someObject == $contact->getSomeObject();
return result;
}
}
这显然可行。当然,我知道比较 someObject
的局限性(需要是确切的某个对象才能为真),但这没关系。
不过 class Contact
将在不久的将来扩展。每次我将新的 properties/values 添加到 class 时,我也必须将它们添加到 isEqualTo
。没什么大不了的,就是有点麻烦。
那么,有什么方法可以实现 isEqualTo
以自动实现所有可用的 public 属性吗?
我找到了 get_class_vars
和 get_object_vars
,但是这些方法不适用于 getter 和 setter,只能用于可以直接访问的变量。
我找到了 get_class_methodes
但是这个 return 所有方法,而不仅仅是 getter 和 setter。按 get...
和 set...
过滤方法名称当然可行,但这更像是黑客而不是 "nice and clean" 解决方案。
简而言之:有什么"correct"方法可以自动检查两个PHP对象是否相等?
我不会说这是 "correct" 方式,但由于您不想 implement/maintain 自己的比较 function/method,您可能对 php 的默认行为感兴趣,包括 protected/private 属性的比较:
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
var_dump(
$f1==$f2,
$f1==$f3
);
打印
bool(false)
bool(true)
这对你来说可能足够也可能不够。
如,循环引用如
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
public function setZ($z) {
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
$f1->setZ($f3);
$f3->setZ($f1);
var_dump(
$f1==$f2,
$f1==$f3
);
会导致 Fatal error: Nesting level too deep - recursive dependency?
.
您可以使用反射来做到这一点,但我认为这不是一个好主意。也许 serialize() 是更好的解决方案?
function isEquals(self $obj){
return serialize($obj)===serialize($this)
}
我需要检查两个 PHP 对象是否相等。当然,我可以轻松地将 isEqualTo(...)
方法添加到 class 来比较所有相关值。然而,具体的 class 将在不久的将来发生变化,我想知道是否有任何自动化的方法可以做到这一点。
示例:
class Contact {
private name; // String
private phone; // Int
private someObject; // Custom Object
public function getName() {
return $this->name;
}
public function setName($newName) {
$this->name = $newName;
}
public function getPhone() {
return $this->phone;
}
public function setPhone($newPhone) {
$this->phone = $newPhone;
}
public function getSomeObject() {
return $this->someObject;
}
public function setSomeObject($newObj) {
$this->someObject = $newObj;
}
// Manual Solution
public function isEqualTo($contact) {
result = $this->name == $contact->getName();
result &= $this->phone == $contact->getPhone();
result &= $this->someObject == $contact->getSomeObject();
return result;
}
}
这显然可行。当然,我知道比较 someObject
的局限性(需要是确切的某个对象才能为真),但这没关系。
不过 class Contact
将在不久的将来扩展。每次我将新的 properties/values 添加到 class 时,我也必须将它们添加到 isEqualTo
。没什么大不了的,就是有点麻烦。
那么,有什么方法可以实现 isEqualTo
以自动实现所有可用的 public 属性吗?
我找到了 get_class_vars
和 get_object_vars
,但是这些方法不适用于 getter 和 setter,只能用于可以直接访问的变量。
我找到了 get_class_methodes
但是这个 return 所有方法,而不仅仅是 getter 和 setter。按 get...
和 set...
过滤方法名称当然可行,但这更像是黑客而不是 "nice and clean" 解决方案。
简而言之:有什么"correct"方法可以自动检查两个PHP对象是否相等?
我不会说这是 "correct" 方式,但由于您不想 implement/maintain 自己的比较 function/method,您可能对 php 的默认行为感兴趣,包括 protected/private 属性的比较:
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
var_dump(
$f1==$f2,
$f1==$f3
);
打印
bool(false)
bool(true)
这对你来说可能足够也可能不够。
如
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
public function setZ($z) {
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
$f1->setZ($f3);
$f3->setZ($f1);
var_dump(
$f1==$f2,
$f1==$f3
);
会导致 Fatal error: Nesting level too deep - recursive dependency?
.
您可以使用反射来做到这一点,但我认为这不是一个好主意。也许 serialize() 是更好的解决方案?
function isEquals(self $obj){
return serialize($obj)===serialize($this)
}