2013-07-15 7 views
7

w kodzie źródłowym doktryny, jeśli natknęli się następujący test:Przydatność użyciu class_implements VS instanceof

if (in_array('Doctrine\Common\Collections\Collection', class_implements($var))) { 
    // ... 
} 

Nie rozumiem, dlaczego nie używając instanceof zamiast:

if ($var instanceof Doctrine\Common\Collections\Collection) { 
    // ... 
} 

co jest lepsze w wielu sposoby.

Czy jest to namacalny powód?

Może występy? Ale tak naprawdę, czy jest jakakolwiek prawdziwa różnica, wydaje mi się, że byłoby to jak simple VS double quotes.

Odpowiedz

2

class_implements spowoduje zwrócenie tablicy wszystkich interfejsów implementowanych przez określoną klasę.

Jednym z powodów do korzystania class_implements nad instanceof jest to, że można użyć class_implementsna sznurku że to nazwa klasy:

<?php 
interface HasTest { 
    public function test(); 
} 

class TestClass implements HasTest { 
    public function test() { 
     return 'This is a quick test'; 
    } 
} 

$test = array (
    'test' => 'TestClass' 
); 


// !! Using instanceof 
var_dump($test['test'] instanceof HasTest); 

// !! Using class_implements 
var_dump(in_array('HasTest', class_implements($test['test']))); 

/** 
* Output: 
* 
* bool(false) 
* bool(true) 
*/ 


$class = new $test['test']; 
var_dump($class instanceof HasTest); 

/** 
* Output: 
* bool(true) 
*/ 
+0

Obawiam się, że Twój kod jest bardzo błędny. Zobacz: http://3v4l.org/QTm9L Używanie nazwy klasy z 'new' przed nią (tj. Po prostu' HasTest') sprawia, że ​​PHP używa go jako stałej. Ponieważ nie istnieje, PHP przekształca go w ciąg znaków "HasTest". –

+0

Masz całkowitą rację, że źle się czuję i odpowiednio zaktualizowałem swoją odpowiedź. – timgws

+0

Ahhh teraz widzę twój punkt (mały błąd rozproszył mnie z głównego punktu), dziękuję za poświęcenie czasu na aktualizację! –

1

Obie wydają się robić to samo. Ale tak naprawdę nie są. Jednym z powodów użycia class_implements może być sprawdzenie, czy klasa implementuje określony interfejs. Podczas korzystania z instanceof nie masz pojęcia, czy klasa jest interfejsem, czy tylko klasą.

5

Z definicji class_implements odnosi się konkretnie do interfaces, gdzie instanceof odnosi się do samej klasy i wszystkich jej rodziców. W podanym przykładzie kod weryfikuje implementację interfejsu, a użycie instanceof może spowodować niepożądane wyniki.

Z PHP Manual instanceof

instanceof jest używany do określenia, czy zmienna PHP jest instancja przedmiotem pewnej klasy:

instanceof mogą być również wykorzystywane w celu ustalenia, czy zmienna jest instancja obiekt klasy, która dziedziczy z klasy nadrzędnej:

Wreszcie, instanceof może być również użyty do określenia, czy zmienna to utworzona instancja Ject z klasy, która implementuje interfejs:

Z PHP Manual class_implements

class_implements - Powrót interfejsy, które są wdrażane przez danej klasy

+0

Tak, chociaż w tej sytuacji to bardzo dziwne, ponieważ 'Collection' jest Interfejs projektu Doctrine, więc nie ma powodu, żeby to była klasa ... –

0

instanceof zwróci false jeśli rodzic klasa implementuje interfejs. Jednak class_implements zwróci zaimplementowany interfejs twojego rodzica.

+1

Czy możesz rozszerzyć nieco więcej? Nie rozumiem twojej odpowiedzi. –

+0

Jestem prawie pewien, że jest odwrotnie: 'instanceOf' zwraca także true dla klas nadrzędnych. – kaiser