W3docs

instanceof

Scopri come l'operatore PHP instanceof verifica se un oggetto appartiene a una classe, a una classe padre o a un'interfaccia implementata, con esempi.

L'operatore PHP instanceof

instanceof è un operatore PHP per la verifica dei tipi. Restituisce un valore boolean (true o false) che indica se un oggetto appartiene a una determinata classe — o, più utilmente, se appartiene a una classe padre nella catena di ereditarietà oppure implementa una determinata interfaccia.

Questa pagina illustra la sintassi, il comportamento di instanceof con l'ereditarietà e le interfacce, come usarlo con il nome di una classe memorizzato in una variabile, i casi limite che sorprendono (non-oggetti, null, nomi di classe sconosciuti) e quando conviene usarlo rispetto a un'alternativa più pulita.

Se le classi e gli oggetti sono nuovi per te, leggi prima PHP Classes and Objects.

Sintassi

$object instanceof ClassName

L'espressione restituisce true quando $object è un'istanza di ClassName, di una qualsiasi classe che estende ClassName, oppure di una qualsiasi classe che implementa ClassName (quando ClassName è un'interfaccia). Altrimenti restituisce false. Si noti che non esiste una sintassi a chiamata di metodo — instanceof è un operatore, come ===, non una funzione.

Una verifica di base

<?php

class MyClass {}
class MyOtherClass {}

$object = new MyClass();

if ($object instanceof MyClass) {
    echo "The object is an instance of MyClass.";
} else {
    echo "The object is not an instance of MyClass.";
}
// Output: The object is an instance of MyClass.

var_dump($object instanceof MyOtherClass);
// Output: bool(false)

$object è stato creato da MyClass, quindi il primo controllo è true. Non ha nulla a che fare con MyOtherClass, quindi quel controllo è false. Le due classi non sono correlate, anche se sembrano simili.

instanceof e l'ereditarietà

Il vero valore di instanceof è che percorre l'intera catena di ereditarietà. Un oggetto figlio è un'istanza della sua classe padre, quindi il controllo ha successo per ogni antenato.

<?php

class Fruit {}
class Apple extends Fruit {}
class Banana extends Fruit {}

$apple = new Apple();

var_dump($apple instanceof Apple);   // bool(true)  — its own class
var_dump($apple instanceof Fruit);   // bool(true)  — its parent class
var_dump($apple instanceof Banana);  // bool(false) — a sibling class

$apple supera il controllo Fruit perché Apple estende Fruit. Fallisce il controllo Banana perché Apple e Banana sono classi sorelle — nessuna eredita dall'altra. Scopri di più in PHP Inheritance.

instanceof e le interfacce

instanceof viene usato più comunemente con le interfacce. Poiché qualsiasi classe che implementa un'interfaccia conta come sua istanza, è possibile verificare una capacità senza preoccuparsi della classe concreta.

<?php

interface Drawable {
    public function draw(): string;
}

class Circle implements Drawable {
    public function draw(): string { return "○"; }
}

class Square implements Drawable {
    public function draw(): string { return "□"; }
}

$shapes = [new Circle(), new Square(), "not a shape"];

foreach ($shapes as $shape) {
    if ($shape instanceof Drawable) {
        echo $shape->draw();
    }
}
// Output: ○□

La stringa "not a shape" viene ignorata perché non è un Drawable. Questo è il caso d'uso quotidiano: filtrare una lista mista per ottenere solo gli oggetti che supportano il comportamento necessario. Consulta PHP Interfaces per il quadro completo.

Usare un nome di classe da una variabile

Il lato destro può essere una variabile stringa contenente il nome di una classe o interfaccia. Questo è utile quando il tipo viene determinato a runtime.

<?php

class Fruit {}
class Apple extends Fruit {}

$apple = new Apple();
$type  = 'Fruit';

var_dump($apple instanceof $type);   // bool(true)

È anche possibile confrontare due oggetti — $a instanceof $b funziona quando $b è un oggetto, verificando se $a è un'istanza della classe di $b.

Casi limite e insidie

instanceof non genera mai eccezioni né avvisi. Quando l'operando sinistro non è un oggetto, restituisce semplicemente false.

<?php

class Fruit {}

var_dump(null instanceof Fruit);      // bool(false)
var_dump("Fruit" instanceof Fruit);   // bool(false) — a string is not an object
var_dump(42 instanceof Fruit);        // bool(false)

Questo rende instanceof sicuro da usare come guardia prima di chiamare un metodo, senza dover verificare prima is_object(). Se hai bisogno solo di sapere se un valore è un oggetto qualsiasi (di qualsiasi classe), usa invece is_object().

Un punto sottile: se si passa come stringa letterale sul lato destro un nome di classe che non esiste, PHP non esegue l'autoload né genera un errore — restituisce semplicemente false. Un errore di battitura nel nome della classe fallisce silenziosamente. Preferisci il nome di classe nudo ($x instanceof Fruit) a una stringa quando possibile, così il parser lo valida.

Quando usare instanceof — e quando no

Usa instanceof quando hai davvero un valore di cui non puoi garantire il tipo: dati da json_decode, una raccolta mista, un plugin restituito da codice utente, oppure un blocco catch che restringe un'eccezione.

<?php

try {
    throw new InvalidArgumentException("bad input");
} catch (Exception $e) {
    if ($e instanceof InvalidArgumentException) {
        echo "Caught an argument error: " . $e->getMessage();
    }
}
// Output: Caught an argument error: bad input

Evita di disseminare controlli instanceof nel codice per ramificare in base al tipo — le lunghe catene if ($x instanceof A) … elseif ($x instanceof B) significano di solito che un metodo dovrebbe essere definito su ciascuna classe e chiamato polimorficamente. Ricorri a instanceof per proteggere un'operazione, non per sostituire l'ereditarietà.

  • $object instanceof ClassName restituisce true se l'oggetto è un'istanza della classe, di una sottoclasse o di un'interfaccia implementata.
  • Percorre l'intera catena di ereditarietà e fa corrispondere le interfacce — questo è ciò che lo rende potente.
  • Restituisce false (mai un errore) per null, scalari e altri non-oggetti, quindi è sicuro come guardia.
  • Un nome di classe inesistente passato come stringa restituisce false silenziosamente; preferisci il nome di classe nudo.
  • Usalo per verificare il tipo di un valore sconosciuto prima di agire su di esso, non come sostituto del polimorfismo.

Pratica

Pratica
Qual è l'utilizzo dell'operatore 'instanceof' in PHP?
Qual è l'utilizzo dell'operatore 'instanceof' in PHP?
Was this page helpful?