46 lines
1.3 KiB
PHP
46 lines
1.3 KiB
PHP
<?php
|
||
|
||
namespace App\Helpers;
|
||
|
||
class FormulaHelper
|
||
{
|
||
public static function calculateFormula($formula, $values)
|
||
{
|
||
if (! $formula) {
|
||
return null;
|
||
}
|
||
|
||
// 1) trim off any leading '=' and whitespace
|
||
$parsed = trim($formula);
|
||
$parsed = ltrim($parsed, '=');
|
||
|
||
// 2) normalize multiplication symbols to '*'
|
||
// covers lowercase x, uppercase X, and the unicode ×
|
||
$parsed = str_ireplace(['x', 'X', '×'], '*', $parsed);
|
||
|
||
// 3) replace variables like BD1, EF1 with their numeric values
|
||
$parsed = preg_replace_callback(
|
||
'/\b([A-Z]{2}\d+)\b/',
|
||
function ($matches) use ($values) {
|
||
$key = strtoupper($matches[1]);
|
||
return (isset($values[$key]) && is_numeric($values[$key]))
|
||
? $values[$key]
|
||
: 0;
|
||
},
|
||
$parsed
|
||
);
|
||
|
||
// 4) ensure only digits, operators, dots, parentheses and spaces remain
|
||
if (! preg_match('/^[0-9\+\-\*\/\.\(\) ]+$/', $parsed)) {
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
// 5) evaluate the expression
|
||
return eval("return {$parsed};");
|
||
} catch (\Throwable $e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
} |