Risposte:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
È possibile utilizzare l'operatore "instanceof". Per usarlo, l'operando di sinistra è un'istanza di classe e l'operando di destra è un'interfaccia. Restituisce vero se l'oggetto implementa una particolare interfaccia.
Come therefromhere sottolinea, è possibile utilizzare class_implements()
. Proprio come con Reflection, questo ti consente di specificare il nome della classe come stringa e non richiede un'istanza della classe:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
fa parte dell'estensione SPL.
Vedi: http://php.net/manual/en/function.class-implements.php
Alcuni semplici test delle prestazioni mostrano i costi di ciascun approccio:
Costruzione di oggetti al di fuori del ciclo (100.000 iterazioni) ____________________________________________ | class_implements | Riflessione | instanceOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Costruzione di oggetti all'interno del ciclo (100.000 iterazioni) ____________________________________________ | class_implements | Riflessione | instanceOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms | 83 ms | Costruttore economico | 431 ms | 607 ms | 338 ms | Costruttore costoso '--------------------------------------------'
100.000 iterazioni ____________________________________________ | class_implements | Riflessione | instanceOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | N / A | '--------------------------------------------'
Dove il costoso __construct () è:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Questi test si basano su questo semplice codice .
nlaq sottolinea che instanceof
può essere utilizzato per verificare se l'oggetto è un'istanza di una classe che implementa un'interfaccia.
Ma instanceof
non distingue tra un tipo di classe e un'interfaccia. Non sai se l'oggetto è una classe che sembra essere chiamata IInterface
.
Puoi anche utilizzare l'API di riflessione in PHP per testarlo in modo più specifico:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
riutilizzarli.
class_implements()
poiché è ovviamente più veloce chiamare class_implements e poi in_array, invece di fare una riflessione completa
Anche per aiutare le ricerche future is_subclass_of è anche una buona variante (per PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
La is_a
funzione manca qui come alternativa.
Ho fatto alcuni test delle prestazioni per verificare quale dei modi indicati è il più performante.
instanceof [object] took 7.67 ms | + 0% | ..........
is_a [object] took 12.30 ms | + 60% | ................
is_a [class] took 17.43 ms | +127% | ......................
class_implements [object] took 28.37 ms | +270% | ....................................
reflection [class] took 34.17 ms | +346% | ............................................
Aggiunti alcuni punti per "sentire" realmente vedere la differenza.
Generato da questo: https://3v4l.org/8Cog7
Nel caso in cui tu abbia un oggetto da controllare, usa instance of
come indicato nella risposta accettata.
Nel caso tu abbia una classe da controllare, usa is_a
.
Dato il caso in cui si desidera creare un'istanza di una classe in base a un'interfaccia richiesta, è più preformante da utilizzare is_a
. C'è solo un'eccezione: quando il costruttore è vuoto.
Esempio:
is_a(<className>, <interfaceName>, true);
Tornerà bool
. Il terzo parametro " allow_string " consente di controllare i nomi delle classi senza creare un'istanza della classe.