2008-09-11 1 views
2

В действительности, если у меня есть class c и экземпляры $c1 и $c2 , которые могут иметь различные частные переменные количества, но все их публичные методы возвращают то же значение, я хотел бы быть в состоянии проверить, что $c1 == $c2?PHP: Как проверить, возвращают ли все общедоступные методы двух классов одинаковые значения?

Кто-нибудь знает простой способ сделать это?

ответ

2

Вы также можете реализовать равные функции ($ другой), как

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

или использовать Еогеасп перебрать общественных свойств (такое поведение может быть перезаписана) одного объекта и сравнить их к свойства другого объекта.

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

(непроверенные)

или (более или менее) то же самое с помощью классов Reflection см http://php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionobject
с отражением можно также реализовать более утиного набрав вид Comparision, если вы хотите , например: «Мне все равно, если это экземпляр или тот же класс, если он имеет одни и те же общедоступные методы, и они возвращают« одинаковые »значения.
действительно зависит от того, как вы определяете« равный ».

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

Затем вы можете использовать оператор равенства, чтобы проверить, если оба экземпляра равны или нет.

НТН,

Rushi

+0

Awkward, так как мне действительно нужно добавлять методы к моим классам, но, возможно. Либо $ a == $ b неявно преобразуется в строки перед сравнением, потому что это то, что я хотел бы сделать с издевательской структурой, поэтому у меня нет возможности запускать строчную трансляцию. – 2008-09-11 03:12:22

1

Джордж: Возможно, вы уже видели это, но это может помочь: http://usphp.com/manual/en/language.oop5.object-comparison.php

При использовании оператора сравнения (==), предметные переменные сравниваются простой способ, а именно: два экземпляра объекта равны, если они имеют одинаковые атрибуты и значения и являются экземплярами одного и того же класса.

Они не получают неявно преобразованные в строки.

Если вы хотите сравнить todo, вы в конечном итоге измените свои классы. Вы также можете написать собственный метод сравнения todo с использованием getters & seters

+0

Я вижу, спасибо за помощь, к сожалению, я просто попробовал это и для того, чтобы равенство было истинным, частные переменные также должны содержать одинаковые значения. – 2008-09-11 04:05:43

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

Это, вероятно, единственный способ, где вы не должны изменять дорадиационным код класса

1

Это трудно следовать точно, что вы после этого. Ваш вопрос, похоже, подразумевает, что эти общедоступные методы не требуют аргументов или что если бы они это сделали, они были бы теми же аргументами.

Возможно, вы, возможно, достаточно далеко, используя встроенные классы отражения.

Вложенный ниже быстрый тест, который я опрокинул, чтобы сравнить результаты всех общедоступных методов двух классов и убедиться, что они были такими же. Вы можете легко изменить его, чтобы игнорировать не соответствующие общедоступные методы (т. Е. Проверять только на наличие общих методов в классе 2, которые существуют в классе1). Предоставление набора аргументов для передачи было бы сложнее, но может быть сделано с помощью массива методов/аргументов для вызова по каждому классу.

В любом случае, это может иметь несколько бит, которые могут вам пригодиться.

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

} 
Смежные вопросы