PHP中的對象比較

在以前的文章中,咱們講過PHP中比較數組的時候發生了什麼?。此次,咱們來說講在對象比較的時候PHP是怎樣進行比較的。php

首先,咱們先根據PHP文檔來定義對象比較的方式:git

  • 同一個類的實例,比較屬性大小,根據順序,遇到不一樣的屬性值後比較返回,後續的不會再比較
  • 不一樣類的實例,比較屬性值
  • ===,必須是同一個實例

咱們經過一個例子來看下:github

function bool2str($bool)
{
    if ($bool === false) {
        return 'FALSE';
    } else {
        return 'TRUE';
    }
}

function compareObjects(&$o1, &$o2)
{
    echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "\n";
    echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "\n";
}

class A {
    private $t = true;
    public function setT($t){
        $this->t = $t;
    }
}

class B {
    protected $t = true;
    public function setT1($t){
        $this->t = $t;
    }
}

class C {
    private $t = true;
    public function setT($t){
        $this->t = $t;
    }
}

$a1 = new A();
$a2 = new A();

compareObjects($a1, $a2); // 相同的類
// o1 == o2 : TRUE
// o1 === o2 : FALSE

$a11 = $a1;

compareObjects($a1, $a11); // 相同的實例
// o1 == o2 : TRUE
// o1 === o2 : TRUE

$a11->setT(false);

compareObjects($a1, $a11); // 相同實例屬性值不一樣
// o1 == o2 : TRUE
// o1 === o2 : TRUE

$b = new B();

compareObjects($a1, $b); // 不一樣的類
// o1 == o2 : FALSE
// o1 === o2 : FALSE

$c = new C();

compareObjects($a1, $b); // 相同屬性不一樣的類
// o1 == o2 : FALSE
// o1 === o2 : FALSE

從例子中,咱們能夠看出基本都是符合上述三個條件的,不過須要注意的是,在===的狀況下,若是是同一個實例對象,屬性值不一樣也會返回TRUE。咱們再經過一個更復雜的例子來觀察:數組

$c = new stdClass();
$d = new stdClass();

$c->t1 = 'c';
$c->t2 = 10;
$c->t3 = 50;

$d->t1 = 'c';
$d->t2 = 11;
$d->t3 = 40;

echo 'c > d:', $c > $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c < d:', $c < $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE

$d->t2 = 10; // $t2屬性改爲相等的
echo 'c > d:', $c > $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c < d:', $c < $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE

$d->t3 = 50; // $c、$d屬性都相等了
echo 'c >= d:', $c >= $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c <= d:', $c <= $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c == d:', $c == $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c === d:', $c === $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE

$c1 = clone $c; // 複製同一個對象
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE

$c1->t4 = 'f'; // 增長了一個屬性
echo 'c > c1:', $c > $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c < c1:', $c < $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE

unset($c1->t4);
$c1->t1 = 'd';  // 修改了一個值
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE

這個例子中,咱們進行了<、>的對比,在這種對比中,都是根據屬性值來進行比對的,而對比的順序也是屬性值的英文排序。當$t2有了不相等的比較結果時,$t3就不會再進行比對了。此外,clone以後的對象並非原來的實例對象了,因此clone後的對象和原對象是沒法用===來得到相等的結果的。當一個對象的屬性比另外一個對象多時,這個對象也會比屬性少的對象大。oop

對象的比較其實和數組是有些相似的,但它們又有着些許的不一樣。一個重要的方面就是把握住它們都會進行屬性比較,另外還有就是===的差異,數組中===必須是全部屬性的類型都相同,而對象中則必須是同一個實例,並且對象只要是同一個實例,使用===就不會在意它屬性值的不一樣了。測試

測試代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/PHP%E4%B8%AD%E7%9A%84%E5%AF%B9%E8%B1%A1%E6%AF%94%E8%BE%83.phpthis

參考文檔:
https://www.php.net/manual/zh/language.oop5.object-comparison.php.net

===========code

各自媒體平臺都可搜索【硬核項目經理】對象

相關文章
相關標籤/搜索