According the PHP Manual:
Internal PHP functions mainly use Error reporting, only modern Object oriented extensions use exceptions. However, errors can be simply translated to exceptions with ErrorException
The example provided in ErrorException:
<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
It seems to allow using Exceptions instead of the default error reporting. My question is, is this an encouragement or merely an option for us?
Moreover, which is a better practice, use Exception alone like the above example, or use both Exception (set_exception_handler) and Error reporting (set_error_handler) alongside with each other?
Short answer: No. That are two different functions.
Long answer: It's not meant to replace but to make use of. set_exception_handlerDocs is used for exceptions and set_error_handlerDocs for errors. That are two different pair of shoes.
See as well:
PHP: exceptions vs errors?
PHP: What is the flow of control for error handling?
Error Handling and LoggingDocs
No, Any exception that is not caught results in a fatal error. If you want to respond gracefully to exceptions that are not caught in catch blocks, then you’ll need to set a function as the default exception handler.
To do so, you use the set_exception_handler() function, which accepts a callable as its parameter. Your script will terminate after the callable has executed.
The function restore_exception_handler() will revert the exception handler to its previous value.
Related
I am trying to use the set_error_handler function to capture require errors.
while my custom error_handler is being used, the context seems completely off, although the trace is correct.
<?php
function error_handler($errno, $errstr, $errfile, $errline){
throw new Exception($errstr);
}
set_error_handler('error_handler');
try{
trigger_error("somethign",E_USER_NOTICE);
}catch(Exception $e){
echo "I got caught";
}
try{
require "something/that/does/not/exists.php";
}catch(Exception $e){
echo "I got caught";
}
As can be seen, when I trigger the first error, it triggers the error_handler which in turn is throwing an exception. Which is caught in the first try-catch.
The second time, where I try to include an un-existing file, again the error_handler is used, but the exception is not caught.
What is going on here?
I am using php 5.5.*
Tested in CLI mode.
Just read the documentation:
require is identical to include except upon failure it will also
produce a fatal E_COMPILE_ERROR level error. In other words, it will
halt the script
(http://php.net/manual/en/function.require.php)
That means, the script execution is aborted when this error is encountered. Your custom error handler will be used but throw will be ignore because that assumes further execution which is not allowed at this point.
It's important to remember that there's two general types of errors with PHP
Processing errors are caught when your program runs
Compile errors occur when you have bad syntax or when you try to do something impossible
In your case, require is a compile error. It will not execute your user defined function because it will never get that far. The compiler can't include the bad file and will fail out.
I can't manage the following: I have an error handler which catches all E_WARNINGS but I only want to handle some of the warnings all the other I want to ignore and pass them to the default PHP error handler (which also takes all the other error types except the E_WARNINGS).
Is this even possible? Look at my simple error handler:
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {
if($errfile != 'somefile_for_example.php') {
// I don't care about this error throw it somewhere else!
}
echo 'error in this file handles my custom error handler';
return true;
}, E_WARNING);
PHP documentation says at: http://php.net/manual/en/function.set-error-handler.php
It is important to remember that the standard PHP error handler is
completely bypassed for the error types specified by error_types
unless the callback function returns FALSE.
Maybe then this should work:
$old_error_handler = set_error_handler(
function($errno, $errstr, $errfile, $errline, $errcontext) {
if($errfile != 'somefile_for_example.php') {
return false;
}
echo 'error in this file handles my custom error handler';
return true;
}, E_WARNING);
-
[Edit] Another user (Philipp) commented that set_error_handler returns old handler, but only for another custom one, not for the default handler.
-
In any case, when programming error handlers, one must always be extra careful with programming errors, as they cannot be handled (maybe test the functions by themselves first).
There isn't an easy solution to do this, if you really want the error handler of php.
If you call set_error_handler, you get the current error handler as return value, but only, if set_error_handler was called already. An possible solution to avoid this is to restore the error handler(restore_error_handler) trigger your own error(trigger_error) and set your own error handler again. Caveat from this is, you lost the information about error line, file and context. In addition, you can only trigger user errors, which means, you have to map each error type to an user error type.
I would suggest, to handle all errors in your custom handler - there's no real benefit in such workarounds.
I want to override the default PHP error handler.I'm sure this has been implemented countless times.
I've found the following projects, but most seem quite old and small projects.
I would primarily like to have:
Development mode, that simply displays all errors/notifications
Production mode, that allows displaying clean custom lay-out pages to the user
Logging to text file (i don't have admin access to the webserver, so can't set this up through the PHP settings)
Send warning e-mails on serious errors
Log to database
How can this be done in php?
You can use set_error_handler function to set your custom error handler and then do whatever you'd like with it.
The best practice, IMO, is to throw ErrorException when error occurs and handle it with try/catch (Note: with handling I don't mean muting errors). For example:
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");
try {
//Some code that may produce error
} catch (ErrorException $e) {
$someLogger->log($e->getMessage());
}
Instead of logger you may have your own custom class that will implement your requirements. So if any of already existing source meets your needs use one, otherwise create.
Note #1: If you want to do something on fatal errors (logging comes in my mind) you can use register_shutdown_function
Note #2: You said that classes/projects you've found are small. There are two things. First, you can't measure how good code is with LOC. Second, there;s not really much to do with errors.
Edit:
In general, it's not common and not even acceptable to re-implement everything from the ground when you develop new project. You should build your own libraries once and then use them in your projects. Personally, I use KLogger for logging stuff and I am happy with it.
Hello I have a code like that :
try
{
// Here I call my external function
do_some_work()
}
catch(Exception $e){}
The question is: If the do_some_work() has a problem and produce an Error this try catch will hide the error?
There are two types of error in PHP. There are exceptions, and there are errors.
try..catch will handle exceptions, but it will not handle errors.
In order to catch PHP errors, you need to use the set_error_handler() function.
One way to simplify things mught be to get set_error_handler() to throw an exception when you encounter an error. You'd need to tread carefully if you do this, as it has the potential to cause all kinds of trouble, but it would be a way to get try..catch to work with all PHP's errors.
If do_some_work() throws an exception, it will be catched and ignored.
The try/catch construct has no effect on standard PHP errors, only on exceptions.
produce a Fatal Error
No, catch can not catch Fatal Errors. You can not even with an error handler.
If you want to catch all other errors, have a look for ErrorException and it's dedicated use with set_error_handler:
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
/* Trigger exception */
strpos();
I'm a beginner in PHP. So far, from the source I'm learning from, the only mechanism to trigger an exception is by writing a line that throws it.
throw new Exception('message')
Furthermore, on the code below, any exception won't be thrown, but an error will be raised.
try
{
$file = fopen('no such file.txt', 'r');
}
catch(Exception $e)
{
echo 'Exception: ' . $e->getMessage();
}
Please give me some explanations.
It seems this try..catch block is not so useful in PHP, unlike in Java or .NET.
By convention, the functions in the PHP core do not throw exceptions (the only exception is that constructors may throw exceptions, because there's no other way for them to properly signal error conditions).
Some differences:
Exceptions have types, and you can catch them according to their type. Errors only have an associated level (E_WARNING, E_STRICT, E_NOTICE, ...).
Exceptions can be caught at any point in the call stack, otherwise they go to a default exception handler. Errors can only be handled in the defined error handler.
"errors" are remains from the pre-oop era of php and are indeed hardly useful in the modern code. Fortunately, you can (actually, must) automatically convert most "errors" to exceptions. The magic is like this
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
Once you've got this, your "fopen" snippet will work as expected. See http://php.net/manual/en/class.errorexception.php for more details/discussion.
It is not useful in this specific case, because fopen() doesn't throw an exception when it encounters an error. I think none of the core functions do.
If you are used to working with exceptions and want to work consistently with them, I think there is nothing speaking against using the ErrorException class to turn all errors into exceptions.
However, fopen() throws only a E_WARNING when it fails to open a file, so in your example, it would be easiest to test whether $file is false to see whether the operation failed.
I personally also like to do a file_exists() before fopen(), and react accordingly if the file is missing.