PHP 计算器:未定义当答案为 0 时溢出

PHP Calculator: Undefined Overflow when answer is 0

我正在用 JS 创建计算器,但计算是在 PHP 中进行的。 计算器必须能够在不使用 eval() 或类似技巧的情况下处理超过 1 个运算符(例如 1+2*3-4/5)。

经过大量搜索后,我得到了这个:

if (isset($_POST)) {
    $equation = $_POST["textview"];
}


$stored = $equation;
$components = preg_split('~([*/%+-])~', $stored, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

while (($index = array_search('*', $components)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] * $components[$index + 1]);
}
while (($index = array_search('/', $components)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] / $components[$index + 1]);
}
while (($index = array_search('%', $components)) !== false) {
    array_splice($components, $index - 1, 3, fmod($components[$index - 1], $components[$index + 1]));
}
while (($index = array_search('+', $components)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] + $components[$index + 1]);
}
while (($index = array_search('-', $components)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] - $components[$index + 1]);
}

echo current($components);

看起来很完美,除了一个问题:当计算结果为0时,它给我一个错误,并且没有结束"while"循环


Notice: Undefined offset: -1 in C:\xampp\htdocs\***************\component\calculation.php on line 26

Notice: Undefined offset: 1 in C:\xampp\htdocs\****************\component\calculation.php on line 26

在这种情况下,第 26 行将是减法(进行了 1-1 运算),但它发生在所有其他应该 return 为 0 的计算中。

我不知道为什么会这样,也不知道如何解决,所以如果有人能帮助我,那就太好了。

问题是 array_search() 正在执行松散比较。当$components的元素是数字时,它会在比较之前将搜索字符串转换为数字。看起来不像数字的字符串被转换为 0,因此 array_search("-", [0]) returns 0 而不是 false(尝试 var_dump('-' == 0, '-' === 0)) .

array_search 有一个可选的 strict 参数,可以使它进行严格比较(像 === 而不是 ==)。将此添加到所有 array_search 调用可解决问题。

$stored = "1-1";
$components = preg_split('~([*/%+-])~', $stored, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
while (($index = array_search('*', $components, true)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] * $components[$index + 1]);
}
while (($index = array_search('/', $components, true)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] / $components[$index + 1]);
}
while (($index = array_search('%', $components, true)) !== false) {
    array_splice($components, $index - 1, 3, fmod($components[$index - 1], $components[$index + 1]));
}
while (($index = array_search('+', $components, true)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] + $components[$index + 1]);
}
while (($index = array_search('-', $components, true)) !== false) {
    array_splice($components, $index - 1, 3, $components[$index - 1] - $components[$index + 1]);
}

echo current($components);