W3docs

interface

La parola chiave "interface" in PHP definisce un insieme di metodi che una classe deve implementare. In questo articolo ne esploriamo sintassi e utilizzo.

La parola chiave interface in PHP

Un'interface è un contratto: elenca i metodi che una classe deve fornire, senza specificare come funzionano. Qualsiasi classe che implements l'interface si impegna a definire ogni metodo dichiarato. Questo permette di programmare rispetto a una capacità ("qualsiasi cosa possa essere registrata", "qualsiasi cosa possa essere serializzata") invece che rispetto a una classe concreta.

Le interface non possono essere istanziate direttamente — non c'è implementazione da eseguire. Esistono affinché classi non correlate possano essere trattate in modo intercambiabile, purché condividano le stesse firme di metodo.

Questa pagina spiega come dichiarare un'interface, implementarne una o più, condividere costanti, estendere interface e verificare i tipi a runtime con instanceof. Se sei nuovo agli oggetti in PHP, inizia con classi e oggetti PHP e cos'è la OOP.

Sintassi

Ecco la sintassi di base per dichiarare un'interface:

interface MyInterface {
  public function someMethod();
}

Questo dichiara un'interface MyInterface con un singolo metodo someMethod(). Regole fondamentali:

  • I corpi dei metodi sono omessi — un'interface dichiara solo le firme, terminando ciascuna con un punto e virgola.
  • Tutti i metodi sono implicitamente public; puoi scrivere public per chiarezza, ma non è consentita altra visibilità (private/protected sono vietati).
  • Una classe adotta un'interface con la parola chiave implements e deve definire ogni metodo, altrimenti PHP genera un errore fatale.

Esempi

Vediamo alcuni esempi pratici di come può essere utilizzata la parola chiave interface. La prima classe implementa un'interface; la seconda ne implementa due contemporaneamente (separate da virgole):

<?php

// Example 1
interface MyInterface {
  public function someMethod();
}
class MyClass implements MyInterface {
  public function someMethod() {
    echo "This is from someMethod." . PHP_EOL;
  }
}

$obj = new MyClass();
$obj->someMethod();

// Output: This is from someMethod.

// Example 2
interface MyOtherInterface {
  public function someOtherMethod();
}
class MyOtherClass implements MyInterface, MyOtherInterface {
  public function someMethod() {
    echo "This is from someMethod." . PHP_EOL;
  }
  public function someOtherMethod() {
    echo "This is from someOtherMethod." . PHP_EOL;
  }
}

$obj2 = new MyOtherClass();
$obj2->someMethod();
$obj2->someOtherMethod();

// Output:
// This is from someMethod.
// This is from someOtherMethod.

In questi esempi definiamo le interface e le usiamo nelle nostre classi PHP per garantire che le classi implementino i metodi richiesti.

Costanti di interface

Un'interface può dichiarare costanti che ogni classe che la implementa eredita. Sono sempre public e non possono essere sovrascritte, il che le rende utili per valori fissi condivisi:

<?php

interface HttpStatus {
  const OK = 200;
  const NOT_FOUND = 404;
}

class Response implements HttpStatus {
  public function describe(): string {
    return "Status " . self::OK;
  }
}

echo (new Response())->describe() . PHP_EOL;
echo HttpStatus::NOT_FOUND . PHP_EOL;

// Output:
// Status 200
// 404

Per le costanti che possono essere sovrascritte, utilizza invece le costanti di classe all'interno di una classe.

Estendere le interface

A differenza delle classi, un'interface può extend più altre interface. L'interface combinata richiede quindi tutti i metodi di ciascun genitore:

<?php

interface Readable {
  public function read(): string;
}

interface Writable {
  public function write(string $data): void;
}

// A single interface that demands both capabilities
interface ReadWrite extends Readable, Writable {}

class File implements ReadWrite {
  private string $buffer = "";
  public function read(): string { return $this->buffer; }
  public function write(string $data): void { $this->buffer = $data; }
}

$f = new File();
$f->write("hello");
echo $f->read() . PHP_EOL;

// Output: hello

Questo è il modo in cui PHP simula l'ereditarietà multipla — vedi ereditarietà PHP per l'ereditarietà singola delle classi con extends.

Type hint e instanceof

Poiché qualsiasi classe che implementa l'interface la soddisfa, puoi usare l'interface come type hint nelle firme delle funzioni e accettare qualsiasi oggetto corrispondente. Usa instanceof per verificare a runtime:

<?php

interface Shape {
  public function area(): float;
}

class Circle implements Shape {
  public function __construct(private float $r) {}
  public function area(): float { return 3.14159 * $this->r ** 2; }
}

function printArea(Shape $shape): void {
  echo round($shape->area(), 2) . PHP_EOL;
}

$c = new Circle(2);
printArea($c);
var_dump($c instanceof Shape);

// Output:
// 12.57
// bool(true)

Interface vs. classe astratta

Entrambe definiscono un contratto, ma risolvono problemi diversi:

  • Un'interface dichiara solo firme di metodi e una classe può implementarne molte. Usala per descrivere una capacità condivisa da classi non correlate.
  • Una classe astratta può fornire metodi e proprietà concreti oltre a quelli astratti, ma una classe ne può estendere solo una. Usala per condividere l'implementazione tra classi correlate.

Quando hai bisogno di condividere codice tra classi senza ereditarietà, utilizza i trait.

Vantaggi

L'utilizzo della parola chiave "interface" offre diversi vantaggi, tra cui:

  • Disaccoppiamento e flessibilità: le interface consentono di sostituire le implementazioni senza modificare il codice dipendente, rendendo il sistema più adattabile.
  • Test più semplici: permettono il mocking e lo stubbing, semplificando i test unitari e il debug.
  • Simulazione dell'ereditarietà multipla: poiché PHP non supporta l'ereditarietà multipla tra classi, una classe può implementare più interface per ereditare contratti di comportamento da più fonti.

Conclusione

La parola chiave interface consente di definire un contratto di metodi richiesti che qualsiasi classe può implementare, indipendentemente dalla sua posizione nella gerarchia delle classi. Combinata con i type hint e instanceof, le interface rendono il codice più flessibile, testabile e disaccoppiato. Utilizza un'interface quando vuoi descrivere una capacità; utilizza una classe astratta quando hai anche bisogno di condividere l'implementazione.

Pratica

Pratica
Qual è lo scopo di un'interface in PHP?
Qual è lo scopo di un'interface in PHP?
Was this page helpful?