I have recently taken over development of a legacy system and want to be able to turn on logging of PHP E_NOTICE's on the deployment environment. The deployment environment ini has the following directives...
error_reporting = E_ALL & ~E_DEPRECATED
display_errors = Off
log_errors = On
I have compared the error_reporting bitmask by using echo (E_ALL & ~E_DEPRECATED).' = '.error_reporting();, and both match, so I know the error_reporting level isn't changed within the system itself, and if I turn display_errors = On notices are displayed, but not logged.
So how can I start logging PHP E_NOTICE's?
Update:
According to #m.p.c in the comments on this answer, errors are being displayed in the browser when display_errors is on, but they aren't appearing in the log. I was assuming errors weren't appearing at all.
Are E_NOTICE errors the only ones that aren't appearing in the log, or are all error types affected? If it's all error types, then the first thing I would check is whether or not error logging is even enabled. Try setting ini_set('log_errors', 'On'); at the top of your script. If that doesn't work, then try setting your log file to something you're sure your server can write to by calling ini_set('error_log', 'your_file_path');. If neither of these work, then I think something is seriously wrong with your PHP install. If either of these fixes work, you can put them into your actual php.ini if you have access.
Original Answer:
Based on the error_reporting level in your question, your PHP install should already be setup to report E_NOTICE errors. If it's not logging these errors, something is wrong. I would suggest turning on display_errors to see if any E_NOTICE errors are displayed. If you can't change the php.ini file, try running ini_set('display_errors', 'On'); at the top of your script. Obviously, these errors will only show up and/or be logged if you trigger one, so you should double check that you're actually doing that somewhere.
One caveat is that the E_DEPRECATED error level was only introduced with PHP 5.3. When I just tested setting E_DEPRECATED on a PHP 5.2 install, PHP responded with errors, and set the error_reporting level to 0, which means it reports no errors at all. While it makes no sense for a pre-5.3 php.ini file to use this setting, I feel it's important to at least raise the possibility that you're using E_DEPRECATED on a server that doesn't support it. If you're not sure of your version, you can run phpinfo() and it will display a page with lots and lots of information, including the version number for your install.
Notwithstanding the above, if I've misunderstood your question and you're only talking about creating your own custom logging, then you need to create a function to run when an error occurs and assign it as the error handler using the set_error_handler() function.
It's important to note that when you use set_error_handler(), you bypass PHP's default error handler entirely. This means that your error_handler level becomes meaningless. All errors, regardless of their severity, will be passed to the error handler function you've created. The first parameter passed to this function by PHP will be the error number, which is the numeric value of the E_xxx constant of the error that was found. You'll need to write custom code to catch only the errors you want.
For example, to catch only E_NOTICE errors, your function would look like this:
function my_error_handler($errno, $errstr, $errfile, $errline) {
if ($errno == E_NOTICE) {
// handle/log the error
}
}
set_error_handler("my_error_handler");
Turns out the system has a custom Apache ErrorLog directive defined, and I have been tail -f ... the default Apache error_log.
Note to self: always check the web server setup first before posting silly questions on SO!
You can create your own handler
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if ($errno == E_USER_NOTICE){
/* log actions here */
}
}
set_error_handler("myErrorHandler");
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);
I have been trying for three days now to enable error reporting in PHP. I have gotten by for a while using the ini_set('display errors' 1); function until I tried to connect to a DB; it didn't work. Now, I have enabled error_reporting, display_startup_errors, log_errors without any effect on error reporting. I have changed all five config files (the development ini, production ini, the php.ini file(s) located in php/7.0/cli, php/7.0/fpm, and even the one in apache2 (even though I am running nginx)
I am beginning to doubt my own abilities, any assistance is greatly appreciated.
EDIT: I have used the ini_set function described above in my files, and it worked up until I tried to connect to a DB. I have confirmed that I've enabled error reporting for the php.ini file described in the phpinfo() function directory path. No effect whatsoever.
Because no one particularily gave away the answer, I will just have to post it myself.
I found the error.log file (which indeed is logging all errors on my Nginx server) in this directory: /var/log/nginx/error.log
Hopefully this may help others using Nginx as well, but I still do not understand why the **** the errors aren't showing up in the browser. I think it is Nginx's nature to make everything quite complicated.
Perhaps I should develop using Apache and then port it into Nginx when I have more experience -- just some thoughts for others who are getting into this as well.
I just wanted to give an update on this: Since upgrading from PHP 7.0.2 <= 7.0.3, I am now able to see the errors that should have been displayed.
EDIT: Don't delete the contents of that log file, it will screw the whole error reporting. I'm back to nothing now. –
Error Reporting Itself
ini_set('display_errors', 1); or display_errors
Simply allows PHP to output errors - useful for debugging, highly recommended to disable for production environments. It often contains information you'd never want users to see.
error_reporting(E_ALL); or error_reporting
Simply sets exactly which errors are shown.
Setting one or the other will not guarantee that errors will be displayed. You must set both to actually see errors on your screen.
As for setting this up permanently inside your PHP config, the default for error_reporting is E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED. That said, this variable should not need changed. See here:
http://php.net/manual/en/errorfunc.configuration.php#ini.error-reporting
As for displaying errors, see here:
http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors
Set the config value of "display_errors" to either stderr or stdout, depending on your need.
Just change these variables inside of your php.ini file and you'll be golden. Make absolutely sure both display_errors and error_reporting is set to a satisfactory value. Just setting error_reporting will not guarantee that you see the errors you're looking for!
Error Reporting Works Everywhere Except When Connecting To My DB!
If you see errors everywhere you need to except in the Database Connection, you just need to do some error catching. If it's PDO, do something like this:
try {
$this->DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$this->DBH->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$STH = $this->DBH->prepare("INSERT INTO `" . $this->table . "` ($fs) value ($ins) $up");
$STH->execute($data);
$id = $this->DBH->lastInsertId();
$this->closeDb();
return $id;
} catch(PDOException $e) {
echo $e->getMessage();
}
Just a snippet from my framework. Of course you'll have to change it to your liking, but you should be able to get the general idea there. They key is this part here:
try {
//DB Stuff
} catch(PDOException $e) {
echo $e->getMessage();
}
I Still Don't See The Error
If you've done both of what I've listed here and still have trouble, your problem has nothing to do with enabling error reporting. The code provided will show you the error with a Database Connection itself, and inside of PHP code. You must have a completely different issue if this has not shown you an error you're chasing.
You'll likely need to be a bit more descriptive on exactly what you're chasing, and what you're expecting to see.
Try:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
perhaps, it will help you. change values of parameteres
in the file /etc/php/7.0/fpm/pool.d/www.conf (for example value display_errors by default is disabled)
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 don't get any PHP error, just get a white page on Firefox, and
Server error
The website encountered an error while retrieving http://example.com/pruebas/prov.php. It may be down for maintenance or configured incorrectly
on Chrome.
This is the code:
if (!ini_get('display_errors')) {
ini_set('display_errors', 1);
}
echo "hola"
echo "hola2";
I intentionally made mistake in the echo "hola" (there's no ';').
I also tried adding to the end of my .htaccess file -> suPHP_ConfigPath /home/username/public_html replacing username with my current username, and then I created a php.ini in public_html with "display_errors = on;". But I'm still not able to get any PHP error.
Your script is dying due to the syntax error before it ever executes, so the ini_set() call is never executed and never takes effect. You'd have to change the setting in the appropriate php.ini.
The actual error message may be in a log file somewhere. Try Apache's error_log, or see if PHP's logging somewhere else.
Make sure that you also have the appropriate error_reporting ini value set as well. You can find more information on PHP.net
Set the error reporting level. The parameter is either an integer representing a bit field, or named constants. The error_reporting levels and constants are described in Predefined Constants, and in php.ini. To set at runtime, use the error_reporting() function. See also the display_errors directive.
In PHP 4 and PHP 5 the default value is E_ALL & ~E_NOTICE. This setting does not show E_NOTICE level errors. You may want to show them during development.
Source
Make sure the display_errors is set to on on your php.ini file.
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!