Reputation: 15
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
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