PHP: iki sınıfın tüm kamu yöntemleri aynı değerleri dönerseniz nasıl kontrol edebilirim?

5 Cevap php

In effect, if I have a class c and instances of $c1 and $c2 which might have different private variable amounts but all their public methods return the same values I would like to be able to check that $c1 == $c2?

Herkes bunu yapmak için kolay bir yol biliyor mu?

5 Cevap

Ayrıca eşit ($ diğer) işlevi gibi uygulayabilirsiniz

<?php
class Foo {
    public function equals($o) {
        return ($o instanceof 'Foo') && $o.firstName()==$this.firstName();
    }
}

veya bir nesnenin ortak özelliklerini (bu davranışı üzerine olabilir) üzerinde yineleme ve diğer nesnenin özelliklerinde bunları karşılaştırmak için foreach kullanın.

<?php
function equalsInSomeWay($a, $b) {
    if ( !($b instanceof $a) ) {
        return false;
    }

    foreach($a as $name=>$value) {
        if ( !isset($b->$name) || $b->$name!=$value ) {
            return false;
        }
    }
    return true;
}

(Denenmemiş)

or (more or less) the same using the Reflection classes, see http://php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionobject
With reflection you might also implement a more duck-typing kind of comparision, if you want to, like "I don't care if it's an instance of or the same class as long as it has the same public methods and they return the 'same' values"
it really depends on how you define "equal".

Size sınıf içinde PHP'nin __toString sihirli yöntemini tanımlayabilirsiniz.

Örneğin

class cat {
    private $name;
    public function __contruct($catname) {
        $this->name = $catname;
    }

    public function __toString() {
        return "My name is " . $this->name . "\n";
    }
}

$max = new cat('max');
$toby = new cat('toby');
print $max; // echoes 'My name is max'
print $toby; // echoes 'My name is toby'

if($max == $toby) {
    echo 'Woohoo!\n';
} else {
    echo 'Doh!\n';
}

Sonra iki örnekleri eşit olup olmadığını kontrol etmek için eşitlik operatörünü kullanabilirsiniz.

HTH,

Rushi

George: Zaten bu görmüş olabilirsiniz ama bu yardımcı olabilir: http://usphp.com/manual/en/language.oop5.object-comparison.php

Onlar aynı nitelik ve değerlere sahip ve aynı sınıfın örnekleri olan varsa iki nesne örnekleri eşit: karşılaştırma operatörü (==) kullanıldığında, nesne değişkenleri basit bir şekilde, yani karşılaştırılmıştır.

Bunlar örtülü dizelere dönüştürülür alamadım.

Todo karşılaştırma istiyorsanız, size sınıfları değiştirerek sona erecek. Ayrıca alıcılar & kullanarak kendi todo karşılaştırma bazı yöntemini yazabilirsiniz belirleyiciler

Eğer peşinde olduğunuz tam olarak ne takip etmek zor. Sorunuz bu kamu yöntemler yaptılar eğer onlar aynı argümanlar olacağını argümanlar gerektirmez, ya da olmadığını ima görünüyor.

Muhtemelen oldukça uzak dahili yansıma sınıfları kullanarak alabilir.

Aşağıda yapıştırılan iki sınıflarının tüm kamu yöntemleri döner karşılaştırmak ve onlar aynı olduklarını sağlamak için hamile hızlı bir testtir. Kolayca olmayan eşleşen genel yöntemleri (yani sadece Class1 var Class2 kamu yöntemleri eşitlik için kontrol) görmezden bunu değiştirebilir. Geçmek who'da verilmesi yanıltıcıdır olacak - ama her sınıfa karşı aramak için yöntemler adları / argümanlar bir dizi yapılabilir.

Her neyse, bu sizin için kullanım olabilir bunu bazı bit olabilir.

$class1 = new Class1();
$class2 = new Class2();
$class3 = new Class3();
$class4 = new Class4();
$class5 = new Class5();

echo ClassChecker::samePublicMethods($class1,$class2); //should be true
echo ClassChecker::samePublicMethods($class1,$class3); //should be false - different values
echo ClassChecker::samePublicMethods($class1,$class4); //should be false -- class3 contains extra public methods
echo ClassChecker::samePublicMethods($class1,$class5); //should be true -- class5 contains extra private methods

class ClassChecker {

    public static function samePublicMethods($class1, $class2) {

        $class1methods = array();

        $r = new ReflectionClass($class1);
        $methods = $r->getMethods();

        foreach($methods as $m) {
            if ($m->isPublic()) {
                @$result = call_user_method($m->getName(), $class1);
                $class1methods[$m->getName()] = $result;
            }
        }

        $r = new ReflectionClass($class2);
        $methods = $r->getMethods();

        foreach($methods as $m) {

            //only comparing public methods
            if ($m->isPublic()) {

                //public method doesn't match method in class1 so return false
                if(!isset($class1methods[$m->getName()])) {
                    return false;
                }

                //public method of same name doesn't return same value so return false
                @$result = call_user_method($m->getName(), $class2);
                if ($class1methods[$m->getName()] !== $result) {
                    return false;
                }
            }
        }

        return true;
    }
}


class Class1 {

    private $b = 'bbb';

    public function one() {
        return 999;
    }

    public function two() {
        return "bendy";
    }


}

class Class2 {

    private $a = 'aaa';

    public function one() {
        return 999;
    }

    public function two() {
        return "bendy";
    }
}

class Class3 {

    private $c = 'ccc';

    public function one() {
        return 222;
    }

    public function two() {
        return "bendy";
    }


}

class Class4 {

    public function one() {
        return 999;
    }

    public function two() {
        return "bendy";
    }

    public function three() {
        return true;
    }

}

class Class5 {

    public function one() {
        return 999;
    }

    public function two() {
        return "bendy";
    }

    private function three() {
        return true;
    }

}

Sen tanımlamak ne dayalı bir karşılaştırma yapmak yöntemlerini eklentisi ve yazmak için kendinize ait bir sınıf yazıyorum deneyebilirsiniz. Örneğin:

class Validate {
    public function validateName($c1, $c2) {
        if($c1->FirstName == "foo" && $c2->LastName == "foo") {
            return true;
        } else if (// someother condition) {
            return // someval;
        } else {
            return false;
        }
    }

    public function validatePhoneNumber($c1, $c2) {
        // some code
    }
}

Bu muhtemelen alışkanlık önceden varolan sınıf kodunu değiştirmek zorunda tek yolu olacaktır