W3docs

eval()

La funzione eval() in PHP valuta una string come codice PHP a runtime. È utile quando occorre eseguire codice PHP in modo dinamico.

Introduzione alla funzione eval()

La funzione eval() valuta una string come codice PHP e la esegue a runtime — nel momento in cui lo script raggiunge la chiamata eval(). Invece di scrivere codice che il parser PHP compila in anticipo, si passa a eval() una string che viene compilata ed eseguita al volo.

Questo rende eval() uno dei costrutti più potenti — e più pericolosi — del linguaggio. Questa pagina ne illustra la sintassi, i valori restituiti, i rari casi in cui è genuinamente utile, i rischi di sicurezza che ne fanno un'ultima risorsa, e le alternative più sicure a cui ricorrere per prime.

eval() è un costrutto del linguaggio, non una funzione ordinaria. Non è possibile chiamarla indirettamente tramite il nome di una funzione variabile né passarla a funzioni callback.

Sintassi

eval(string $code): mixed

L'unico argomento è una string di codice PHP. Alcune regole importanti:

  • Non includere il tag di apertura <?php. La string è già trattata come sorgente PHP, quindi aggiungere <?php farebbe tornare in "modalità HTML".
  • Il codice deve essere sintatticamente valido e terminato correttamente. Un punto e virgola mancante o una parentesi graffa non chiusa produce un errore di analisi. Da PHP 7, un errore di analisi all'interno di eval() lancia un'eccezione ParseError catturabile — le versioni precedenti restituivano false.

Valore restituito

Il modo in cui eval() restituisce un valore dipende da ciò che fa il codice valutato:

  • Se il codice esegue un'istruzione return, eval() restituisce quel valore.
  • Altrimenti restituisce null.
<?php

$result = eval('return 2 + 3;');
echo $result; // 5

Ecco perché un return all'interno di eval() termina soltanto la string valutata, non l'intero script — il controllo torna alla riga successiva a eval(). Consulta l'istruzione return per il comportamento di return nelle funzioni normali.

Esempio di base

Ecco l'utilizzo più semplice possibile — costruire una string di codice ed eseguirla:

php— editable, runs on the server

La variabile $code contiene PHP valido che stampa Hello, world!. eval() compila ed esegue quella string a runtime, quindi il messaggio viene visualizzato. Si noti che all'interno della string non è presente il tag <?php.

Gestione sicura degli errori

Poiché il codice non valido lancia un ParseError, è consigliabile racchiudere il codice non attendibile o generato dinamicamente in un blocco try/catch, in modo che una string errata non faccia crashare l'intera richiesta:

<?php

try {
    eval('echo "missing semicolon"'); // no terminating ;
} catch (ParseError $e) {
    echo "Could not evaluate: " . $e->getMessage();
}

Questo stampa un messaggio "Could not evaluate" invece di un errore fatale, permettendo allo script di continuare.

Quando usare eval()?

Nel PHP moderno, quasi mai — e questa è la risposta onesta. I casi d'uso legittimi e circoscritti includono:

  • Motori di template/espressioni che compilano un mini-linguaggio personalizzato in PHP (Twig e Blade fanno qualcosa di concettualmente simile, ma con un pesante sandboxing).
  • Caching di configurazione compilata come PHP da eseguire in seguito con eval, anche se scrivere un vero file .php e usare include è più veloce e sicuro.
  • Strumenti educativi o di debug come i REPL, dove l'input è completamente attendibile.

Se il valore da calcolare è un dato (numeri, JSON, un elenco di opzioni), quasi certamente non è necessario usare eval().

Rischi di sicurezza

eval() esegue qualsiasi cosa le venga passata. Se qualsiasi parte della string può essere influenzata dall'input dell'utente, un attaccante può eseguire codice arbitrario — leggere file, cancellare dati o prendere il controllo del server. Questa è una classica vulnerabilità di remote code execution (RCE).

<?php

// NEVER do this:
$expr = $_GET['expr'];          // attacker-controlled
eval("\$answer = $expr;");      // attacker can inject any PHP

Una richiesta come ?expr=1; system('rm -rf /') eseguirebbe il comando iniettato. Considera ogni eval() su input utente come un exploit garantito.

Alternative più sicure

Prima di ricorrere a eval(), verifica se una di queste opzioni soddisfa le tue esigenze:

ObiettivoUsa invece di eval()
Analizzare dati strutturatijson_decode()
Chiamare una funzione scelta a runtimeCallback / funzioni variabili
Eseguire codice memorizzato in un fileinclude / require
Associare una string a un comportamentoUn match/switch o un array di closure
Valutare espressioni matematicheUna libreria dedicata per il parsing di espressioni

Conclusione

eval() valuta una string come codice PHP a runtime, restituendo il risultato di un'istruzione return al suo interno oppure null. È genuinamente potente, ma è anche una delle principali fonti di vulnerabilità di sicurezza — qualsiasi input controllato dall'utente passato ad essa costituisce un bug di remote code execution. Usala solo quando l'input è completamente attendibile e nessun costrutto integrato è adatto, racchiudila in un try/catch per ParseError, e preferisci le alternative più sicure illustrate sopra ogni volta che è possibile.

Pratica

Pratica
Qual è lo scopo della funzione eval() in PHP?
Qual è lo scopo della funzione eval() in PHP?
Was this page helpful?