rcoelho14
rcoelho14

Reputation: 15

PHP Calculator: Undefined Overflow when answer is 0

I am creating a calculator in JS, but the calculations are made in PHP. The calculator must be able to process more than 1 operator (ex. 1+2*3-4/5) without using eval() or similar tricks.

After searching a lot, I ended up with this:

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

It seems to work perfectly, except for one problem: when the result of the calculation is 0, it gives me an error, and doesn't end the "while" loop


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

In this case, line 26 would be the subtraction (did a 1-1 operation), but it happens with every other calculation that should return a 0.

I have no idea why it happens and how to solve it, so if someone could help me, please, it would be great.

Upvotes: 1

Views: 109

Answers (1)

Barmar
Barmar

Reputation: 781726

The problem is that array_search() is performing loose comparison. When an element of $components is a number, it will convert the search string to a number before comparing. A string that doesn't look like a number is converted to 0, so array_search("-", [0]) returns 0 rather than false (try var_dump('-' == 0, '-' === 0)).

array_search has an optional strict parameter that makes it do strict comparison (like === rather than ==). Adding this to all the array_search calls fixes the problem.

$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);

Upvotes: 1

Related Questions