I have a large mathematical expression that has to be created dynamically. For example, once I have parsed "something" the result will be a string like: "$foo+$bar/$baz";
.
So, for calculating the result of that expression I'm using the eval
function... something like this:
eval("\$result = $expresion;"); echo "The result is: $result";
The problem here is that sometimes I get errors that says there was a division by zero, and I don't know how to catch that Exception. I have tried things like:
eval("try{\$result = $expresion;}catch(Exception \$e){\$result = 0;}"); echo "The result is: $result";
Or:
try{ eval("\$result = $expresion;"); } catch(Exception $e){ $result = 0; } echo "The result is: $result";
But it does not work. So, how can I avoid that my application crashes when there is a division by zero?
Edit:
First, I want to clarify something: the expression is built dynamically, so I can't just eval if the denominator is zero. So... with regards to the Mark Baker's comment, let me give you an example. My parser could build something like this:
"$foo + $bar * ( $baz / ( $foz - $bak ) )"
The parser build the string step by step without worrying about the value of the vars... so in this case if $foz == $bak
there's in fact a division by zero: $baz / ( 0 )
.
On the other hand as Pete suggested, I tried:
<?php $a = 5; $b = 0; if(@eval(" try{ \$res = $a/$b; } catch(Exception \$e){}") === FALSE) $res = 0; echo "$res\n"; ?>
But it does not print anything.
The Division function checks if the denominator passed is equal to zero if no it returns the quotient, if yes it throws a runtime_error exception. This Exception is caught by the catch block which prints the message “Exception occurred” and then calls the what function with runtime_error object e.
The most sane would be to check if the divisor is zero before doing the division. Otherwise, you could create a custom function for division like mydivide() and handle the zero case there.
When divide by zero operation is performed, a trap is generated i.e. INT0 is sent to the processor and ultimately SIGFPE signal is sent to the process that performed the operation.
if ($baz == 0.0) { echo 'Divisor is 0'; } else { ... }
Rather than use eval, which is highly dangerous if you're using user-input within the evalled expression, why not use a proper parser such as evalmath on PHPClasses, and which raises a clean exception on divide by zero
You just need to set an error handler to throw an exception in case of errors:
set_error_handler(function () { throw new Exception('Ach!'); }); try { $result = 4 / 0; } catch( Exception $e ){ echo "Divide by zero, I don't fear you!".PHP_EOL; $result = 0; } restore_error_handler();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With