1

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.

asked Sep 17, 2019 at 16:38
12
  • Possible duplicate of "Notice: Undefined variable", "Notice: Undefined index", and "Notice: Undefined offset" using PHP Commented Sep 17, 2019 at 16:40
  • When $index is 0, $components[$index - 1] will try to access $components[-1]. Commented Sep 17, 2019 at 16:41
  • @Barmar what's the way to fix it, then? I really have no idea :| Commented Sep 17, 2019 at 16:44
  • See 3v4l.org/IhW94 At the end of the first loop, you've replaced the array of 0=>1, 1=> '-', 2=>1 with 0=>0, so it breaks. For some odd reason, array_search('-', [0]) returns 0, which is not false. Commented Sep 17, 2019 at 16:47
  • When I try this with $stored = "1-1"; I get an infinite loop, not that error. Commented Sep 17, 2019 at 16:47

1 Answer 1

1

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);
answered Sep 17, 2019 at 16:59
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it works very well! I actually didn't know about that "strict" parameter. Still don't know very well how the array_search works

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.