복붙노트

eval을 사용하여 문자열에서 수학 표현식 계산

PHP

eval을 사용하여 문자열에서 수학 표현식 계산

문자열에서 수학 표현식을 계산하려고합니다. 나는 이것에 대한 해결책이 eval ()을 사용하는 것이라고 읽었다. 하지만 다음 코드를 실행하려고하면 :

<?php

$ma ="2+10";
$p = eval($ma);
print $p;

?>

그것은 나에게 다음과 같은 오류를 준다 :

누군가이 문제에 대한 해결책을 알고 있습니까?

해결법

  1. ==============================

    1.eval을 사용하는 것을 제안하지는 않지만 (솔루션이 아닙니다), eval은 단편뿐만 아니라 완전한 코드 행을 기대합니다.

    eval을 사용하는 것을 제안하지는 않지만 (솔루션이 아닙니다), eval은 단편뿐만 아니라 완전한 코드 행을 기대합니다.

    $ma ="2+10";
    $p = eval('return '.$ma.';');
    print $p;
    

    당신이 원하는 것을해야합니다.

    더 좋은 해결책은 수학 표현식에 대해 토크 나이저 / 파서를 작성하는 것입니다. 다음은 매우 간단한 정규식 기반 예제입니다.

    $ma = "2+10";
    
    if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $ma, $matches) !== FALSE){
        $operator = $matches[2];
    
        switch($operator){
            case '+':
                $p = $matches[1] + $matches[3];
                break;
            case '-':
                $p = $matches[1] - $matches[3];
                break;
            case '*':
                $p = $matches[1] * $matches[3];
                break;
            case '/':
                $p = $matches[1] / $matches[3];
                break;
        }
    
        echo $p;
    }
    
  2. ==============================

    2.이것 좀 봐.

    이것 좀 봐.

    금액 입력 필드에 수학 표현식을 쓸 수있는 회계 시스템에서 이것을 사용합니다.

    $Cal = new Field_calculate();
    
    $result = $Cal->calculate('5+7'); // 12
    $result = $Cal->calculate('(5+9)*5'); // 70
    $result = $Cal->calculate('(10.2+0.5*(2-0.4))*2+(2.1*4)'); // 30.4
    
    class Field_calculate {
        const PATTERN = '/(?:\-?\d+(?:\.?\d+)?[\+\-\*\/])+\-?\d+(?:\.?\d+)?/';
    
        const PARENTHESIS_DEPTH = 10;
    
        public function calculate($input){
            if(strpos($input, '+') != null || strpos($input, '-') != null || strpos($input, '/') != null || strpos($input, '*') != null){
                //  Remove white spaces and invalid math chars
                $input = str_replace(',', '.', $input);
                $input = preg_replace('[^0-9\.\+\-\*\/\(\)]', '', $input);
    
                //  Calculate each of the parenthesis from the top
                $i = 0;
                while(strpos($input, '(') || strpos($input, ')')){
                    $input = preg_replace_callback('/\(([^\(\)]+)\)/', 'self::callback', $input);
    
                    $i++;
                    if($i > self::PARENTHESIS_DEPTH){
                        break;
                    }
                }
    
                //  Calculate the result
                if(preg_match(self::PATTERN, $input, $match)){
                    return $this->compute($match[0]);
                }
                // To handle the special case of expressions surrounded by global parenthesis like "(1+1)"
                if(is_numeric($input)){
                    return $input;
                }
    
                return 0;
            }
    
            return $input;
        }
    
        private function compute($input){
            $compute = create_function('', 'return '.$input.';');
    
            return 0 + $compute();
        }
    
        private function callback($input){
            if(is_numeric($input[1])){
                return $input[1];
            }
            elseif(preg_match(self::PATTERN, $input[1], $match)){
                return $this->compute($match[0]);
            }
    
            return 0;
        }
    }
    
  3. ==============================

    3.eval 주어진 코드를 PHP로 평가합니다. 주어진 매개 변수를 PHP 코드로 실행한다는 것을 의미합니다.

    eval 주어진 코드를 PHP로 평가합니다. 주어진 매개 변수를 PHP 코드로 실행한다는 것을 의미합니다.

    코드를 수정하려면 다음을 사용하십시오.

    $ma ="print (2+10);";
    eval($ma);
    
  4. ==============================

    4.해결!

    해결!

    <?php 
    function evalmath($equation)
    {
        $result = 0;
        // sanitize imput
        $equation = preg_replace("/[^a-z0-9+\-.*\/()%]/","",$equation);
        // convert alphabet to $variabel 
        $equation = preg_replace("/([a-z])+/i", "\$$0", $equation); 
        // convert percentages to decimal
        $equation = preg_replace("/([+-])([0-9]{1})(%)/","*(1\$1.0\$2)",$equation);
        $equation = preg_replace("/([+-])([0-9]+)(%)/","*(1\$1.\$2)",$equation);
        $equation = preg_replace("/([0-9]{1})(%)/",".0\$1",$equation);
        $equation = preg_replace("/([0-9]+)(%)/",".\$1",$equation);
        if ( $equation != "" ){
            $result = @eval("return " . $equation . ";" );
        }
        if ($result == null) {
            throw new Exception("Unable to calculate equation");
        }
        echo $result;
       // return $equation;
    }
    
    
    $a = 2;
    $b = 3;
    $c = 5;
    $f1 = "a*b+c";
    
    $f1 = str_replace("a", $a, $f1);
    $f1 = str_replace("b", $b, $f1);
    $f1 = str_replace("c", $c, $f1);
    
    evalmath($f1);
    /*if ( $equation != "" ){
    
        $result = @eval("return " . $equation . ";" );
    }
    if ($result == null) {
    
        throw new Exception("Unable to calculate equation");
    }
    echo $result;*/
    ?>
    
  5. ==============================

    5.eval 함수를 사용하면 문자열 인수를 제어 할 수 없을 때 매우 위험합니다.

    eval 함수를 사용하면 문자열 인수를 제어 할 수 없을 때 매우 위험합니다.

    안전한 수학 공식 계산을 위해 Matex를 사용해보십시오.

  6. ==============================

    6.eval 된 표현식은 ";"로 끝나야합니다.

    eval 된 표현식은 ";"로 끝나야합니다.

    이 시도 :

    $ma ="2+10;";
    $p = eval($ma);
    print $p;
    

    그건 그렇고, 이것은 범위 밖이지만 'eval'함수는 표현식의 값을 반환하지 않습니다. eval ( '2 + 10')은 12를 반환하지 않습니다. 12를 반환하려면 eval ( 'return 2 + 10;');

  7. from https://stackoverflow.com/questions/18880772/calculate-math-expression-from-a-string-using-eval by cc-by-sa and MIT license