suppose I do this in php:
eval("\$answer=1--1;");
The expression 1--1 will lead to a syntax error in eval, my question is how do I detect the error and handle it gracefully? ie: catch error in eval and then print out a helpful message. Right now, it just spits out "Parse error: syntax error, unexpected T_DEC". Unfortunately, the php manual states that it is not possible to catch parse errors with the set_error_handler() function.
This is for a simple school assignment and they have suggested using "eval()".
As the assignment is trivial, perhaps there is no need to worry about these rare cases.
Prepend the string with something like echo 'd41d8cd98f00b204e9800998ecf8427e';.
Turn on output buffering.
eval
Get contents of the output buffer and delete it.
Test whether the contents start with 'd41d8cd98f00b204e9800998ecf8427e'.
Alternatively, use the Parsekit.
There are not a single reason to use eval for math equations.
As there are thousands math parsers around. Safe and maintainable.
By pre-pending # symbol to eval to suppress the error output, and then by checking error_get_last():
$test = #eval($str);
if (error_get_last())
var_dump(error_get_last());
Then, parse the PHP token referenced in the error message ('message' value, or T_DEC in your case) against the list: http://php.net/manual/en/tokens.php
However, certain parse errors may fail your entire script, such as calling undefined functions. And, because you suppressed the error output, the failure won't appear in your logs. Basically: avoid eval for anything other than an amusing toy to pass the time.
Edit: I was going by the assumption "\$answer=1--1;" is not really the value you want to check (just too obvious), but just a test example of what kinds of strings you might be passing to eval. If it is really, you should just fix it right there. But if you want to pass and check any string at all in eval, then the above will help.
Related
"multiple annotations found at this line"
i have been using aptana and other IDE before, but never gave me this error, but yesterday i installed zend studio and it was giving following error in all my code where i have assigned and also check if condition at same time.
code:
line 16: if ($message_array = #unserialize($e->getMessage()))
line 17: $message = $message_array;
on all if condition, where i assigned the value to a variable and also check if the variable is true/false, it gives me error "multiple annotations found at this line"
Yeah, that syntax is typically flagged by most decent IDEs as "Accidental Assignment" (since it's not obvious if you meant = or ==). Most will allow you to wrap it in a () to silence the error (since then it's apparent you want the result rather than a test):
if (($message_array = #unserialize($e->getMessage()))) {
}
Also, for readability and maintainability, I would suggest a few things there.
First, use braces. Since it's only a special case that lets you not use them, I personally think it's better form to always use them so that it's clear what was meant.
Second, do all asignment outside of the if clause. It makes it more explicit and easier to tell at a quick glance what you meant. Plus it looks less cluttered.
$message_array = #unserialize($e->getMessage());
if ($message_array) {
...
}
Third, I would suggest avoiding the # operator. To me it's a sign of code-rot. While I know it's easy to use and easier than properly handling the error, I think it's just a short-cut that will make life harder for you. You can avoid it in a few ways. First, you can check the string before you pass it to unserialize. Make sure it's non-empty, a string, etc. Secondly, you can install an error handler to throw exceptions on PHP errors (what I do). That way, you just wrap the unserialize call in a try {} catch(){} block. It's nicer since you actually can inspect the error rather than just trusting that the thrown error is what you think it is...
That is not an actual error. Instead the IDE has found more than one error, warnings or hints at the same code line.
You can look at the Problems tab to see the actual errors and warnings.
This question already has answers here:
Reference Guide: What does this symbol mean in PHP? (PHP Syntax)
(24 answers)
Closed 4 years ago.
What does the '#' symbol do in the following code?
#mkdir(ROOT. "cache/");
It suppresses errors from displaying:
PHP supports one error control operator: the at sign (#). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
If the track_errors feature is enabled, any error message generated by the expression will be saved in the variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it.
As noted in the comments, I too cannot imagine a reason to actually use this functionality -- write code that deals appropriately with error states/conditions.
As pointed out, it is the error suppression operator.
But what has not been pointed out, is that it is very bad practice to use - errors should not fail silently.
Check for error returns, and use try/catch blocks where exceptions are being used.
In the specific example...
#mkdir(ROOT. "cache/");
...it ignores any errors from mkdir(). The docs says it returns FALSE on failure, so you should be doing...
if ( ! mkdir(ROOT. "cache/")) {
// Handle error.
}
People seem to forget that PHP was a quick dirty language for getting things done, only recently has it tried to be mature and sophisticated.
Error suppression is a quick and dirty way of making functions behave the way you need them to, because in web-development you cannot predict what will be thrown at you, and sometimes it is not worth caring!
A classic example is the useful function getimagesize, that allows you to get some information about an image that someone has uploaded.
This function chucks a wobbly if the image file is not a standard image file. It is not really the developers role to inspect a file, determine if it can be loaded into getimagesize. There might be elegant ways of doing this, but seriously I don't care!
just do this:
if( !($a = #getimagesize( $_FILE['file']['tmp_name'] )))
{
unlink( $_FILE['file']['tmp_name'] );
//politely tell user that you rejected their image!
}
yes, you could use try and catch statements which are more elegant, but in the end, you have caught the error and suppressed the error message, which is what you wanted without wearing out the tab-key!
Contrary to what above answers say, the # prefix used carefully does not result in a runaway train wreck. It just allows the developer to accommodate errors in the way they prefer.
What I have and want to do
I have an input area.
I have a JS script what reads the input area's innerHTML and encodes it using encodeURICompontent then sends the value to evaluate.php?code=+value;
I have an evaluate.php what GET's the code's value from the URL and returns an evaluated value using eval($code) to the javascript.
And at the end it puts the xmlHttp.responseText to a div.
But I get this error when the eval is executed:
Parse error: syntax error, unexpected '"', expecting T_STRING in /Applications/MAMP/htdocs/Apps/editor/includes/exe.php(5) : eval()'d code on line 1
Evaluate.php
if(isset($_GET["code"])){
$e = $_GET["code"];
echo eval($e);
}
The value what I try to evaluate is just:
echo "Hello World!";
Then this is looks like in $_GET["code"] as:
echo \"Hello World!\";
According to PHP's documentation:
eval() returns NULL unless return is
called in the evaluated code, in which
case the value passed to return is
returned. If there is a parse error in
the evaluated code, eval() returns
FALSE and execution of the following
code continues normally. It is not
possible to catch a parse error in
eval() using set_error_handler().
So I think there may be a problem when you run echo eval($e).
P.S. It's best practice not to use double quotes in PHP unless a variable is contained within those quotes. For example, use "Hello, $name" and use 'Hello, Bob'.
Obviously you have an error in a string you are tying to evaluate. Try to output it first and see if it has semi columns and things like that.
But you should never (!) evaluate code you get from URL! Never-never, anyone can send "exec('rm -rf /')".
I feel terrible answering this. In your PHP settings, magic_quotes_gpc might be enabled which "corrupts" your incoming data by escaping it.
In order to get it working, you might want to add a little more insecurity to your undertaking by disabling magic quotes.
If that doesn't fix it, debug your input by following Silver Light's suggestions.
I've seen code samples that use an # before fopen as in
$fh = #fopen($myFile, 'w');
What's the significance of this #?
It suppresses errors an expression may display.
You can read more about it here.
Example:
file_get_contents('file_does_not_exist'); //this shows an error
#file_get_contents('file_does_not_exist'); //this does not
Its PHP's error control char.
PHP supports one error control operator: the at sign (#). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
More here.
Using # is always bad practice. It will suppress an error message if occurrs, while error messages are extremely useful for the programmer and suppressing it is suicide. PHP's fate is to be used mostly not by programmers but by casual users who have no clue. You've got this code from one of that latter kind. So, better to get rid of all #, so, you'll be able to see what happened and correct a mistake.
Note that every error message has it's particular meaning and explain what the problem is.
For example there can be filesystem permissions problem or PHP OPEN_BASEDIR setting to prevent file from open. So, an error message will tell you what to do. Error messages is good and # is evil.
What is the difference between these two function calls in PHP?
init_get($somevariable);
#init_get($somevariable);
the "#" will silence any php errors your function could raise.
It silences errors and warnings. See Error Control Operators.
As already answered the # will stop the error (if any) from showing up.
In terms of performance this is not recommended.
What php is doing is:
reading the error display state
setting the error display to show no errors
running your function
setting the error display to it's previous state
If you don't want any errors showing up use error_reporting(0);.
Or just write bug free code :P
http://www.faqts.com/knowledge_base/view.phtml/aid/18068/fid/38
All PHP expressions can be called with the "#" prefix, which turns off
error reporting for that particular expression.
As everyone said, it stops the output of errors for that particular function. However, this decreases performance greatly since it has to change the error display setting twice. I would recommend NOT ignoring warnings or errors and fixing the code instead.