is there a way to not stop script if errors found? - php

i have a php script which sometimes makes some light errors that are not important, but the script stops executing next lines. i want some ini_set or something to make it executes all the script even if there is warning or errors.
note: i can't fix those errors.
Thanks

If there are fatal errors, the script will stop no matter what and you can do nothing about it. You see there is nothing like "Resume on error" thing like that is in vb. You can suppress the errors though with # character.

You could try wrapping the "unimportant" code in a try/catch block: http://php.net/manual/en/language.exceptions.php
You probably want to understand why the errors are happening first, though. I'm concerned about the fact that you say the errors aren't important and that you can't fix them.

Related

fatal vs. not fatal error in php?

I'm wondering what errors are considered fatal vs. not in PHP (though interested in other languages too). Is there a concise explanation and/or listing of each somewhere of error types? Does using the expression "non-fatal" even make sense?
The reason I'm wondering is because sometimes when I make PHP errors my $_SESSION (actually using codeigniter sessions) is destroyed whereas in other cases it is not and I can't quite put my finger on why this is happening.
Well, the naming is pretty self-explanatory:
Fatal errors are critical errors and it means that the parser cannot possibly continue to parse the rest of your code, because of this error. For example:
Your webserver has run out of memory to parse the script (e.g. parser hit the memory_limit set in php.ini).
The script contains an infinite loop (e.g. while(1) { echo "Hi friend!"; } and runs longer than the set max_execution_time in your php.ini).
Non-fatal errors are usually called Warnings, they are still pretty serious and should be fixed, but do not cause the parser to stop parsing your code, it can still continue, regardless of the error that occurred. For example:
You are calling unset variables.
You are requesting a key in an array that does not exist.
You are calling an non-existing function.
Hope this clears things up a bit for you.

PHP alternatives to handling malformed input instead of throwing errors

There are many functions (well most really) in the PHP language that get all upset and throw warnings and notices when they don't like something about their input - rather than just returning FALSE (though they do that too).
One place this is really common is in the GD and string functions. They are very particular about their arguments and it's really easy for user input to fail meeting their standards.
For example, a user uploads a image that is corrupt (intentionally or unintentionally). Resulting in warnings from the GD library.
So far there are only three ways I have found to silence PHP on this issue:
Change your error reporting setting in the ini or at runtime (yuck).
Suppress errors with the slow # symbol.
Change error reporting right before/after the function:
like so:
$errorlevel=error_reporting();
error_reporting($errorlevel & ~E_NOTICE);
//...code that generates notices
error_reporting($errorlevel);
Naturally, the second two choices just make me sick. Which leaves me using 1) and toning down the PHP error settings. However, I want PHP to be in strict mode so that while I'm working I can catch logic bugs and bad form that might creep into my code. However, I don't want to have random errors thrown when PHP doesn't like something.
So is there any way to separate errors that are from malformed arguments (bad input) from errors that are from bad programming? For example:
If a user image is invalid just return FALSE and I'll deal with it. I don't need warnings.
If my passing of an image resource to print function is invalid throw warnings.
There's another alternative - use set_error_handler(), you can even call it just before the GD function call and return to the default with restore_error_handler().
There's a good comment in the question try and catch a warning that gives more detail on how this is accomplished.
This is an ill-design from the beginnings of PHP. A modern PHP library would throw an exception on error. And an exception may be caught. But back then GD was written PHP didn't yet support exceptions.
Thus I think that in this case it is legitimate to use the # operator.
Fix the code
Sanitize the input before you call the functions. This saves you errors.
There is no generic approach for all libraries besides editing the offending library and changing how it throws exceptions. Honeslty, a lot of PHP devs really didn't care about exceptions being thrown, but now more and more people are getting on the E_STRICT wagon. When the GD libs were generated the mentality probably was that throwing uncatchable errors wasn't that big a deal.
As far as the validating images with GD. The only thing you can really do is to use a different library or function to validate your images. You might try using magic byte functions to check if the images have proper headers(though this doesn't mean the rest of the file is structured correctly). At least using the magic byte functions will take care of obvious things like someone uploading a text file instead of a JPEG.
If there is something like that, you can use the #-operator
Its not a clean solution, but there are situations, where it's indispensable.
Did you check the image before using getimagesize() ?
However, I don't want to have random
errors thrown when PHP doesn't like
something.
Why not? PHP is trying to tell you something notable with warnings and notices. In the GD example you'll want to log when a user is uploading a corrupt file - especially if it's being used in an attack. Turn of the display of error messages and log everything.

Any way to make PHP abort on unset/undefined variables and array indexes and such?

Currently, PHP would trigger (and log if logging is enabled) E_NOTICE 'errors' when accessing undefined variables and array indexes. Is there a way to make it abort on these, so that I know I don't miss any. Frankly, IMO, far too often a script SHOULD abort on such condition anyway, as it will inevitably break something farther down the execution path. In all other cases there is the '#' operator, that's what it is for, right?
I know I can use a custom error handler and abort on any condition. In fact I do use one already, but I do have places where I trigger notices myself (granted, E_USER_NOTICE instead of PHP's own E_NOTICE), and I also always return false letting PHP's own internal handler do its job - logging and aborting on errors, continuing on everything else.
Then there are other cases where PHP produces E_NOTICE without me wanting to abort the script. Basically, there is no way for me to know if a particular E_NOTICE is a result of an unset variable or a totally harmless condition (which notices should be caused by anyway).
Has anyone a neat and non-hackish solution? Some recommended way of doing this?
Cheers.
I'm sure there is no native PHP way to do this.
Extending your already existent error handler to look into the error message (stristr($errmsg, "undefined variable") ...) and die() if necessary is the best (and only) way that comes to mind.
You can user PHP function set_error_handler() to register a custom function that will handles any PHP error. Specify E_NOTICE as the second parameter so that your custom function will only receive E_NOTICE error. Then in that function, simply do 'exit;' if the second parameter which is the error message starts with 'Undefined offset:'.
Rather than try to hack around PHP's error handling, I suggest you enforce some constraints on your script and check your variables with PHP's isset, empty and is_null functions.
I'm not sure what you want. You want to abort on notices, but not every notice? You want to distinguish between the several types of E_NOTICES and abort on some? The only way to do this is to check the message in the error handler and not abort if the message is about undefined variables – which you shouldn't use, by the way.

# character before a function call

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.

PHP escaping error reporting with #

I am currently refactoring some code for work and I have come across some function calls prefixed by the "#" symbol. As I understand it, this is intended to escape PHP error reporting if the call fails.
Is this type of thing good practice? I understand the rationale in a development environment but when the site is pushed to production shouldn't all errors be handled properly rather than just escaped?
The use of this symbol would therefore mean that the developer has to sort through the code at a later stage to remove all error reporting escapes.
I am unsure whether to remove these symbols and just find a better way to handle potential errors or not.
For clarity, the function this was used on was the native PHP fsockopen() function.
That's probably among the worst practices you can come across in php code. It basically tells the interpreter to suppress errors and just try to do whatever the code asks it to do regardless of the outcome.
A great way to drag yourself and fellow teammates into all-nighter phantom bug hunts once the app has grown substantially.
Try-catch with custom exception handling is the way to go.
I think it is sometimes understandable to use # for calling functions like fsockopen(), because when they fail they will raise a warning as well as returning false.
There may be cases where you expect these calls to fail regularly and therefore do not want a warning to be raised. Obviously you shouldn't be displaying warnings in production and should be logging them instead, but you might still want to use the # operator to stop your logs getting full. You could stop warnings getting reported at all by changing the error_reporting setting but that is not ideal.
That's called the error control operator, and is generally a very scary thing to consider using. A warning from the manual (the emboldening is mine):
Currently the "#" error-control
operator prefix will even disable
error reporting for critical errors
that will terminate script execution.
Among other things, this means that if
you use "#" to suppress errors from a
certain function and either it isn't
available or has been mistyped, the
script will die right there with no
indication as to why.
Using the "#" operator is very useful when you know that the function call can fail, like, for example, the fsockopen call. Best practice is to use this only when the function you are calling often fails and is a valid case in your application. Also, you should definitely check the return value of the function after calling it:
$fp = #fsockopen($hostname, $port);
if ($fp === false) {
// handle connection failure
}
else {
// handle connection success
}
You should avoid two things:
Not checking the return value;
Using the "#" operator where you don't expect an error -- for example when opening a local file or sending headers. When opening a local file fails, that is an error and it should be handled properly.
Note: you might also want to look at set_error_handler()
if you use your custom error-handlers, the # operator will not help you,
you will always get error-events from situations where your are handling the "Warning" in your code ... like at fsockopen etc.
so you can simple suppress effectively the warning this way:
function renameWithOutExpectedAndSelfHandledErrors( ... ) {
set_error_handler(function(){}); // deactivate all errors
$result = rename('not existing','blafussel');
restore_error_handler(); // restore old error-situation
return $result;
}

Categories