2

実際には、プライベート変数の量が異なる可能性のあるclass cand のインスタンスが$c1あり、$c2 それらのすべてのパブリックメソッドが同じ値を返す場合、それを確認できるようにしたいと思います$c1 == $c2?

これを行う簡単な方法を知っている人はいますか?

4

5 に答える 5

2

あなたが求めているものを正確にフォローするのは難しいです。あなたの質問は、これらのパブリック メソッドが引数を必要としないこと、または必要な場合は同じ引数になることを暗示しているようです。

組み込みのリフレクション クラスを使用すると、かなり遠くまで到達できる可能性があります。

以下に貼り付けたのは、2 つのクラスのすべてのパブリック メソッドの戻り値を比較し、それらが同じであることを確認するために作成した簡単なテストです。一致しないパブリック メソッドを無視するように簡単に変更できます (つまり、class1 に存在する class2 のパブリック メソッドの等価性のみをチェックします)。渡す引数のセットを指定するのはややこしいですが、各クラスに対して呼び出すメソッド名/引数の配列を使用して実行できます。

とにかく、これにはいくつかのビットが含まれている可能性があります。

$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;
    }

}
于 2008-09-11T08:19:23.483 に答える
2

次のような equal($other) 関数を実装することもできます

<?php
クラス Foo {
    パブリック関数 equals($o) {
        return ($o instanceof 'Foo') && $o.firstName()==$this.firstName();
    }
}

または foreach を使用して、1 つのオブジェクトのパブリック プロパティを反復処理し (この動作は上書きされる可能性があります)、それらを他のオブジェクトのプロパティと比較します。

<?php
関数 equalsInSomeWay($a, $b) {
    if ( !($b インスタンスの $a) ) {
        false を返します。
    }

    foreach($a as $name=>$value) {
        if ( !isset($b->$name) || $b->$name!=$value ) {
            false を返します。
        }
    }
    true を返します。
}

(未テスト)

または (多かれ少なかれ) Reflection クラスを使用して同じです。 http://php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionobject を参照して ください -必要に応じて、「同じパブリックメソッドがあり、それらが「同じ」値を返す限り、それがインスタンスであるか同じクラスである か
は気にしません」のようなタイプの比較。
「等しい」と定義します。

于 2008-09-11T08:43:07.090 に答える
1

クラス内で PHP の__toStringマジック メソッドを定義できます。

例えば

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';
}

次に、等値演算子を使用して、両方のインスタンスが等しいかどうかを確認できます。

HTH、

ルシ

于 2008-09-11T03:02:59.983 に答える
1

George: すでに見たことがあるかもしれませんが、参考になるかもしれません: http://usphp.com/manual/en/language.oop5.object-comparison.php

比較演算子 (==) を使用すると、オブジェクト変数は単純な方法で比較されます。つまり、2 つのオブジェクト インスタンスは、同じ属性と値を持ち、同じクラスのインスタンスである場合に等しくなります。

暗黙的に文字列に変換されることはありません。

比較を行いたい場合は、クラスを変更することになります。ゲッターとセッターを使用して、独自の todo 比較のメソッドを作成することもできます

于 2008-09-11T03:18:06.640 に答える
0

プラグインに独自のクラスを作成して、定義に基づいて比較を行うメソッドを作成することができます。例えば:

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
    }
}

これはおそらく、既存のクラス コードを変更する必要がない唯一の方法です。

于 2008-09-11T04:34:40.107 に答える