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
preg_replace
– http://php.net/manual/en/function.preg-replace.php intval
– http://php.net/manual/en/function.intval.php eval
– http://php.net/manual/en/function.eval.php 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);
Ho usato questo metodo nello script della calcolatrice.
$field1 = $_GET["field1"]; $field2 = $_GET["field2"]; $answer = $field1 + $field2; echo "$field1 + $field2 = $answer";