Valuta in modo sicuro semplici calcoli matematici

Mi piacerebbe sapere se c'era un modo sicuro per valutare la math come

2+2 10000+12000 10000-20 2 + 2 40 - 20 + 23 - 12 

Senza wherer usare eval() perché l'input può provenire da qualsiasi utente. Le cose che avrei bisogno di implementare sono solo aggiunte e sottrazioni di numbers interi.

C'è qualche frammento che esiste già per questo, o alcune funzioni PHP che non ho incontrato?

Vorrei mettere in discussione l'utilizzo di eval , considerando la varietà delle funzioni matematiche disponibili in PHP. Hai detto che vuoi solo fare math semplice: l'unica ragione per usare eval è eseguire operazioni più complesse o accettare le equazioni dall'integer tessuto dell'utente.

Se vuoi solo aggiungere o sottrarre, disinfettare l'input con intval e andare in città:

 $number1 = '100'; $number2 = 'shell_exec(\'rm -rf *\')'; echo intval($number1) + intval($number2); // 100 

Provalo: http://codepad.org/LSUDUw1M

Funziona perché intval ignora qualsiasi cosa non numbersca.

Se si sta effettivamente ottenendo l'equazione intera da input dell'utente (ad esempio 100 - 20 ), è ansible utilizzare preg_replace per rimuovere qualsiasi cosa, ad exception degli operatori e dei numbers consentiti:

 $input = '20 + 4; shell_exec(\'rm *\')'; $input = preg_replace( '/[^0-9+-]/', '', $input ); eval('$result = '.$input.';'); echo 'result: '.$result; // 24 

Provalo: http://codepad.org/tnISDPJ3

Qui, stiamo usando regex /[^0-9+-]/ , che corrisponde a qualsiasi cosa NOT 0-9 OR + OR – e lo sostituisce con una string vuota.

Se vuoi get di più in profondità con le equazioni consentite, prese direttamente dalla pagina di manuale di eval :

 // credit for code to bohwaz (http://www.php.net/manual/en/function.eval.php#107377) $test = '2+3*pi'; // Remove whitespaces $test = preg_replace('/\s+/', '', $test); $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number $functions = '(?:abs|a?cosh?|a?sinh?|a?tanh?|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; } 

Documentazione

Potresti analizzare da solo le espressioni.

Qualcosa come questo:

 // Minus is the same as plus a negative // Also remove spaces after minus signs $str = preg_replace('/-\s*(\d+)/', '+-$1', $str); // Split on plusses $nums = explode('+', $str); // Trim values $nums = arrays_map('trim', $nums); // Add 'em up echo arrays_sum($nums); 

DEMO: http://codepad.org/ANc0gh27

Ho usato questo metodo nello script della calcolatrice.

 $field1 = $_GET["field1"]; $field2 = $_GET["field2"]; $answer = $field1 + $field2; echo "$field1 + $field2 = $answer";