PHP: la struttura di controllo match

Con un funzionamento simile all’istruzione switch, il nuovo blocco match ha la seguente sintassi:

match (espressione) {
  pattern1 => azione1,
  pattern2 => azione2,
  ...
  default => azione_default
}

dove espressione e i vari pattern possono essere valori statici o espressioni dinamiche. Rispetto a switch, differisce per alcuni aspetti:

  • Restituisce un valore. Questo ne suggerisce un uso simile a quello dell’operatore ternario, permettendo però di valutare condizioni più complesse
  • Esegue un confronto stretto, cioè compara espressione con i vari pattern non solo per valore, ma anche per tipo
  • Genera un’eccezione quando espressione non eguaglia uno dei pattern

Utilizzo di match in PHP

Un utilizzo tipico dell’istruzione match è simile a quello illustrato di seguito: a seguito di una richiesta HTTP effettuata mediante cURL, si stampa un messaggio per comunicarne l’esito all’utente. Con un’istruzione switch, la soluzione sarebbe simile a questa:

$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // $ch in questo caso è una chiamata a curl_init()

$message = '';

switch ($status_code) {
	case 200:
		$message = 'Ok';
		break;
	case 201:
		$message = 'Creato';
		break;
	case 204:
		$message = 'Ok, ma nessuna risposta';
		break;
	case 403:
		$message = 'Accesso negato';
		break;
	case 500:
		$message = 'Errore interno del server';
		break;
}

echo $message;

Utilizzando l’istruzione match, possiamo scrivere la seguente forma equivalente:

$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

$message = match ($status_code) {
	200 => 'Ok',
	201 => 'Creato',
	204 => 'Ok, ma nessuna risposta',
	403 => 'Accesso negato',
	404 => 'Non trovato',
	500 => 'Errore interno del server'
};

echo $message;

Si può facilmente notare la maggior semplicità della sintassi.

Un altro possibile utilizzo è la valutazione di condizioni booleane. In questo caso, il match andrà effettuato su un valore true oppure false. A fini puramente illustrativi si può immaginare il caso in cui si intende fornire un messaggio più generico per diversi status code:


$message = match (true) {
	$status_code >= 200 && $status_code < 300 => 'Operazione effettuata',
	$status_code >= 400 && $status_code < 499 => 'Risorsa non raggiungibile. Potrebbe non esistere, essere stata spostata o potresti non avere le autorizzazioni per accedere',
	$status_code === 500 || $status_code === 503 => 'Errore del server'
};

echo $message;

La casistica precedente permette di mostrare un’altra funzionalità del blocco match, cioè l’intercettazione di più corrispondenze:

$message = match ($status_code) {
	200,201,204 => 'Operazione effettuata',
	400,401,403,404,410 => 'Risorsa non raggiungibile. Potrebbe non esistere, essere stata spostata o potresti non avere le autorizzazioni per accedere',
	500,503,508,510 => 'Errore del server'
};

echo $message;

Gestire le corrispondenze mancate

Come anticipato, il blocco match lancia un’eccezione quando non viene trovata una corrispondenza. In questo caso, basta aggiungere il pattern default. Con riferimento al primo esempio, il risultato sarebbe come segue:

$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

$message = match ($status_code) {
	200 => 'Ok',
	201 => 'Creato',
	204 => 'Ok, ma nessuna risposta',
	403 => 'Accesso negato',
	404 => 'Non trovato',
	500 => 'Errore interno del server',
	default => 'Casistica non contemplata'
};

echo $message;