Let's say I'm basically inheriting a live site that has a lot of errors in production, I'm basically doing a recode of this entire site which might take a month or so.
There are some cases in which this site was reliant upon external xml file feeds which are no longer there, but the code wasn't properly setup to supply a nice clean error message ( there are various similar circumstances ) - the client is requesting that at least these error messages go away even if for example the content from the xml file isn't published so we wouldn't be seeing php errors and a blank region on the page ( so the rest of the page can look "fine" ).
At one point I have heard of someone using set_error_handler to nullify some cases where it isn't extreme and I had the idea of setting it up to store error messages in a file/log or email them ( and try to not have duplicate error messages ) basically so end users don't have to see those ugly things.
I'm looking for tips from anyone who's actually done this, so thanks in advance.
On your production server, you should have the following ini settings:
ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('log_errors', true);
ini_set('error_log', '/tmp/php_errors.log'); // or whatever file is appropriate
ini_set('display_errors', false);
By turning off display_errors, your users will never see another error message, but you will be able to see error messages by looking in the log file.
When the re-code is finished, there should be no more errors going into the log file (because you've fixed them all).
Edit: Some developers set error_reporting to E_ALL ^ E_NOTICE as a way of hiding errors. This is bad practice because it hides messages about possible programming errors. You should only use E_ALL ^ E_NOTICE when there are so many Notices coming from legacy code that you are unable to fix them all.
When in development, it is good to use
error_reporting(E_ALL);
ini_set('display_errors', 'On');
So you can see errors immediatly : it helps correcting them.
When on the production server, you don't want error displayed, so :
ini_set('display_errors', 'Off');
error_reporting can remain activated : if display_errors is Off, errors won't be displayed anyway -- but you can still have them logged to a file.
BTW, those can be set in the php.ini file, of course :
error_reporting
display_errors
On the production machine, you might want to use log_errors and error_log, so errors are logged to a file (which means you will be able to know what errors occured -- can be useful, sometimes) ; of course, don't forget to check that file from time to time ;-).
As a sidenote, if you just have a couple functions/methods you don't want to display errors, you could envisage using the # operator to just mask the errors those might trigger...
... But I strongly advise against it (except in very specific cases) : it make debugging lots harder : errors triggered there are never displayed, not even on your development machine !
In my opinion, it is way better to just disable display_errors on the production machine ; it also means no error will be displayed at all, which is better for users!
Related
I can't turn off display errors for my website. I use ISP Manager control panel. It is Off in all php.ini files and settings. But still warnings and notices are showing. Even using ini_set() right in the script doesn't work. Can you help me with this?
<?php
ini_set('display_errors', 0);
phpinfo(); // display_errors is still On On
ini_get('display_errors'); // returns 'stderr'
If I understood correctly, something like:
var_dump(ini_set('display_errors', 0));
… produces:
bool(false)
I can think of two ways to intentionally prevent display_errors from being changed:
Disabling ini_set() altogether in system-wide INI file, which produces different symptoms:
Warning: ini_set() has been disabled for security reasons
NULL
This can be checked anyway:
var_dump(ini_get('disable_functions'));
Hard-coding display_errors in Apache settings using php_admin_flag, which only applies if PHP runs as Apache module but effectively produces a boolean false.
I believe we're in #2. You may want to check whether PHP runs as Apache module; I'm not aware though of any way to verify by yourself if php_admin_flag is being used. If that's the case, I reckon you're out of luck:
php_admin_flag name on|off
Used to set a boolean configuration directive. This can not be used in
.htaccess files. Any directive type set with php_admin_flag can
not be overridden by .htaccess or ini_set().
If you're in control of Apache settings this is something you can easily fix. Otherwise, I suggest you ask hosting support about this. IMHO, it isn't reasonable to enable display_errors in a production server, let alone force it:
; This directive controls whether or not and where PHP will output errors,
; notices and warnings too. Error output is very useful during development, but
; it could be very dangerous in production environments. Depending on the code
; which is triggering the error, sensitive information could potentially leak
; out of your application such as database usernames and passwords or worse.
; For production environments, we recommend logging errors rather than
; sending them to STDOUT.
; Possible Values:
; Off = Do not display any errors
; stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
; On or stdout = Display errors to STDOUT
; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
Overview
There are a few different types of error reporting function in PHP. Luckily we have a decent explanation of these in the PHP docs here.
I typically use the three in the examples below. Let's walk through those.
Breakdown Docs
This function sets the error reporting level.
error_reporting()
The error_reporting() function sets the error_reporting directive at
runtime. PHP has many levels of errors, using this function sets that
level for the duration (runtime) of your script. If the optional level
is not set, error_reporting() will just return the current error
reporting level.
This first function takes a parameter of an integer or a named constant. The named constant is recommended in case future version of PHP release new error levels. That way you will always know what to expect after upgrading to a newer version of PHP.
This next mode decides if errors will be printed to the screen or not.
ini_set('display_errors', 1)
This determines whether errors should be printed to the screen as part
of the output or if they should be hidden from the user.
The last one handles errors that happen during PHP's startup sequence. When you turn display_errors on it does not handle errors that occur in the startup sequence. This is partially the reason why a lot of times people do not understand why they are not seeing errors even though they have turned error reporting on.
Even when display_errors is on, errors that occur during PHP's startup
sequence are not displayed. It's strongly recommended to keep
display_startup_errors off, except for debugging.
This will tell the app to log errors to the server.
ini_set('log_errors', 1);
Tells whether script error messages should be logged to the server's
error log or error_log. This option is thus server-specific.
Example
To turn off error reporting in a file try this,
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(0);
To turn on error reporting in a file try this,
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Answer
If you want to log errors but do not want them to show up on the screen then you would need to do this,
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL);
Or try,
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
ini_set("log_errors", 1);
error_reporting(E_ALL);
What is the most convenient way of error reporting in finished website? I would like to still log exceptions and errors to external file. I definitely don't want the user to see anything more than "Error: something went wrong, we are lookin into it".
Does my try - catch work and can I log my Exceptions if I set:
error_reporting(0);
In your php.ini file you should hide errors:
display_errors = Off
If you want to know about any errors that occur (you should care) you should turn on error logging:
log_errors = On
How to set error reporting depends on what errors you want to know about. Ideally you should want to know about everything (maybe except errors about deprecated stuff; if the website is already done then you should have fixed any such errors). See this page for more information.
; Show everything except deprecated errors
error_reporting = E_ALL & ~E_DEPRECATED
And then there are a few more things you can set:
; It makes little sense to have this on
html_errors = Off
; Set this to where your log file should be stored
error_log = /path/to/log/file.log
; Maybe more, see link below...
You can see some more options here.
Restart your server after making changes to php.ini.
I have created a Shell using CakePHP. I am writing the output to a file using the following command:
sitename/app/Console/cake customconsole >> errorlog.log
Everything seems to work here, but I am not getting the PHP notices or warnings. However, I can see the notices and warnings in the terminal.
Is there any way by which I can log the notices and warnings to my log file as well?
I have made the following changes in php.ini for CLI:
display_errors
Default Value: On
error_reporting
Default Value: E_ALL
I have also adjusted debug value to 1 in CakePHP.
Thanks
A proper written app should not throw notices and hard errors anyway. Besides the attempt to logging them I would invest more time in unit testing and avoiding errors and notices. Specially notices are not hard to correct.
I'm not sure and to lazy to test this right now for you, you can do it yourself, CakePHP is using the console streams for different states, so I guess in the case of a hard php error it's sending the output to the error stream (2).
See this page http://www.ibm.com/developerworks/linux/library/l-lpic1-v3-103-4/ section "Redirecting output" how to redirect all streams in one file.
Try it, it might be the solution.
When our site used to be on IIS hosting with PHP installed, I had error reporting set to E_NONE and was able to turn it on temporarily by using:
ini_set('display_errors', 1);
That command seems to no longer work now that we are on Linux/Apache hosting. I have tried purposely sending bad commands to the server and I get no errors reported.
What am I doing wrong? Is there any other way to temporarily turn on error reporting without having to edit the php.ini each time?
You can change error reporting to E_ALL using the following line:
error_reporting(E_ALL);
Try adding that to the file.
The best way to turn on all errors is:
error_reporting( -1 );
This is better than E_ALL, as E_ALL doesn't actually mean all errors in all versions of PHP (it only does in the most recent). -1 is the only way to ensure it's on in all cases.
I just had to do this in one of my scripts. DOMDocument warnings were killing my logs. So, here's what you do:
// First, grab a copy of the current error_reporting level
// while setting the new level, I set it to zero because I wanted
// it off - but you could easily turn it on here
$erlevel = error_reporting(0);
// Then, do stuff that generates errors/warnings
// Finally, set the reporting level to it's previous value
error_reporting($erlevel);
I've seen a few methods for hiding php errors using php.ini or by adding php_flag display_errors off to .htaccess, but I'm wondering if there's a way to make it so only I can see php errors (useful for debugging obviously), but anyone else will be redirected to some boilerplate error page. I have a few scripts on my site that use my forum to authenticate me as an admin and kick everyone else out, so maybe it's possible using the same method?
If this isn't possible, I guess I'll go with the .htaccess method since I don't have access to php.ini. Is adding php_flag display_errors off to .htaccess a good way to go for this?
Thanks!
While displaying errors on screen is great for development (as you see them right away), they should not be enabled for production servers because you may accidentally expose sensitive information (e.g., database passwords) to unauthorized users.
The useful INI options are:
ini_set('error_reporting', E_ALL & ~E_NOTICE);
ini_set('error_log', '/path/to/my/php.log');
ini_set('log_errors', 'On'); // log to file (yes)
ini_set('display_errors', 'Off'); // log to screen (no)
With that, all errors will be logged to the specified file. No errors will be seen on the screen.
Make sure the web server user is able to write to that file. You may have to create it and chmod / chown it accordingly before running your script.
On private development servers, you could disable the log file and display directly to screen. When developing, I would also get in the habit of displaying E_NOTICE errors as well. (Just use E_ALL as the value.) And if your scripts are well written, you can then continue to log them while in production too. An E_NOTICE is good for catching typos in variable names or array indices.
Note that all of those options can also be set in the php.ini or .htaccess files. But if you use .htaccess you cannot use the E_* constants; instead, you must hardcode the integer representation. (i.e., In a .htaccess file, you use whatever the results of <?php echo E_ALL ?> show as the value, or whatever you wish to log.)
In fact, I would recommend setting them in the php.ini if at all possible. Otherwise, if there's a script parsing error (or the ini_set gets skipped for some reason), you may not get the errors logging properly, etc.
On a Linux box you can always do a tail -f /path/to/my/php.log from a shell to monitor the log in realtime.
Although I agree with konforce, this is possible by setting the error reporting at runtime with the error_reporting() function. If you insist on doing that, put it in the same block of code that you mentioned for determining you are the admin, so that you don't have the decision made in different places.
Since your code already knows you are an admin you can use a logic like this:
if($_SESSION['isadmin']==1){
ini_set('display_errors', 1);
ini_set('log_errors', 1);
}
The admins will see errors but the other users will not see the errors.
You can check against the users IP, and if it matches yours, you can show errors.
Something like this:
if($_SERVER['REMOTE_ADDR'] == 'your.ip.address'){
error_reporting(E_ALL);
} else {
error_reporting(0);
}
If you don't know you external IP, just google "what is my ip" or similar.
Base case scenario is obviously having a dev-server.
if you have a users system, set the codes so it recognize you when you log in, and show errors. So, it will only show errors when it's you who is logged in.