57 lines
1.6 KiB
PHP
57 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Helpers;
|
|
|
|
use Exception;
|
|
use Throwable;
|
|
|
|
class FormulaEvaluator
|
|
{
|
|
/**
|
|
* Evaluate a mathematical formula string and return the result as float.
|
|
* Only supports numbers, + - * / ( ) . and scientific notation.
|
|
*
|
|
* @param string $formula
|
|
* @param array $vars (unused, for interface compatibility)
|
|
* @return float
|
|
* @throws \Exception
|
|
*/
|
|
public function evaluate(string $formula, array $vars = []): float
|
|
{
|
|
// Bersihkan spasi
|
|
$formula = trim($formula);
|
|
|
|
// Validasi karakter yang diperbolehkan
|
|
if (!preg_match('/^[0-9\.\+\-\*\/eE\(\)\s]+$/', $formula)) {
|
|
throw new \Exception('Invalid characters in formula: ' . $formula);
|
|
}
|
|
|
|
// Cek kurung buka/tutup
|
|
if (substr_count($formula, '(') !== substr_count($formula, ')')) {
|
|
throw new \Exception('Kurung buka/tutup pada formula tidak seimbang: ' . $formula);
|
|
}
|
|
|
|
// Ganti double minus (contoh: 4--3 jadi 4+3)
|
|
$formula = preg_replace('/--/', '+', $formula);
|
|
|
|
// Ganti +- jadi -
|
|
$formula = preg_replace('/\+\-/', '-', $formula);
|
|
|
|
set_error_handler(function ($errno, $errstr) {
|
|
throw new \Exception("Error evaluating formula: $errstr");
|
|
});
|
|
|
|
try {
|
|
$result = eval("return ($formula);");
|
|
} finally {
|
|
restore_error_handler();
|
|
}
|
|
|
|
if (!is_numeric($result)) {
|
|
throw new \Exception('Formula could not be evaluated: ' . $formula);
|
|
}
|
|
|
|
return (float)$result;
|
|
}
|
|
}
|