Po pierwsze od operatora ==
jest wystarczająca w większości przypadków, szczególnie jeśli mówimy o obiektach wartości. Po prostu pamiętaj o podaniu metody __toString
, jeśli chcesz porównać instancję z wartościami skalarnymi.
<?php
final class ValueObject {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function __toString() {
return (string) $this->value;
}
}
$a = new ValueObject(0);
$b = new ValueObject(1);
var_dump(
$a == $b, // bool(false)
$a == $a, // bool(true)
$b == $b, // bool(true)
$a == '0', // bool(true)
$b == '1' // bool(true)
);
Jest jedna haczyka z tym, nie można porównać do typu skalarnego innego niż ciąg (przynajmniej nie w PHP 5 i 7), ponieważ będzie narzekać, że instancja nie może być zamieniony na żądaną wartość. Dlatego zawsze musisz upewnić się, że typ wartości, który porównujesz, jest ciągiem.
Jeśli chcesz uzyskać więcej, np. chcesz wprowadzać małe litery w danych wejściowych lub obsługiwać wartość zmiennoprzecinkową do pewnej dokładności, potrzebujesz innego podejścia. Jednym ze sposobów radzenia sobie z tym jest:
<?php
interface Comparable {
function compareTo(Comparable $other): int;
}
function class_compare(Comparable $a, Comparable $b): int {
return $a->compareTo($b);
}
final class C implements Comparable {
private $value;
public function __construct(int $value) {
$this->value = $value;
}
public function compareTo(Comparable $other): int {
assert($this instanceof $other && $other instanceof $this);
return $this->value <=> $other->value;
}
}
$c1 = new C(0);
$c2 = new C(0);
var_dump($c1->compareTo($c2)); // int(0)
$c0 = new C(0);
$c1 = new C(1);
$c2 = new C(2);
$actual = [$c2, $c1, $c0];
usort($actual, 'class_compare');
var_dump($actual === [$c0, $c1, $c2]); // bool(true)
The assert
jest ważny, ponieważ nie mamy generycznych w PHP. Jest to dość smutny stan rzeczy i nie ma łatwego sposobu na jego wdrożenie.
Co mam tendencję do zrobienia jest następujące.
<?php
final class SomeClass {
private $value;
public function __construct($value) {
$this->value = $value;
}
public static function compare(SomeClass $a, SomeClass $b): int {
return $a->compareTo($b);
}
public function compareTo(SomeClass $other): int {
return $this->value <=> $other->value;
}
public function isEqual($other): bool {
return $other instanceof $this && $other->value === $this->value;
}
public function isIdentical($other): bool {
return $other instanceof $this && $this instanceof $other && $other->value === $this->value;
}
}
Po prostu trzymanie się tych nazw metod zgodnie z konwencją pozwala na ich właściwe użycie. Można nawet podać cechy, aby zaimplementować pożądane domyślne zachowanie wśród wielu klas.
Czy chcesz porównać obiekty, które są tą samą instancją lub dwiema instancjami obiektu z tej samej klasy? Czy sprawdziłeś [podręcznik] (http://php.net/manual/en/language.oop5.object-comparison.php)? – dbf
Java nie ma magicznych metod, więc nie wiem o co dokładnie pytasz. Oczywiście, możesz po prostu dodać metody takie jak w Javie. –
Zamiast porównywać '$ ClassA === $ ClassB', po prostu zaimplementuj equals, więc możesz zrobić' $ ClassA-> equals ($ ClassB) '. – halfer