2013-07-15 14 views
7

nel codice sorgente della Dottrina se imbattuto nel seguente test:utilità di utilizzare class_implements VS instanceof

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

non capisco il motivo per cui non si usa instanceof invece:

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

che è meglio in molti modi.

C'è una ragione tangibile per farlo?

Forse spettacoli? Ma davvero, c'è una vera differenza qui, mi sembra che sarebbe come simple VS double quotes.

risposta

2

class_implements restituirà un array di tutte le interfacce implementate da una classe specificata.

Una ragione per usare class_implements oltre instanceof è che è possibile utilizzare class_implementssu una stringa che è il nome di una classe:

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

Ho paura che il tuo codice sia molto sbagliato. Vedi: http://3v4l.org/QTm9L Usando il nome della classe con 'new' di fronte ad esso (cioè semplicemente' HasTest'), PHP lo usa come costante. Poiché non esiste, PHP lo trasforma nella stringa '' HasTest ''. –

+0

Sei estremamente corretto sul fatto che io stia sbagliando molto, e ho aggiornato la mia risposta di conseguenza. – timgws

+0

Ahhh ora vedo il tuo punto (il piccolo errore mi ha distratto dal punto principale), grazie per aver dedicato del tempo all'aggiornamento! –

1

Entrambi sembrano fare la stessa cosa. Ma in realtà non lo sono. Un motivo per utilizzare class_implements potrebbe essere quello di verificare se una classe implementa una determinata interfaccia. Quando si usa instanceof non si ha idea se la classe è un'interfaccia o solo una classe.

5

Per definizione, class_implements si riferisce specificamente a interfaces dove instanceof si riferisce alla classe stessa e a tutti i relativi genitori. Nell'esempio che hai fornito, il codice sta verificando l'implementazione di un'interfaccia e l'utilizzo di instanceof potrebbe causare risultati indesiderati.

Dal PHP Manual instanceof

instanceof è utilizzato per determinare se una variabile PHP è un oggetto un'istanza di una determinata classe:

instanceof può anche essere utilizzato per determinare se una variabile è un istanziata oggetto di una classe che eredita da una classe genitore:

Infine, instanceof può essere utilizzato anche per determinare se una variabile è un'istanza ogg Ject di una classe che implementa un'interfaccia:

Dalle PHP Manual class_implements

class_implements - Restituisce le interfacce che sono attuate dalla classe data

+0

Sì, anche se in quella situazione che è molto strano perché 'Collection' è un'interfaccia del progetto Doctrine, quindi non c'è ragione per cui possa essere una classe ... –

0

instanceof restituisce false se un genitore la classe implementa un'interfaccia. Tuttavia class_implements restituirà l'interfaccia implementata del tuo genitore.

+1

Puoi espandere un po 'di più? Non capisco la tua risposta. –

+0

Sono abbastanza sicuro che è vero il contrario: 'instanceOf' restituisce true anche per le classi genitore. – kaiser