eval

(PHP 4, PHP 5, PHP 7, PHP 8)

evalEsegue una stringa come codice PHP

Descrizione

eval(string $code): mixed

Esegue la data stringa code come codice PHP.

Attenzione

eval() è un costrutto del linguaggio molto pericoloso perché permette l'esecuzione di codice PHP arbitrario. Il suo uso è pertanto sconsigliato. Se si è certi che non esistono altre soluzioni al posto di usare eval(), fare particolare attenzione a non inserire codice fornito dall'utente senza averlo preventivamente validato.

Elenco dei parametri

code

Codice PHP valido da eseguire.

Il codice non deve essere incluso nei tag di apertura e chisura di PHP. Ad esempio 'echo "Ciao!";' è corretto invece di '<? echo "Ciao!"; >'. È comunque possibile uscire e rientrare nella modalità PHP attraverso l'utilizzo dei tag PHP appropriati, ad esempio: 'echo "In PHP mode!"; ?>In HTML mode!<? echo "Back in PHP mode!";'.

Oltre a questo, valgono tutte le regole del codice PHP. Questo include l'inserimento al termine di ogni istruzione del punto e virgola. 'echo "Ciao!"' per esempio causerà un parse error, mentre 'echo "Ciao!";' funzionerà.

Un'istruzione return causa immediatamente la terminazione del codice in corso di esecuzione dalla eval().

L'ambito di esecuzione è ristretto a dove eval() viene chiamata. Quindi qualsiasi variabile definita o modificata all'interno di eval() rimarrà visibile dopo la sua terminazione.

Valori restituiti

eval() ritorna null a meno che non venga richiamato return nel codice da valutare, in tal caso il valore passato a return viene ritornato. Se avviene un parse error nel codice valutato, eval() ritorna false e l'esecuzione del codice seguente continua normalmente. Non è possibile catturare un parse error in eval() usando set_error_handler().

Esempi

Example #1 Esempio di eval() - semplice unione di testo

<?php
$string
= 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo
$str. "\n";
eval(
"\$str = \"$str\";");
echo
$str. "\n";
?>

Il precedente esempio visualizzerà:

This is a $string with my $name in it.
This is a cup with my coffee in it.

Note

Nota: Poiché questo è un costrutto del linguaggio e non una funzione, non può essere chiamato con le variabili funzione

Suggerimento

Come con qualsiasi cosa che invia il risultato direttamente al browser, è possibile utilizzare la funzione output-control per catturare l'uscita di questa funzione e salvarla - per esempio - in una stringa (per esempio).

Nota:

In caso di fatal error nel codice valutato, l'intero script termina.

Vedere anche:

add a note

User Contributed Notes 7 notes

up
474
Anonymous
20 years ago
Kepp the following Quote in mind:

If eval() is the answer, you're almost certainly asking the
wrong question. -- Rasmus Lerdorf, BDFL of PHP
up
43
lord dot dracon at gmail dot com
9 years ago
Inception with eval()

<pre>
Inception Start:
<?php
eval("echo 'Inception lvl 1...\n'; eval('echo \"Inception lvl 2...\n\"; eval(\"echo \'Inception lvl 3...\n\'; eval(\'echo \\\"Limbo!\\\";\');\");');");
?>
up
21
Jeremie LEGRAND
7 years ago
At least in PHP 7.1+, eval() terminates the script if the evaluated code generate a fatal error. For example:
<?php
@eval('$content = (100 - );');
?>

(Even if it is in the man, I'm note sure it acted like this in 5.6, but whatever)
To catch it, I had to do:
<?php
try {
eval(
'$content = (100 - );');
} catch (
Throwable $t) {
$content = null;
}
?>

This is the only way I found to catch the error and hide the fact there was one.
up
27
bohwaz
12 years ago
If you want to allow math input and make sure that the input is proper mathematics and not some hacking code, you can try this:

<?php

$test
= '2+3*pi';

// Remove whitespaces
$test = preg_replace('/\s+/', '', $test);

$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functions = '(?:sinh?|cosh?|tanh?|abs|acosh?|asinh?|atanh?|exp|log10|deg2rad|rad2deg|sqrt|ceil|floor|round)'; // Allowed PHP functions
$operators = '[+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?2))?)+$/'; // Final regexp, heavily using recursive patterns

if (preg_match($regexp, $q))
{
$test = preg_replace('!pi|π!', 'pi()', $test); // Replace pi with pi function
eval('$result = '.$test.';');
}
else
{
$result = false;
}

?>

I can't guarantee you absolutely that this will block every possible malicious code nor that it will block malformed code, but that's better than the matheval function below which will allow malformed code like '2+2+' which will throw an error.
up
8
catgirl at charuru dot moe
6 years ago
It should be noted that imported namespaces are not available in eval.
up
5
divinity76 at gmail dot com
7 years ago
imo, this is a better eval replacement:

<?php
function betterEval($code) {
$tmp = tmpfile ();
$tmpf = stream_get_meta_data ( $tmp );
$tmpf = $tmpf ['uri'];
fwrite ( $tmp, $code );
$ret = include ($tmpf);
fclose ( $tmp );
return
$ret;
}
?>

- why? betterEval follows normal php opening and closing tag conventions, there's no need to strip `<?php?>` from the source. and it always throws a ParseError if there was a parse error, instead of returning false (note: this was fixed for normal eval() in php 7.0). - and there's also something about exception backtraces
up
6
darkhogg (foo) gmail (bar) com
14 years ago
The following code

<?php
eval( '?> foo <?php' );
?>

does not throw any error, but prints the opening tag.
Adding a space after the open tag fixes it:

<?php
eval( '?> foo <?php ' );
?>
To Top