In my PHP aplication,I want that whenever -Internal Server or 500 error occurs,I want the error code to be changed from 500 to 302.I mean error code 302.
Try to use http_response_code.Also, take a look on related question How to return an HTTP 500 code on any error, no matter what.
i would not recommend you do that.
Instead wrap your code that is generating this error within a Try & Catch statement and try to handle exception there.
try {
// your code here
} catch (Exception $e) {
echo $e->getMessage();
}
Related
Now that we can catch fatal errors in PHP7 (set_error_handler cannot), would it be a good idea to use it to catch errors on a whole project? Mine is always going through index.php, so I was planning to do this:
try {
//All the code and includes, etc.
} catch(Error $ignored) {
//save the error in log and/or send a notification to admin.
}
I tried first to be sure:
set_error_handler(function(int $number, string $message) {
echo "Error $number: '$message'" . PHP_EOL ;
});
$var = $undeclared_var //The error is sent to the error_handler.
function_dont_exist(); //The error isn't sent to the error_handler.
try {
function_dont_exist();
}
catch(Error $E){
echo "Error"; //That works.
}
Is it a good idea / good practice to envelope the whole code with a try/catch/error to deal with them? It sounds good, but I wonder why I don't see it much. I tried and I believe it works, but it sounds too easy.
Thank you for your help!
I'm using CodeIgniter and am trying to execute code in a try/catch block with the idea that errors will stop execution of the code after the error until the catch block is reached, as you would normally think it would work.
However on encountering PHP Errors, the code is continuing. This is causing a database transaction complete command to execute which is .... very bad if there's an error and all of the instructions weren't carried out properly. For example, I have this code which is executed in an ajax request:
// start transaction
$this->db->trans_start();
try {
$this->M_debug->fblog("firstName=" . $triggerOpts->{'firstXXXName'});
$data = array("test_col" => 123);
$this->db->where("id", 4);
$this->db->update("my_table", $data);
// if got this far, process is ok
$status = "process_ok";
// complete transaction
$this->db->trans_complete();
} catch (Exception $ex) {
// output the error
$this->M_debug->logError($ex);
}
In this code, I'm trying to execute a database update as part of a transaction.
My call to $this->M_debug->fblog() is designed to just log a variable to PHP Console, and I've deliberately tried to log a variable that does not exist.
This causes a PHP error, which I guess is a fatal error, and the desired result is that the code after the log commands fails, and the transaction does not complete. However after this error, despite reporting the PHP error in Chrome console, the code keeps right on executing, the database is updated and the transaction is completed. Would appreciate any help in how i could stop this from happening.
Thanks very much, G
EDIT --
As requested heres fblog(), it's simply a Chrome console log request of a variable
public function fblog( $var ) {
ChromePhp::log( $var );
}
Assuming you're using PHP 7.0 or higher, you can catch PHP errors as well as exceptions, however you need to catch Error or the parent Throwable type rather than Exception.
try {
...
} catch (Throwable $ex) {
//this will catch anything, including Errors and Exceptions
}
or catch them separately if you want to do something different for each of them...
try {
...
} catch (Exception $ex) {
//this will catch Exceptions but not errors.
} catch (Error $ex) {
//this will Errors only
}
Note that if you're still only PHP 5.x, the above won't work; you can't catch PHP errors in older PHP versions.
I've read this thread: php: catch exception and continue execution, is it possible?
Every answer suggests that a try catch will continue executing the script. Here is an example where it doesn't:
try{ $load = #sys_getloadavg(); }
catch (Exception $e){ echo 'Couldn\'t find load average.<br>'; return false; }
I'm running it on xampp on windows, which could be why it errors (it gives a Call to undefined function sys_getloadavg() error when the # is removed), but that isn't the issue in question. It could be any function that doesn't exist, isn't supported or fails - I can not get the script to continue executing.
Another example is if there is a syntax error in the try, say I'm including an external file and parsing it as an array. This also produces an error and stops executing.
Is there any brute force way to continue the script running, regardless of what fails in the try?
Unlike other languages, there's a difference in PHP between exceptions and errors. This would be like a compile error in other languages. that require declaration files. You can't catch or ignore Fatal errors like a function not exisiting. You can test for existence before using though:
if( function_exists('sys_getloadavg') {
try{ $load = #sys_getloadavg(); }
catch (Exception $e){ echo 'Couldn\'t find load average.<br>'; return false; }
}
Let's say I do a odbc_connect call, deliberately using erroneous information, as follows:
<?PHP odbc_connect('bogus','bogus','bogus'); ?>
Now, the manual states that odbc_connect "[r]eturns an ODBC connection id or 0 (FALSE) on error". I'm okay with the 0 being returned, but when I'm running the file (using Wampserver), I also receive error messages telling me that something went wrong.
I would like to suppress this error message, since I'm trying to build a PHP file that only echoes a certain piece of text, like "unsuccessful", when the information for the database call was wrong.
Use a try-catch:
<?php
try {
odbc_connect('bogus', 'bogus', 'bogus');
} catch (Exception $e) {
// handle your exception
}
You can also use # to suppress error messages on a single line - but it isn't good practice.
<?PHP #odbc_connect('bogus','bogus','bogus'); ?>
Error messages are there for a reason, don't ignore them. Use something like #Matt suggests and trap them as needed - not just hush them up.
You can use the error-suppression operator #.
<?php
$conn = #odbc_connect('bogus','bogus','bogus');
?>
PHP fatal errors come back as status code 200 to the HTTP client. How can I make it return a status code 500 (Internal server error)?
header("HTTP/1.1 500 Internal Server Error");
This is exactly the problem I had yesterday and I found solution as follows:
1) first of all, you need to catch PHP fatal errors, which is error type E_ERROR. when this error occurs, script will be stored the error and terminate execution. you can get the stored error by calling function error_get_last().
2) before script terminated, a callback function register_shutdown_function() will always be called. so you need to register a error handler by this function to do what you want, in this case, return header 500 and a customized internal error page (optional).
function my_error_handler()
{
$last_error = error_get_last();
if ($last_error && $last_error['type']==E_ERROR)
{
header("HTTP/1.1 500 Internal Server Error");
echo '...';//html for 500 page
}
}
register_shutdown_function('my_error_handler');
Note: if you want to catch custom error type, which start with E_USER*, you can use function set_error_handler() to register error handler and trigger error by function trigger_error, however, this error handler can not handle E_ERROR error type. see explanation on php.net about error handler
Standard PHP configuration does return 500 when error occurs! Just make sure that your display_errors = off. You can simulate it with:
ini_set('display_errors', 0);
noFunction();
On production display_errors directive is off by default.
I have used "set_exception_handler" to handle uncaught exceptions.
function handleException($ex) {
error_log("Uncaught exception class=" . get_class($ex) . " message=" . $ex->getMessage() . " line=" . $ex->getLine());
ob_end_clean(); # try to purge content sent so far
header('HTTP/1.1 500 Internal Server Error');
echo 'Internal error';
}
set_exception_handler('handleException');
Since PHP >= 5.4
http_response_code(500);
echo json_encode( [ 'success' => false , 'message' => 'Crazy thing just happened!' ]);
exit();
Please set the httpCode before echo.
It is not possible to handle PHP E_ERROR in any way according to the PHP documentation:
http://www.php.net/manual/en/function.set-error-handler.php
Nor is is possible to handle "E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT" according to that link.
You CAN provide a handler for the other error, warning, and notices including E_USER_ERROR, but that's really not as useful as it sounds since this error only gets thrown intentionally by the programmer with trigger_error().
And of course you can catch any Exception (even the ones thrown by the native PHP functions).
I agree that this is a problem. Servers should NOT return 200 OK when application code crashes and burns.
You can use php error handling
http://www.w3schools.com/php/php_error.asp
You would have to catch the thrown error using try/catch and then use that catch block to send a header() with the 500 error.
try {
...badcode...
throw new Exception('error');
} catch (Exception $e) {
header("Status: 500 Server Error");
var_dump($e->getMessage());
}
If the fatal exception is not surrounded by try {} catch blocks then you must register a global handler and use register_shutdown_function() to check for an error at script end.
Never forget to set header("HTTP/1.1 200 OK", true, 200); as the last line of any execution path:
//first things first:
header("HTTP/1.1 500 Internal Server Error", true, 500);
//Application code, includes, requires, etc. [...]
//somewhere something happens
//die();
throw new Exception("Uncaught exception!");
//last things last, only reached if code execution was not stopped by uncaught exception or some fatal error
header("HTTP/1.1 200 OK", true, 200);
In PHP 5.4 you can replace the header function above with the much better http_response_code(200) or http_response_code(500).
The hard thing when dealing with fatal errors (compile errors, for example a missing semicolon) is that the script won't be executed, so it won't help to set the status code in that script. However, when you include or require a script, the calling script will be executed, regardless of errors in the included script. With this, I come to this solution:
rock-solid-script.php:
// minimize changes to this script to keep it rock-solid
http_response_code(500); // PHP >= 5.4
require_once("script-i-want-to-guard-for-errors.php");
script-i-want-to-guard-for-errors.php:
// do all the processsing
// don't produce any output
// you might want to use output buffering
http_response_code(200); // PHP >= 5.4
// here you can produce the output
Direct your call to the rock-solid-script.php and you're ready to go.
I would have liked it better to set the default status code to 500 in .htaccess. That seems more elegant to me but I can't find a way to pull it off. I tried the RewriteRule R-flag, but this prevents execution of php altogether, so that's no use.