Skip to main content
To handle the special case of expressions surrounded by global parenthesis like "(1+1)"
Source Link
jptsetung
  • 9.2k
  • 3
  • 45
  • 55
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; } } 
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]); } 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; } } 
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; } } 
added 93 characters in body
Source Link
clarkk
  • 1
  • 76
  • 228
  • 370

#Code class Field_calculate { const PATTERN = '/(?:-?\d+(?:.?\d+)?[+-*/])+-?\d+(?:.?\d+)?/';

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]); } 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; } } 

#Code class Field_calculate { const PATTERN = '/(?:-?\d+(?:.?\d+)?[+-*/])+-?\d+(?:.?\d+)?/';

 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 while(strpos($input, '(') || strpos($input, ')')){ $input = preg_replace_callback('/\(([^\(\)]+)\)/', 'self::callback', $input); } // Calculate the result if(preg_match(self::PATTERN, $input, $match)){ return $this->compute($match[0]); } 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; } } 

#Code

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]); } 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; } } 
Source Link
clarkk
  • 1
  • 76
  • 228
  • 370

Take a look at this..

I use this in an accounting system where you can write math expressions in amount input fields..

#Examples

$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 

#Code class Field_calculate { const PATTERN = '/(?:-?\d+(?:.?\d+)?[+-*/])+-?\d+(?:.?\d+)?/';

 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 while(strpos($input, '(') || strpos($input, ')')){ $input = preg_replace_callback('/\(([^\(\)]+)\)/', 'self::callback', $input); } // Calculate the result if(preg_match(self::PATTERN, $input, $match)){ return $this->compute($match[0]); } 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; } }