in this case I accidentally made a wrong database username or password, my goal here is how to generate an error in the form of JSON data and open in the form of a PHP warning or error like my picture
// Here's my PHP Code
if (!empty($_POST)){
$test_conn = new mysqli('localhost' , $_POST['db_user'] , $_POST['db_pass']);
$conn = new mysqli('localhost' , $_POST['db_user'] , $_POST['db_pass'] , $_POST['db_name']);
if ($test_conn->connect_error){
$response = array('status' => 0 , 'message' => "Failed Connect to Databases");
print_r(json_encode($response));
}else{
// The Code When Username and Password is Correct
}
}
here I know that the username or password is wrong, but I am confused how to only display the json data in the image at the bottom and not display the php warning
If you are sure that this is what you want, just disable errors by adding the following at the top of your script:
error_reporting(0);
if you want to hide errors for a given code, use the following:
// Disable errors and get current error reporting level
$err = error_reporting(0);
/* here goes you buggy code */
// Set the default error reporting level
error_reporting($err);
You have to suppress the php error reporting in order to use your own check of connect_error. The php documentation on mysqli::$connect_error suggests to do this with the # error control operator like this:
$test_conn = #new mysqli( ... )
This will only suppress errors caused by a faulty instantiation of the mysqli object. It should be clear that you then have to handle these errors yourself (as you already do). All other errors still could cause your php script to stop and not to return any JSON string to the AJAX function that called the script.
As #Victor correctly pointed out in his answer you could disable all errors for the script (or parts of it) by setting error_reporting(0) at the beginning at the script. In that case you wouldn't have to check other possible errors, e.g. if the db credentials in the $_POST array are not set or empty.
As #Ben mentioned in his comments you could also make mysqli throw exceptions to avoid fatal errors by setting mysqli_report(MYSQLI_REPORT_STRICT). This would also be a feasible solution for your problem.
As a general consideration you should make these settings in your php.ini:
display_errors = Off
error_log = syslog
This prevents error message from being exposed to the www (security) while making them available for developers in /var/log/syslog (maintainability).
Related
Problem:
Finding best practice for error handling using PDO. The options I have found on websites, SO, books, etc.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
Others are recommending logging it to a log file outside the document root.
Some use error handling to log it to a SQL table.
With a multitude of options, it gets quite easy to drown into what option you should be using. Of course you could use a MVC framework and let it handle error logging for you, but how would it look like if you are not using MVC.
As I have understood it error handling should like the following in development environment:
display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(-1);
ini_set("display_errors", 1);
And in production environment:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(0);
To take an example of a database connection in production environment.
Code:
<?php
// Error handling
error_reporting(0);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
try {
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// Catches errors raised by PDO
catch (PDOException $e) {
// Prints error messages to file
file_put_contents('/home/ubuntu/errors.log', 'Error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
// Shows generic error message to user
header('Location: 404.php');
exit;
}
?>
Question:
What is the best practice for handling errors in general in PHP?
What is the best practice for handling errors in the catch-block?
That's a very good question, but there is one wrong premise at the very beginning: you are taking error reporting for PDO separated from site-wide error reporting. Which makes very little sense: PDO errors in every way are the same as other errors - filesystem errors, HTTP errors, and so on. Thus, there is no reason in establishing PDO-only error reporting. All you need is to properly set site-wide error reporting.
There is also one wrong assumption regarding php.ini inaccessibility: you can always set any configuration directive using ini_set() function. Thus, here is not a single reason in setting error_reporting to disastrous level of 0.
To answer the rest of your questions all you need is a little common sense.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
What you think yourself? Does it any good showing system error messages to user? Does it any good showing system internals to a malicious user?
Others are recommending logging it to a log file outside the document root.
Do you have any objections for this?
Some use error handling to log it to a SQL table.
Don't you think it's quite contradicting idea - to log database errors into database?
What is the best practice for handling errors in general in PHP?
You have shown it already: display in dev and log in prod. All is controlled site-wide through few simple configuration options.
What is the best practice for handling errors in the catch-block?
NOT to use try-catch block for error reporting at all. You aren't going to write a catch block with a friendly error message for the every query in your app, as it's suggested in the other answer, are you?
Thus your code have to be
<?php
// Error handling
error_reporting(-1);
ini_set('display_errors',0);
ini_set('log_errors',1);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Now to the question you voiced in the comment.
A custom error screen is a very different matter and your code is especially bad with it. Neither it should be a 404 error nor an HTTP redirect have to be used (thats very bad for SEO).
To create a custom error page you have to use either your web-server features (preferred) or an error handler in PHP script.
When encountering a fatal error (and uncaught exception is one), PHP responds not with 200 OK HTTP status but with 5xx status. And every web-server can catch this status and show an according error page. E.g. for Apache it would be
ErrorDocument 503 server_error.html
where you can write whatever excuses you want.
Or you can set up a custom error handler in PHP which would handle all PHP errors as well, an example can be seen in the article I wrote on the matter: The (im)proper use of try..catch.
Problem:
Finding best practice for error handling using PDO. The options I have found on websites, SO, books, etc.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
Others are recommending logging it to a log file outside the document root.
Some use error handling to log it to a SQL table.
With a multitude of options, it gets quite easy to drown into what option you should be using. Of course you could use a MVC framework and let it handle error logging for you, but how would it look like if you are not using MVC.
As I have understood it error handling should like the following in development environment:
display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(-1);
ini_set("display_errors", 1);
And in production environment:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(0);
To take an example of a database connection in production environment.
Code:
<?php
// Error handling
error_reporting(0);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
try {
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// Catches errors raised by PDO
catch (PDOException $e) {
// Prints error messages to file
file_put_contents('/home/ubuntu/errors.log', 'Error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
// Shows generic error message to user
header('Location: 404.php');
exit;
}
?>
Question:
What is the best practice for handling errors in general in PHP?
What is the best practice for handling errors in the catch-block?
That's a very good question, but there is one wrong premise at the very beginning: you are taking error reporting for PDO separated from site-wide error reporting. Which makes very little sense: PDO errors in every way are the same as other errors - filesystem errors, HTTP errors, and so on. Thus, there is no reason in establishing PDO-only error reporting. All you need is to properly set site-wide error reporting.
There is also one wrong assumption regarding php.ini inaccessibility: you can always set any configuration directive using ini_set() function. Thus, here is not a single reason in setting error_reporting to disastrous level of 0.
To answer the rest of your questions all you need is a little common sense.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
What you think yourself? Does it any good showing system error messages to user? Does it any good showing system internals to a malicious user?
Others are recommending logging it to a log file outside the document root.
Do you have any objections for this?
Some use error handling to log it to a SQL table.
Don't you think it's quite contradicting idea - to log database errors into database?
What is the best practice for handling errors in general in PHP?
You have shown it already: display in dev and log in prod. All is controlled site-wide through few simple configuration options.
What is the best practice for handling errors in the catch-block?
NOT to use try-catch block for error reporting at all. You aren't going to write a catch block with a friendly error message for the every query in your app, as it's suggested in the other answer, are you?
Thus your code have to be
<?php
// Error handling
error_reporting(-1);
ini_set('display_errors',0);
ini_set('log_errors',1);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Now to the question you voiced in the comment.
A custom error screen is a very different matter and your code is especially bad with it. Neither it should be a 404 error nor an HTTP redirect have to be used (thats very bad for SEO).
To create a custom error page you have to use either your web-server features (preferred) or an error handler in PHP script.
When encountering a fatal error (and uncaught exception is one), PHP responds not with 200 OK HTTP status but with 5xx status. And every web-server can catch this status and show an according error page. E.g. for Apache it would be
ErrorDocument 503 server_error.html
where you can write whatever excuses you want.
Or you can set up a custom error handler in PHP which would handle all PHP errors as well, an example can be seen in the article I wrote on the matter: The (im)proper use of try..catch.
Problem:
Finding best practice for error handling using PDO. The options I have found on websites, SO, books, etc.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
Others are recommending logging it to a log file outside the document root.
Some use error handling to log it to a SQL table.
With a multitude of options, it gets quite easy to drown into what option you should be using. Of course you could use a MVC framework and let it handle error logging for you, but how would it look like if you are not using MVC.
As I have understood it error handling should like the following in development environment:
display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(-1);
ini_set("display_errors", 1);
And in production environment:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
Or if no access is available to the php.ini file:
error_reporting(0);
To take an example of a database connection in production environment.
Code:
<?php
// Error handling
error_reporting(0);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
try {
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// Catches errors raised by PDO
catch (PDOException $e) {
// Prints error messages to file
file_put_contents('/home/ubuntu/errors.log', 'Error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
// Shows generic error message to user
header('Location: 404.php');
exit;
}
?>
Question:
What is the best practice for handling errors in general in PHP?
What is the best practice for handling errors in the catch-block?
That's a very good question, but there is one wrong premise at the very beginning: you are taking error reporting for PDO separated from site-wide error reporting. Which makes very little sense: PDO errors in every way are the same as other errors - filesystem errors, HTTP errors, and so on. Thus, there is no reason in establishing PDO-only error reporting. All you need is to properly set site-wide error reporting.
There is also one wrong assumption regarding php.ini inaccessibility: you can always set any configuration directive using ini_set() function. Thus, here is not a single reason in setting error_reporting to disastrous level of 0.
To answer the rest of your questions all you need is a little common sense.
A great number of websites say you should echo your error messages in your catch block.
A large number of users on SO say that you should never echo error messages due to security risks.
What you think yourself? Does it any good showing system error messages to user? Does it any good showing system internals to a malicious user?
Others are recommending logging it to a log file outside the document root.
Do you have any objections for this?
Some use error handling to log it to a SQL table.
Don't you think it's quite contradicting idea - to log database errors into database?
What is the best practice for handling errors in general in PHP?
You have shown it already: display in dev and log in prod. All is controlled site-wide through few simple configuration options.
What is the best practice for handling errors in the catch-block?
NOT to use try-catch block for error reporting at all. You aren't going to write a catch block with a friendly error message for the every query in your app, as it's suggested in the other answer, are you?
Thus your code have to be
<?php
// Error handling
error_reporting(-1);
ini_set('display_errors',0);
ini_set('log_errors',1);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Now to the question you voiced in the comment.
A custom error screen is a very different matter and your code is especially bad with it. Neither it should be a 404 error nor an HTTP redirect have to be used (thats very bad for SEO).
To create a custom error page you have to use either your web-server features (preferred) or an error handler in PHP script.
When encountering a fatal error (and uncaught exception is one), PHP responds not with 200 OK HTTP status but with 5xx status. And every web-server can catch this status and show an according error page. E.g. for Apache it would be
ErrorDocument 503 server_error.html
where you can write whatever excuses you want.
Or you can set up a custom error handler in PHP which would handle all PHP errors as well, an example can be seen in the article I wrote on the matter: The (im)proper use of try..catch.
I have some code that allows a user to input details for their database on their server. After they submit the details, the code checks a connection to the database to see if valid details were entered. I want it to give outcomes of variables being true if the connection either works or does, like this:
$mysqli = new mysqli($_POST['dbHost'],$_POST['dbUser'],$_POST['dbPassword'],$_POST['dbName']);
if ($mysqli->connect_errno) { $badDetails = true; }
else { goodDetails = true; }
Problem is, if the details are indeed incorrect, it shows a PHP warning from the first line of the code above giving 'Unknown MySQL server host'.
What is the way around this? I don't want PHP throwing it's own visible error for this, I want to deal with the error myself.
You should not worry about visual errors. In a production environment, these should be turned off in the ini, and all errors should go to a log on the server instead of just to the screen.
This is configured with the display_errors setting and error_reporting()
Many frameworks override the PHP error handler with a custom implementation to display error in a pretty way, depending on their severity.
To achieve this, you can override the PHP error handler
As seen in the manual one can register custom handlers for regular errors and exceptions. And it is also possible to trigger an user defined error.
Just use a die()
$mysqli = new mysqli($_POST['dbHost'],$_POST['dbUser'],$_POST['dbPassword'],$_POST['dbName']) or die("Database Connection Failed");
A quick, dirty method would be error supression:
$con = #mysqli_connect( /* info */ );
Note that you should not keep this there, as this will suppress all errors, and mysqli can have multiple errors that you might need to know about.
Though I would check the host variable first, to see why the error is caused. You can also use die.
$con = mysqli_connect(/* info */) or die ("SQL Error!");
As far as where to look, try seeing that the host var is actually set and check it's value:
if (!isset($_POST['dbHost'])) {
echo "Host var not set!";
} else {
echo "Host var set: " . $_POST['dbHost']
}
I'm already set its debugging option to true,but when there's error in smarty template(i.e. there is no corresponding plugin for a specific smarty_modifier),nothing is output for information.
UPDATE
For anyone that wants to have a try,this is the most simple template I can think of :
{$var|nosuch_modifier}
1- First, you can check if error_reporting is on. this is usually done in php.ini but you can place these statements on top of your php source.
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
and make sure it is not disabled elsewhere.
2- smarty may report errors as throwing an exception. You can define a global exception handler to catch them, here is an example;
try {
// place your code here
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Update upon comments:
The only reason I can think of is that you've set compile_check to false.
$tpl->compile_check = false;
In this case, Smarty will show the latest compiled source, whatever you do to the tpl file. So, did you check and set compile_check to true?
$tpl->compile_check = true;
Try
ini_set('display_errors', true);
error_reporting(E_ALL);
in the PHP code.
Smarty error reporting can be set manually.
$smarty->error_reporting = E_ALL ^ E_NOTICE;
Some comments from the Smarty.class.php
error muting is done because some people implemented custom
error_handlers using http://php.net/set_error_handler and for some
reason did not understand the following paragraph:
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. error_reporting() settings
will have no effect and your error handler will be called regardless -
however you are still able to read the current value of
error_reporting and act appropriately. Of particular note is that this
value will be 0 if the statement that caused the error was prepended
by the # error-control operator.
Smarty deliberately uses #filemtime() over file_exists() and
filemtime() in some places. Reasons include
- #filemtime() is almost twice as fast as using an additional file_exists()
- between file_exists() and filemtime() a possible race condition is opened, which does not exist using the simple #filemtime() approach.