I have written a supersimple code to track my blog's activity.
I'm including this file on every page at the very begining:
<?php
session_start();
if ($_SESSION["i"] == "") {
$_SESSION["i"] = rand(0,9) . chr(rand(65,90)) . chr(rand(65,90)) . chr(rand(65,90));
}
$r = $_SERVER['HTTP_REFERER'];
if ($r == "") {$r = "Direct";}
$u = $_SERVER['REQUEST_URI'];
include ($_SERVER['DOCUMENT_ROOT'].'/db.php');
$stmt = $conn->prepare("INSERT INTO analytika (id, page, referrer, visit, time) VALUES (DEFAULT, ?, ?, ?, DEFAULT)");
$stmt->bind_param("sss",$u,$r,$_SESSION["i"]);
$stmt->execute();
$stmt->close();
$conn->close();
?>
Problem is, what do I do to prevent echo's from PHP when error occures?
I've found error_reporting(0); but that obviously isn't the solution, because my page wont load further the error. And since im including things into DB, problems may really occur.
So, how do I rewrite my code to skip itself if something goes wrong and the page loads on as it would normally? Thanks
PHP 7.0
You would typically use a try/catch block to handle errors that you think may occur e.g. "what do you want to happen if your database is unavailable?"
https://www.w3schools.com/php/php_exception.asp
In PHP you can suppress error messages using the # operator. Again though it's recommended that you handle errors. This wouldn't prevent an error in your script from stopping execution.
http://php.net/manual/en/language.operators.errorcontrol.php
When you're using PHP in production, it's highly recommended not to show exceptions and errors, and even notices and warnings. To prevent showing these bad characters, you have to change display_errors option in php.ini file (see the link for more details).
However, there's another option. For instance, if you could not change ini file, you can use ini_set() function on every page you want to disable error reporting. But there is a problem with ini_set(); from php.net:
Note: Although display_errors may be set at runtime (with ini_set()), it won't have any effect if the script has fatal errors. This is because the desired runtime action does not get executed.
Also, to track errors, you can set log_errors and error_log options, by changing php.ini or using ini_set() function.
Related
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).
I am trying to enumerate through a perfectly valid array using php 5.3.5 on Joomla 1.5. Whenever I try to access the array I get the white screen of death. If I add a die() statement right after then I get the array, (but of course, execution after that is halted). I purposely put no code after array call and die() for debugging purposes. Removing die doesn't echo the array. Has anyone else had this issue before?
Edit: yes, turned error checking on. WSOD is BLANK.
**in the View class:**
$seminarsRefDB =& JFactory::getDBO();
$seminarsRefQuery = [MYSQL STUFF]
$seminarsRefDB->setQuery($seminarsRefQuery);
$seminarsRefList = $seminarsRefDB->loadAssocList();
for($i=0; $i<count($seminarsRefList); $i++) {
$classAppendix = $i;
$seminarselects[] = JHTML::_('select.genericList', $seminar_options, 'seminar_title[]', 'class="seminardropdown" style="width:200px;"', 'value', 'text', $seminarsRefList[$i]['value'], 'seminar'.$classAppendix);
};
$this->assignRef('seminarsArray', $seminarselects);
**In the Default Template**
print_r($this->seminarsArray[0]);
die;
END
I have another array called speakersArray which is echoed perfectly. I copied this code verbatim from the backend of my site where both arrays show no problems.
Used get_included_files and the default template is the last file included, so execution stops there.
You should turn on display_errors and error_reporting to E_ALL so you don't get a white screen of death and have your server tell you what errors it is getting.
It sounds to me that if its a big array and your passing it around, you could be running out of memory at some point in the code. By placing a die right after the array, you may have not hit that threshold yet.
Though iLLin's approach is fine for development testing, this is bad practice for a live site. Assuming you have access to your server, view the error log file to find out what is going on here.
tail -f error_log
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.
I am well aware about error_reporting(0); & ini_set('display_errors', "Off"); to make error messages go away.
What would be an appropriate way to do this - for a specific file or part of code only?
Surpressing errors with #'s seems like a bad idea since it apparently slows the code down...
The reason? We have a number of memcached servers in a development LAN that is really unreliable due to the network settings, thereby we are recieving errors multiple times every hour and there's nothing we can do about it except stop using memcache or turning off errors for the whole application, which would be giving us a headache - in the middle of the development stage :)
<?php
// normal code
// error_reporting returns the old error code
$old_error_reporting = error_reporting(0);
// your errorful code
// reset error_reporting to its old value
error_reporting($old_error_reporting);
// normal code
Although it would be a good idea to fix what is actually causing the errors.
You've kind of answered your own question. To do it for a specific file, error_reporting(0); will turn off errors. You can also call it multiple times in a script, I think.
You can also use php exceptions to 'catch' errors over a block of code. For example:
try {
// code to ignore errors for here
} catch {
// you can output a custom error here, but putting nothing here will effectively mean errors are ignored for the try block
}
The script will continue running past the try block, even if there is an error within it. See the PHP Manual Entry for more information.
You can change the error reporting level during runtime:
<?
error_reporting(E_ALL);
... some code ....
error_reporting(0);
... some more code ....
error_reporting(E_ALL);
I know of no other way but I can't think of a case where this wouldn't be sufficient. Can you?
That's really a long time ago but someone like me would maybe use my answer.
When i need to do this kind of stuff, i just put # before the variable in order to NOT display the errors coming from this variable.
example:
switch(#$var!="e") {
....
}
// Get the image information and display the image:
if ($image = #getimagesize ("../uploads/$pid")) {
echo "<div align=\"center\"><img src=\"show_image.php?image=$pid&name=" . urlencode($row['image_name']) . "\" $image[3] alt=\"{$row['print_name']}\" /></div>\n";
} else {
echo "<div align=\"center\">No image available.</div>\n";
}
What does # do in #getimagesize?
It is an Error Control Operator, that will mask (prevent from being displayed) any error the getimagesize function could generate.
It it generally not considered a good practice to use it : it makes your code really harder to debug (if there is an error, you won't know about it) :
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.
There is even a PHP extension, called scream, that disables this operator -- can be pretty useful when you are maintaintaing an apllication that used this operator a lot...
Generally, it is better to set error_reporting (see also) level and display_errors so that errors are displayed in development, and not in production -- that's way more useful that just always hiding them !
It stops errors from being displayed and/or being logged from that specific function call.
It suppress errors to appear. If the command you are invoking has an error or a warning to state, you will not get any printout in the page. You can also see it used with mysql_* routines.