For syntax errors, you need to enable error display in the php.ini. By default these are turned off because you don’t want a «customer» seeing the error messages. Check this page in the PHP documentation for information on the 2 directives: error_reporting
and display_errors
. display_errors
is probably the one you want to change. If you can’t modify the php.ini, you can also add the following lines to an .htaccess file:
php_flag display_errors on
php_value error_reporting 2039
You may want to consider using the value of E_ALL (as mentioned by Gumbo) for your version of PHP for error_reporting
to get all of the errors. more info
3 other items: (1) You can check the error log file as it will have all of the errors (unless logging has been disabled). (2) Adding the following 2 lines will help you debug errors that are not syntax errors:
error_reporting(-1);
ini_set('display_errors', 'On');
(3) Another option is to use an editor that checks for errors when you type, such as PhpEd. PhpEd also comes with a debugger which can provide more detailed information. (The PhpEd debugger is very similar to xdebug and integrates directly into the editor so you use 1 program to do everything.)
Cartman’s link is also very good: http://www.ibm.com/developerworks/library/os-debug/
Sumurai8
20k10 gold badges69 silver badges99 bronze badges
answered May 10, 2009 at 9:52
Darryl HeinDarryl Hein
141k91 gold badges216 silver badges260 bronze badges
3
Janyk
5713 silver badges18 bronze badges
answered Jul 4, 2011 at 19:46
EljakimEljakim
6,8572 gold badges16 silver badges16 bronze badges
6
The following code should display all errors:
<?php
// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);
// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);
// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
if(@is_array($error = @error_get_last()))
{
return(@call_user_func_array('ErrorHandler', $error));
};
return(TRUE);
};
register_shutdown_function('ShutdownHandler');
// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
$_ERRORS = Array(
0x0001 => 'E_ERROR',
0x0002 => 'E_WARNING',
0x0004 => 'E_PARSE',
0x0008 => 'E_NOTICE',
0x0010 => 'E_CORE_ERROR',
0x0020 => 'E_CORE_WARNING',
0x0040 => 'E_COMPILE_ERROR',
0x0080 => 'E_COMPILE_WARNING',
0x0100 => 'E_USER_ERROR',
0x0200 => 'E_USER_WARNING',
0x0400 => 'E_USER_NOTICE',
0x0800 => 'E_STRICT',
0x1000 => 'E_RECOVERABLE_ERROR',
0x2000 => 'E_DEPRECATED',
0x4000 => 'E_USER_DEPRECATED'
);
if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
{
$name = 'E_UNKNOWN';
};
return(print(@sprintf("%s Error in file xBB%sxAB at line %d: %sn", $name, @basename($file), $line, $message)));
};
$old_error_handler = set_error_handler("ErrorHandler");
// other php code
?>
The only way to generate a blank page with this code is when you have a error in the shutdown handler. I copied and pasted this from my own cms without testing it, but I am sure it works.
answered Aug 13, 2013 at 11:59
m4dm4x1337m4dm4x1337
1,8472 gold badges11 silver badges3 bronze badges
9
You can include the following lines in the file you want to debug:
error_reporting(E_ALL);
ini_set('display_errors', '1');
This overrides the default settings in php.ini, which just make PHP report the errors to the log.
answered May 10, 2009 at 9:54
TomalakTomalak
329k66 gold badges520 silver badges621 bronze badges
1
Errors and warnings usually appear in ....logsphp_error.log
or ....logsapache_error.log
depending on your php.ini settings.
Also useful errors are often directed to the browser, but as they are not valid html they are not displayed.
So "tail -f
» your log files and when you get a blank screen use IEs «view» -> «source» menu options to view the raw output.
Jens
66.3k15 gold badges97 silver badges113 bronze badges
answered Sep 25, 2009 at 4:22
James AndersonJames Anderson
27k7 gold badges51 silver badges78 bronze badges
4
PHP Configuration
2 entries in php.ini dictate the output of errors:
display_errors
error_reporting
In production, display_errors
is usually set to Off
(Which is a good thing, because error display in production sites is generally not desirable!).
However, in development, it should be set to On
, so that errors get displayed. Check!
error_reporting
(as of PHP 5.3) is set by default to E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
(meaning, everything is shown except for notices, strict standards and deprecation notices). When in doubt, set it to E_ALL
to display all the errors. Check!
Whoa whoa! No check! I can’t change my php.ini!
That’s a shame. Usually shared hosts do not allow the alteration of their php.ini file, and so, that option is sadly unavailable. But fear not! We have other options!
Runtime configuration
In the desired script, we can alter the php.ini entries in runtime! Meaning, it’ll run when the script runs! Sweet!
error_reporting(E_ALL);
ini_set("display_errors", "On");
These two lines will do the same effect as altering the php.ini entries as above! Awesome!
I still get a blank page/500 error!
That means that the script hadn’t even run! That usually happens when you have a syntax error!
With syntax errors, the script doesn’t even get to runtime. It fails at compile time, meaning that it’ll use the values in php.ini, which if you hadn’t changed, may not allow the display of errors.
Error logs
In addition, PHP by default logs errors. In shared hosting, it may be in a dedicated folder or on the same folder as the offending script.
If you have access to php.ini, you can find it under the error_log
entry.
mario
143k20 gold badges236 silver badges288 bronze badges
answered Feb 2, 2014 at 20:47
Madara’s GhostMadara’s Ghost
170k50 gold badges264 silver badges308 bronze badges
1
I’m always using this syntax at the very top of the php script.
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On'); //On or Off
answered Sep 25, 2009 at 7:48
FDiskFDisk
8,0342 gold badges45 silver badges51 bronze badges
2
There is a really useful extension called «xdebug» that will make your reports much nicer as well.
answered May 10, 2009 at 9:59
gnarfgnarf
104k25 gold badges125 silver badges161 bronze badges
3
For quick, hands-on troubleshooting I normally suggest here on SO:
error_reporting(~0); ini_set('display_errors', 1);
to be put at the beginning of the script that is under trouble-shooting. This is not perfect, the perfect variant is that you also enable that in the php.ini
and that you log the errors in PHP to catch syntax and startup errors.
The settings outlined here display all errors, notices and warnings, including strict ones, regardless which PHP version.
Next things to consider:
- Install Xdebug and enable remote-debugging with your IDE.
See as well:
- Error Reporting (PHP The Right Way.)
- Predefined ConstantsDocs
error_reporting()
Docsdisplay_errors
Docs
answered Jan 24, 2013 at 15:06
hakrehakre
189k51 gold badges426 silver badges824 bronze badges
It is possible to register an hook to make the last error or warning visible.
function shutdown(){
var_dump(error_get_last());
}
register_shutdown_function('shutdown');
adding this code to the beginning of you index.php will help you debug the problems.
answered Jan 5, 2016 at 18:59
1
If you are super cool, you might try:
$test_server = $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "localhost" || substr($_SERVER['SERVER_NAME'],0,3) == "192";
ini_set('display_errors',$test_server);
error_reporting(E_ALL|E_STRICT);
This will only display errors when you are running locally. It also gives you the test_server variable to use in other places where appropriate.
Any errors that happen before the script runs won’t be caught, but for 99% of errors that I make, that’s not an issue.
answered Jul 4, 2011 at 19:49
Rich BradshawRich Bradshaw
70.8k44 gold badges178 silver badges241 bronze badges
1
On the top of the page choose a parameter
error_reporting(E_ERROR | E_WARNING | E_PARSE);
answered May 6, 2013 at 14:14
KldKld
6,8633 gold badges36 silver badges50 bronze badges
This is a problem of loaded vs. runtime configuration
It’s important to recognize that a syntax error or parse error happens during the compile or parsing step, which means that PHP will bail before it’s even had a chance to execute any of your code. So if you are modifying PHP’s display_errors
configuration during runtime, (this includes anything from using ini_set
in your code to using .htaccess, which is a runtime configuration file) then only the default loaded configuration settings are in play.
How to always avoid WSOD in development
To avoid a WSOD you want to make sure that your loaded configuration file has display_errors
on and error_reporting
set to -1
(this is the equivalent E_ALL because it ensures all bits are turned on regardless of which version of PHP you’re running). Don’t hardcode the constant value of E_ALL, because that value is subject to change between different versions of PHP.
Loaded configuration is either your loaded php.ini
file or your apache.conf
or httpd.conf
or virtualhost file. Those files are only read once during the startup stage (when you first start apache httpd or php-fpm, for example) and only overridden by runtime configuration changes. Making sure that display_errors = 1
and error_reporting = -1
in your loaded configuration file ensures that you will never see a WSOD regardless of syntax or parse error that occur before a runtime change like ini_set('display_errors', 1);
or error_reporting(E_ALL);
can take place.
How to find your (php.ini) loaded configuration files
To locate your loaded configuration file(s) just create a new PHP file with only the following code…
<?php
phpinfo();
Then point your browser there and look at Loaded Configuration File and Additional .ini files parsed, which are usually at the top of your phpinfo()
and will include the absolute path to all your loaded configuration files.
If you see (none)
instead of the file, that means you don’t have a php.ini in Configuration File (php.ini) Path. So you can download the stock php.ini bundled with PHP from here and copy that to your configuration file path as php.ini then make sure your php user has sufficient permissions to read from that file. You’ll need to restart httpd or php-fpm to load it in. Remember, this is the development php.ini file that comes bundled with the PHP source. So please don’t use it in production!
Just don’t do this in production
This really is the best way to avoid a WSOD in development. Anyone suggesting that you put ini_set('display_errors', 1);
or error_reporting(E_ALL);
at the top of your PHP script or using .htaccess like you did here, is not going to help you avoid a WSOD when a syntax or parse error occurs (like in your case here) if your loaded configuration file has display_errors
turned off.
Many people (and stock installations of PHP) will use a production-ini file that has display_errors
turned off by default, which typically results in this same frustration you’ve experienced here. Because PHP already has it turned off when it starts up, then encounters a syntax or parse error, and bails with nothing to output. You expect that your ini_set('display_errors',1);
at the top of your PHP script should have avoided that, but it won’t matter if PHP can’t parse your code because it will never have reached the runtime.
answered Nov 12, 2015 at 6:24
SherifSherif
11.7k3 gold badges32 silver badges57 bronze badges
0
To persist this and make it confortale, you can edit your php.ini file. It is usually stored in /etc/php.ini
or /etc/php/php.ini
, but more local php.ini
‘s may overwrite it, depending on your hosting provider’s setup guidelines. Check a phpinfo()
file for Loaded Configuration File
at the top, to be sure which one gets loaded last.
Search for display_errors in that file. There should be only 3 instances, of which 2 are commented.
Change the uncommented line to:
display_errors = stdout
sjas
18.1k12 gold badges85 silver badges92 bronze badges
answered Jul 4, 2011 at 19:54
RamRam
1,1611 gold badge10 silver badges34 bronze badges
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
answered Dec 4, 2017 at 20:54
Abuzer FirdousiAbuzer Firdousi
1,5541 gold badge10 silver badges25 bronze badges
I don’t know if it will help, but here is a piece of my standard config file for php projects. I tend not to depend too much on the apache configs even on my own server.
I never have the disappearing error problem, so perhaps something here will give you an idea.
Edited to show APPLICATON_LIVE
/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment. It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/
if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', false);
} else {
die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
// Log or take other appropriate action.
}
/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging. Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
if ( ! APPLICATION_LIVE ) {
// A few changes to error handling for development.
// We will want errors to be visible during development.
ini_set ( "display_errors", "1");
ini_set ( "display_startup_errors", "1");
ini_set ( "html_errors", "1");
ini_set ( "docref_root", "http://www.php.net/");
ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
ini_set ( "error_append_string", "</div>");
}
peterh
11.4k17 gold badges85 silver badges104 bronze badges
answered Sep 25, 2009 at 8:09
EliEli
96.4k20 gold badges75 silver badges81 bronze badges
2
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
ini_set('html_errors', 1);
In addition, you can get more detailed information with xdebug.
Janyk
5713 silver badges18 bronze badges
answered Aug 19, 2014 at 15:36
Yan.ZeroYan.Zero
4494 silver badges12 bronze badges
1
I recommend Nette Tracy for better visualization of errors and exceptions in PHP:
Janyk
5713 silver badges18 bronze badges
answered Jul 15, 2015 at 22:38
Ondřej ŠotekOndřej Šotek
1,7711 gold badge13 silver badges24 bronze badges
1
error_reporting(E_ALL | E_STRICT);
And turn on display errors in php.ini
answered May 10, 2009 at 9:54
Ólafur WaageÓlafur Waage
68k21 gold badges142 silver badges196 bronze badges
You can register your own error handler in PHP. Dumping all errors to a file might help you in these obscure cases, for example. Note that your function will get called, no matter what your current error_reporting is set to. Very basic example:
function dump_error_to_file($errno, $errstr) {
file_put_contents('/tmp/php-errors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');
answered May 10, 2009 at 9:54
soulmergesoulmerge
72.7k19 gold badges118 silver badges153 bronze badges
0
The two key lines you need to get useful errors out of PHP are:
ini_set('display_errors',1);
error_reporting(E_ALL);
As pointed out by other contributors, these are switched off by default for security reasons. As a useful tip — when you’re setting up your site it’s handy to do a switch for your different environments so that these errors are ON by default in your local and development environments. This can be achieved with the following code (ideally in your index.php or config file so this is active from the start):
switch($_SERVER['SERVER_NAME'])
{
// local
case 'yourdomain.dev':
// dev
case 'dev.yourdomain.com':
ini_set('display_errors',1);
error_reporting(E_ALL);
break;
//live
case 'yourdomain.com':
//...
break;
}
Brad Larson♦
170k45 gold badges398 silver badges571 bronze badges
answered Jun 10, 2014 at 13:37
open your php.ini,
make sure it’s set to:
display_errors = On
restart your server.
Otiel
18.2k16 gold badges77 silver badges126 bronze badges
answered Jan 16, 2011 at 20:59
user577803user577803
611 silver badge1 bronze badge
0
You might also want to try PHPStorm as your code editor. It will find many PHP and other syntax errors right as you are typing in the editor.
answered Jun 18, 2014 at 1:03
if you are a ubuntu user then goto your terminal and run this command
sudo tail -50f /var/log/apache2/error.log
where it will display recent 50 errors.
There is a error file error.log
for apache2 which logs all the errors.
Unihedron
10.8k13 gold badges61 silver badges70 bronze badges
answered Nov 10, 2014 at 11:23
To turn on full error reporting, add this to your script:
error_reporting(E_ALL);
This causes even minimal warnings to show up. And, just in case:
ini_set('display_errors', '1');
Will force the display of errors. This should be turned off in production servers, but not when you’re developing.
answered May 10, 2009 at 12:09
1
The “ERRORS” are the most useful things for the developers to know their mistakes and resolved them to make the system working perfect.
PHP provides some of better ways to know the developers why and where their piece of code is getting the errors, so by knowing those errors developers can make their code better in many ways.
Best ways to write following two lines on the top of script to get all errors messages:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Another way to use debugger tools like xdebug in your IDE.
Janyk
5713 silver badges18 bronze badges
answered Feb 1, 2014 at 6:24
In addition to all the wonderful answers here, I’d like to throw in a special mention for the MySQLi and PDO libraries.
In order to…
- Always see database related errors, and
- Avoid checking the return types for methods to see if something went wrong
The best option is to configure the libraries to throw exceptions.
MySQLi
Add this near the top of your script
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
This is best placed before you use new mysqli()
or mysqli_connect()
.
PDO
Set the PDO::ATTR_ERRMODE
attribute to PDO::ERRMODE_EXCEPTION
on your connection instance. You can either do this in the constructor
$pdo = new PDO('driver:host=localhost;...', 'username', 'password', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
or after creation
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
answered Sep 14, 2018 at 3:31
PhilPhil
152k23 gold badges235 silver badges236 bronze badges
You can enable full error reporting (including notices and strict messages). Some people find this too verbose, but it’s worth a try. Set error_reporting
to E_ALL | E_STRICT
in your php.ini.
error_reporting = E_ALL | E_STRICT
E_STRICT
will notify you about deprecated functions and give you recommendations about the best methods to do certain tasks.
If you don’t want notices, but you find other message types helpful, try excluding notices:
error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE
Also make sure that display_errors
is enabled in php.ini. If your PHP version is older than 5.2.4, set it to On
:
display_errors = "On"
If your version is 5.2.4 or newer, use:
display_errors = "stderr"
answered May 10, 2009 at 9:58
Ayman HouriehAyman Hourieh
129k22 gold badges143 silver badges116 bronze badges
Aside from error_reporting and the display_errors ini setting, you can get SYNTAX errors from your web server’s log files. When I’m developing PHP I load my development system’s web server logs into my editor. Whenever I test a page and get a blank screen, the log file goes stale and my editor asks if I want to reload it. When I do, I jump to the bottom and there is the syntax error. For example:
[Sun Apr 19 19:09:11 2009] [error] [client 127.0.0.1] PHP Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\webroot\test\test.php on line 9
answered May 10, 2009 at 18:16
jmucchiellojmucchiello
18.5k7 gold badges41 silver badges61 bronze badges
This answer is brought to you by the department of redundancy department.
-
ini_set()
/ php.ini / .htaccess / .user.iniThe settings
display_errors
anderror_reporting
have been covered sufficiently now. But just to recap when to use which option:ini_set()
anderror_reporting()
apply for runtime errors only.php.ini
should primarily be edited for development setups. (Webserver and CLI version often have different php.ini’s).htaccess
flags only work for dated setups (Find a new hoster! Well managed servers are cheaper.).user.ini
are partial php.ini’s for modern setups (FCGI/FPM)
And as crude alternative for runtime errors you can often use:
set_error_handler("var_dump"); // ignores error_reporting and `@` suppression
-
error_get_last()
Can be used to retrieve the last runtime notice/warning/error, when error_display is disabled.
-
$php_errormsg
Is a superlocal variable, which also contains the last PHP runtime message.
-
isset()
begone!I know this will displease a lot of folks, but
isset
andempty
should not be used by newcomers. You can add the notice suppression after you verified your code is working. But never before.A lot of the «something doesn’t work» questions we get lately are the result of typos like:
if(isset($_POST['sumbit'])) # ↑↑
You won’t get any useful notices if your code is littered with
isset
/empty
/array_keys_exists
. It’s sometimes more sensible to use@
, so notices and warnings go to the logs at least. -
assert_options(ASSERT_ACTIVE|ASSERT_WARNING);
To get warnings for
assert()
sections. (Pretty uncommon, but more proficient code might contain some.)PHP7 requires
zend.assertions=1
in the php.ini as well. -
declare(strict_types=1);
Bending PHP into a strictly typed language is not going to fix a whole lot of logic errors, but it’s definitely an option for debugging purposes.
-
PDO / MySQLi
And @Phil already mentioned PDO/MySQLi error reporting options. Similar options exist for other database APIs of course.
-
json_last_error()
+json_last_error_msg
For JSON parsing.
-
preg_last_error()
For regexen.
-
CURLOPT_VERBOSE
To debug curl requests, you need CURLOPT_VERBOSE at the very least.
-
shell/exec()
Likewise will shell command execution not yield errors on its own. You always need
2>&1
and peek at the $errno.
answered May 17, 2019 at 12:00
mariomario
143k20 gold badges236 silver badges288 bronze badges
Содержание
- error_get_last
- Description
- Parameters
- Return Values
- Examples
- See Also
- User Contributed Notes 13 notes
- error_log
- Description
- Parameters
- Return Values
- Changelog
- Examples
- Notes
- User Contributed Notes 20 notes
- stuff
error_get_last
(PHP 5 >= 5.2.0, PHP 7, PHP
error_get_last — Get the last occurred error
Description
Gets information about the last error that occurred.
Parameters
This function has no parameters.
Return Values
Returns an associative array describing the last error with keys «type», «message», «file» and «line». If the error has been caused by a PHP internal function then the «message» begins with its name. Returns null if there hasn’t been an error yet.
Examples
Example #1 An error_get_last() example
The above example will output something similar to:
See Also
User Contributed Notes 13 notes
[Editor’s note: as of PHP 7.0.0 there is error_clear_last() to clear the most recent error.]
To clear error_get_last(), or put it in a well defined state, you should use the code below. It works even when a custom error handler has been set.
// var_dump or anything else, as this will never be called because of the 0
set_error_handler ( ‘var_dump’ , 0 );
@ $undef_var ;
restore_error_handler ();
// error_get_last() is now in a well known state:
// Undefined variable: undef_var
Function error_get_last() will return an error information even if the error is hidden because you’ve used character @, because of the «error_reporting» directive in the php.ini file, or because you’ve used function error_reporting().
( E_ALL ^ E_NOTICE );
$y = $x ;
$err = error_get_last ();
var_export ( $err );
?>
Will display: array ( ‘type’ => 8, ‘message’ => ‘Undefined variable: x’, ‘file’ => ‘test.php’, ‘line’ => 4, )
= @ $x ;
$err = error_get_last ();
var_export ( $err );
?>
Will display: array ( ‘type’ => 8, ‘message’ => ‘Undefined variable: x’, ‘file’ => ‘test.php’, ‘line’ => 4, )
The error_get_last() function will give you the most recent error even when that error is a Fatal error.
function handleFatalPhpError () <
$last_error = error_get_last ();
if( $last_error [ ‘type’ ] === E_ERROR ) <
echo «Can do custom output and/or logging for fatal error here. » ;
>
>
To know if something happened between two statements one can of course use a special string with user_error() (in lieu of a built-in special reset mentioned by mail at mbaierl dot com): @ user_error ( $error_get_last_mark = ‘error_get_last mark’ );
$not_set ;
$error_get_last = error_get_last ();
$something_happened =( $error_get_last [ ‘message’ ]!= $error_get_last_mark ); ?>
If your (function) ?> function returns true then you’ll have to roll you own error_get_last functionality. (Shortly mentioned by dmgx dot michael at gmail dot com).
To manual moderators: Re php.net/manual/add-note.php: Since i guess the above technically sorts under «References to other notes» i feel the need to defend myself with that i’m thinking it might show for usability where other’s say it fails and no, i haven’t got any other medium to reach the readers of the php manual notes.
Also, you could have some examples of what notes you think is okay. Thanks for your moderation.
Like $php_errormsg, the return value of this function may not be updated if a user-defined error handler returns non-FALSE. Tested on PHP 5.2.6.
( PHP_VERSION );
// Outputs: string(5) «5.2.6»
@ trigger_error ( «foo» );
$e = error_get_last ();
var_dump ( $e [ ‘message’ ]);
// Outputs: string(3) «foo»
set_error_handler ( create_function ( ‘$a,$b’ , » ));
@ trigger_error ( «bar» );
$e = error_get_last ();
var_dump ( $e [ ‘message’ ]);
// Outputs: string(3) «foo»
set_error_handler ( create_function ( ‘$a,$b’ , ‘return false;’ ));
@ trigger_error ( «baz» );
$e = error_get_last ();
var_dump ( $e [ ‘message’ ]);
// Outputs: string(3) «baz»
?>
Beware that registing a shutdown function to catch errors won’t work if other shutdown functions throw errors.
( ‘cleanupObjects’ );
register_shutdown_function ( ‘handleFatalPhpError’ );
function cleanupObjects () <
trigger_error ( ‘An insignificant problem’ , E_USER_WARNING );
>
function handleFatalPhpError () <
$last_error = error_get_last ();
if( $last_error [ ‘type’ ] === E_ERROR || $last_error [ ‘type’ ] === E_USER_ERROR ) <
echo «Can do custom output and/or logging for fatal error here. » ;
>
>
trigger_error ( ‘Something serious’ , E_USER_ERROR );
?>
In the above code, $last_error will contain the warning, becuase cleanupObjects() is called first.
This is a simple debugging script for mail functions.
//Built By Manomite for Debugging
error_reporting ( E_ALL ^ E_NOTICE );
$err = error_get_last ();
$res = «An error has occurred in your application sir.n Details Include » . $err . «»
mail ( «admin@manomite.net» , «Error Occurred» , $res , $from );
>
>
>
?>
If you have the need to check whether an error was a fatal error before PHP 5.2 (in my case, within an output buffer handler), you can use the following hack:
# Check if there was a PHP fatal error.
# Using error_get_last is the «right» way, but it requires PHP 5.2+. The back-up is a hack.
if ( function_exists ( ‘error_get_last’ )) <
$lastPHPError = error_get_last ();
$phpFatalError = isset( $lastPHPError ) && $lastPHPError [ ‘type’ ] === E_ERROR ;
> else <
$phpFatalError = strstr ( $output , ‘Fatal error:’ ) && ! strstr ( $output , ‘ ‘ );
>
?>
This is, of course, language-dependent, so it wouldn’t be good in widely-distributed code, but it may help in certain cases (or at least be the base of something that would work).
While mail at mbaierl dot com makes the point that this function isn’t best for reporting the possible error condition of the most recently executed step, there are situations in which it is especially helpful to know the last error—regardless of when it occurred.
As an example, imagine if you had some code that captured the output from dynamic pages, and cached it for faster delivery to subsequent visitors. A final sanity check would be to see if an error has occurred anywhere during the execution of the script. If there has been an error, we probably don’t want to cache that page.
Источник
error_log
(PHP 4, PHP 5, PHP 7, PHP
error_log — Send an error message to the defined error handling routines
Description
Sends an error message to the web server’s error log or to a file.
Parameters
The error message that should be logged.
Says where the error should go. The possible message types are as follows:
error_log() log types
message is sent to PHP’s system logger, using the Operating System’s system logging mechanism or a file, depending on what the error_log configuration directive is set to. This is the default option. | |
1 | message is sent by email to the address in the destination parameter. This is the only message type where the fourth parameter, additional_headers is used. |
2 | No longer an option. |
3 | message is appended to the file destination . A newline is not automatically added to the end of the message string. |
4 | message is sent directly to the SAPI logging handler. |
The destination. Its meaning depends on the message_type parameter as described above.
The extra headers. It’s used when the message_type parameter is set to 1 . This message type uses the same internal function as mail() does.
Return Values
Returns true on success or false on failure. If message_type is zero, this function always returns true , regardless of whether the error could be logged or not.
Changelog
Version | Description |
---|---|
8.0.0 | destination and additional_headers are now nullable. |
Examples
Example #1 error_log() examples
// Send notification through the server log if we can not
// connect to the database.
if (! Ora_Logon ( $username , $password )) <
error_log ( «Oracle database not available!» , 0 );
>
// Notify administrator by email if we run out of FOO
if (!( $foo = allocate_new_foo ())) <
error_log ( «Big trouble, we’re all out of FOOs!» , 1 ,
«operator@example.com» );
>
// another way to call error_log():
error_log ( «You messed up!» , 3 , «/var/tmp/my-errors.log» );
?>
Notes
error_log() is not binary safe. message will be truncated by null character.
message should not contain null character. Note that message may be sent to file, mail, syslog, etc. Use appropriate conversion/escape function, base64_encode() , rawurlencode() or addslashes() before calling error_log() .
User Contributed Notes 20 notes
Advice to novices: This function works great along with «tail» which is a unix command to watch a log file live. There are versions of Tail for Windows too, like Tail for Win32 or Kiwi Log Viewer.
Using both error_log() and tail to view the php_error.log you can debug code without having to worry so much about printing debug messages to the screen and who they might be seen by.
Further Note: This works even better when you have two monitors setup. One for your browser and IDE and the other for viewing the log files update live as you go.
DO NOT try to output TOO LARGE texts in the error_log();
if you try to output massive amounts of texts it will either cut of the text at about 8ooo characters (for reasonable massive strings,
There is a limit on the maximum length that you can pass as the $message.
The default seem to be 1024 but can be changed by adjusting the value of the runtime configuration value of ‘log_errors_max_len’.
Beware! If multiple scripts share the same log file, but run as different users, whichever script logs an error first owns the file, and calls to error_log() run as a different user will fail *silently*!
Nothing more frustrating than trying to figure out why all your error_log calls aren’t actually writing, than to find it was due to a *silent* permission denied error!
when using error_log to send email, not all elements of an extra_headers string are handled the same way. «From: » and «Reply-To: » header values will replace the default header values. «Subject: » header values won’t: they are *added* to the mail header but don’t replace the default, leading to mail messages with two Subject fields.
( «sometext» , 1 , «zigzag@my.domain» ,
«Subject: FoonFrom: Rizzlas@my.domainn» );
You can easily filter messages sent to error_log() using «tail» and «grep» on *nix systems. This makes monitoring debug messages easy to see during development.
Be sure to «tag» your error message with a unique string so you can filter it using «grep»:
error_log(«DevSys1 — FirstName: $FirstName — LastName: $Lastname»);
On your command line:
tail -f /var/log/httpd/error_log | grep DevSys1
In this example, we pipe apache log output to grep (STDIN) which filters it for you only showing messages that contain «DevSys1».
The «-f» option means «follow» which streams all new log entries to your terminal or to any piped command that follows, in this case «grep».
Relative paths are accepted as the destination of message_type 3, but beware that the root directory is determined by the context of the call to error_log(), which can change, so that one instance of error_log () in your code can lead to the creation of multiple log files in different locations.
In a WordPress context, the root directory will be the site’s root in many cases, but it will be /wp-admin/ for AJAX calls, and a plugin’s directory in other cases. If you want all your output to go to one file, use an absolute path.
When logging to apache on windows, both error_log and also trigger_error result in an apache status of error on the front of the message. This is bad if all you want to do is log information. However you can simply log to stderr however you will have to do all message assembly:
LogToApache($Message) <
$stderr = fopen(‘php://stderr’, ‘w’);
fwrite($stderr,$Message);
fclose($stderr);
>
«It appears that the system log = stderr if you are running PHP from the command line»
Actually, it seems that PHP logs to stderr if it can’t write to the log file. Command line PHP falls back to stderr because the log file is (usually) only writable by the webserver.
Note that since typical email is unencrypted, sending data about your errors over email using this function could be considered a security risk. How much of a risk it is depends on how much and what type of information you are sending, but the mere act of sending an email when something happens (even if it cannot be read) could itself imply to a sophisticated hacker observing your site over time that they have managed to cause an error.
Of course, security through obscurity is the weakest kind of security, as most open source supporters will agree. This is just something that you should keep in mind.
And of course, whatever you do, make sure that such emails don’t contain sensitive user data.
Another trick to post «HTML» mail body. Just add «Content-Type: text/html; charset=ISO-8859-1» into extra_header string. Of course you can set charset according to your country or Env or content.
stuff
«,1,»eat@joe.com»,»subject :lunchnContent-Type: text/html; charset=ISO-8859-1″);
//Multiline error log class
// ersin güvenç 2008 eguvenc@gmail.com
//For break use «n» instead ‘n’
Class log <
//
const USER_ERROR_DIR = ‘/home/site/error_log/Site_User_errors.log’ ;
const GENERAL_ERROR_DIR = ‘/home/site/error_log/Site_General_errors.log’ ;
/*
User Errors.
*/
public function user ( $msg , $username )
<
$date = date ( ‘d.m.Y h:i:s’ );
$log = $msg . » | Date: » . $date . » | User: » . $username . «n» ;
error_log ( $log , 3 , self :: USER_ERROR_DIR );
>
/*
General Errors.
*/
public function general ( $msg )
<
$date = date ( ‘d.m.Y h:i:s’ );
$log = $msg . » | Date: » . $date . «n» ;
error_log ( $msg . » | Tarih: » . $date , 3 , self :: GENERAL_ERROR_DIR );
>
$log = new log ();
$log -> user ( $msg , $username ); //use for user errors
//$log->general($msg); //use for general errors
?>
Depending on the error, you may also want to add an error 500 header, and a message for the user:
$message = ‘Description of the error.’;
error_log($message);
header($_SERVER[‘SERVER_PROTOCOL’] . ‘ 500 Internal Server Error’, true, 500);
exit($message);
When error_log() unexpectedly uses stdout, you should check if the php.ini value for error_log is empty in your CLI environment. Something as simple as this might restore expected behavior:
After scouring the internet for getting event logging to
work in syslog on Windows 2003, I found the following
from this post and was able to successfully get Windows
Event Viewer to log PHP errors/notices:
Источник
on
May 06, 2021
The Essential Guide to PHP Error Logging
PHP has been one of the top (if not best) server-side scripting languages in the world for decades. However, let’s be honest – error logging in PHP is not the most straightforward or intuitive. It involves tweaking a few configuration options plus some playing around to get used to. Once you have everything set up and figured out (like you will after reading this post), things seem much easier, and you realize how helpful error logging can turn out to be for your application – from debugging and troubleshooting to monitoring and maintenance.
And this is why we are covering error logging in PHP in this post. We will start by revisiting the importance of logging errors in your application. We will then explore errors in PHP – their different types, and how they can be output. Next, we will look at all the error logging configurations in PHP, and understand how we can tweak these to our liking, before we see some error logging examples, and explore functions in PHP that allow us to write errors to log files. This post is a complete guide to error logging in PHP.
Here’s an outline of what we’ll be covering so you can easily navigate or skip ahead in the guide:
- Importance of Logging Errors
- PHP Error Types
- Where Can PHP Errors be Output
- Enabling and Configuring Error Reporting in PHP
- Logging Errors in PHP
- PHP’s Error Logging Functions
- error_log()
- trigger_error()
- syslog()
- set_error_handler()
- Popular PHP Logging Libraries
Importance of Logging Errors
Errors in software systems have this terrible reputation of being associated with failing things and breaking functionality. As a result, many of us often fail to recognize the importance of these loud red strings that bring our attention to faults, inconsistencies, and inaccuracies in our code – mistakes that can cost us dearly if allowed to fall through the cracks. Therefore, it is worthwhile for some of us to change our outlook towards error messages – to track, log, and organize them – and embrace their importance.
There’s a reason developers and organizations build and leverage dedicated logging systems that keep track of errors that arise throughout an application’s lifecycle. These logs provide useful information about what went wrong, when, where, and how it can be fixed.
For small-scale personal projects, it is common for developers not to feel the need to spend time setting up an effective logging system. This seems plausible because your code and end-user interactions are much more manageable for smaller projects. However, the requirement for effectively logging and maintaining errors and other information grows exponentially as your application scales. For larger applications, catering to thousands of users, it becomes unwieldy to track errors and updates across hundreds of components in real-time. Putting in place a system that can record the status of the very many events that an application’s operation entails allows organizations to maintain a clear record of their performance. This allows for more transparency and therefore ensures that no issues go unnoticed. As a result, this makes your application more reliable, easy to maintain, monitor, and debug.
Now that we are hopefully convinced that error logging is a worthwhile expedition, let us look at the different types of errors in PHP.
PHP Error Types
Broadly, there are five types of errors in PHP:
1. Fatal run-time Errors (E_ERROR)
These errors typically happen when an operation in your code cannot be performed. This leads to your code exiting. An example of a fatal error would be when you call a function that hasn’t been defined in your code, shown below:
<?php
function foo() {
echo "Function foo called.";
}
boo(); // undefined function 'boo'
?>
Error output –>
Fatal error: Uncaught Error: Call to undefined function boo() in code/my-php/index.php:5 Stack trace: #0 {main} thrown in code/my-php/index.php on line 5.
2. Warning Errors (E_WARNING)
A warning error is more gentle and less obtrusive in that it does not halt the execution. It presents a friendly reminder of something amiss in your code – a mistake that might not fail things immediately or fail anything at all but suggests a more accurate way of doing things that make your code more foolproof. These warnings can also save developers from issues that might pose a much bigger threat in the future. An example of a warning error would be when you try to include a file in PHP using an incorrect file path, as shown below:
<?php
include('filename.txt'); // arbitrary file that is not present
echo "Hello world";
?>
Error output ->
Warning: include(filename.txt): failed to open stream: No such file or directory in code/my-php/index.php on line 2
3. Parse Errors (E_PARSE)
Parse errors are also known as syntax errors as they arise from syntactical mistakes in your code. These errors are raised during the compilation of your code, making it exit before it runs. A common example of a parse error is missing a semicolon at the end of a code statement, shown below:
<?php
echo Hello world // no quotes or semicolon used
?>
Error output ->
Parse error: syntax error, unexpected 'world' (T_STRING), expecting ',' or ';' in code/my-php/index.php on line 2.
4. Notice Errors (E_NOTICE)
Notice errors are minor errors that are encountered during run-time, and just like warning errors, do not halt the execution. They usually occur when the script is attempting to access an undefined variable, for example, as shown below:
<?php
$a = 1;
$c = $a + $b; // undefined variable $b
?>
Error output ->
Notice: Undefined variable: b in code/my-php/index.php on line 3
5. User Errors (E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE)
User errors are user-defined, i.e., present a custom user-generated message raised explicitly from the code to capture a specific condition. These errors are manually raised by developers using the trigger_error function instead of the PHP engine. They are further classified as fatal, warning, and notice errors, but we’ll group them all as user errors for simplicity.
Where can PHP Errors be Output?
There are two primary places where we can have our errors presented in PHP – through inline errors and dedicated error log files.
Inline Errors
Inline errors are those that show up on your webpage in the browser or your terminal via STDOUT in a command-line environment. These errors prove to be quite useful during development – for developers to debug their code, fix issues, and get information about the overall execution. Below is an example of what these errors usually look like in the browser:
Though this proves to be super helpful for developers, you should be very careful in ensuring that these errors are not output when your application goes into production – for two reasons – end-user experience and security. You can toggle the displaying of these errors using the display_error directive in your system’s configuration. We’ll dive deeper into this in the next section.
Error Log Files
Inline errors are not persistent in memory, i.e., they are not saved anywhere and are only viewed as long as the browser or terminal session is alive. Additionally, you’ll only want to have them in a development environment. Conversely, as the theme of this post suggests, logging your errors is the more intelligent and more systematic approach towards maintaining large-scale applications. These are persistent in memory and provide information about the operation of your application across multiple components in one place, making it easier for monitoring and troubleshooting.
PHP, therefore, allows you to direct all your errors to specific log files; these files store timestamps, error stack traces, custom messages, and other helpful information about the source of the error and how to fix it. You can specify the path of your custom log file using the error_log directive of your system configuration. Here’s an example of an error log file:
You can also choose to have your errors logged to the system’s log file, usually located in – /var/log/syslog. We’ll cover this in a later section in the post.
Now let’s look at how we can configure where and how we want our errors logged.
Enabling and Configuring Error Reporting in PHP
As we discussed previously, logging in PHP is slightly less straightforward than other languages and frameworks. You might have to tweak a few options in configuration files to customize logging patterns. For example, when you install PHP on your machine, the initial configuration comes with some aspects of error logging disabled. This differs from system to system, and therefore, you should manually check these settings before getting started.
Logging Configuration Options in php.ini File
The configuration options are in the php.ini file. This file is read when PHP starts up and allows developers to play around with PHP’s functionality. Usually, this file can be found somewhere in the /etc/php directory on most Linux systems.
There are a bunch of directives (options) pertaining to the logging of errors in PHP that we can configure in this php.ini file:
- display_errors (default: 1)
Display errors are the inline errors we previously looked at. This directive can be used to good effect during development to output PHP error messages to the browser or terminal. However, for applications in production, you should likely turn this off to save your users from a poor website experience due to obscure error messages. Not only that, but this also protects you from exposing valuable information about the internals of your application as a security measure.
- display_startup_errors (default: 0)
As the name suggests, this is to output any errors that take place when PHP starts up. These usually do not provide any valuable information about your application specifically, and therefore need not be turned on.
- log_errors (default: 0)
This directive allows you to toggle the logging of errors to the specified path (in the next directive). Because this is turned off by default, it would be advisable to toggle this to 1 for recording your application’s error messages in a log file.
- error_log (default: 0)
This directive allows you to specify the path of your log file. You can also set this to “syslog” for directing all your error log messages to the system log.
- error_reporting (default: null)
The error_reporting directive allows you to customize which error levels you want reported, and which you are okay with going unreported. For example, you can use the directive as shown below to have all errors reported: error_reporting = E_ALL
- track_errors (default: 0)
This directive allows you to access the last raised error message in the $php_errormsg global variable in your code and can keep track of errors across your whole project.
After making changes to your php.ini file, you will need to restart the server for the changes to take effect.
The ini_set() Function
However, if you are unable to locate the php.ini file, or prefer overriding your project’s global configuration options, there is also an option to update these directives using the ini_set() function in your PHP code. For example, the below code can be used for customizing error reporting in your project:
<?php
// enabling error logging
ini_set('log_errors', 1);
// Customize reporting of errors
ini_set('error_reporting', E_WARNING | E_ERROR | E_PARSE | E_NOTICE);
// specify error log file path
ini_set('error_log', '/tmp/my-logs.log');
?>
The error_reporting() Function
One can also modify the error_reporting configuration option using the error_reporting() function from inside your code during run-time. As in the ini_set function, you can use bitwise operators like OR (|), AND (&), NOT (~), etc., when specifying the error levels to be reported. Below are a few examples of how this function can be used.
// Report only selected kinds of errors
error_reporting(E_ERROR | E_PARSE | E_NOTICE);
or
// Report all errors except E_WARNING
error_reporting(E_ALL & ~E_WARNING);
Now that we have got the system configurations and overall setup out of the way, let’s look at an example of how errors in your project code can be logged to files on your system.
Logging Errors in PHP
First, we will override the logging configuration parameters using the ini_set() function to enable error logging and specify the log file’s path. Then we’ll write some erroneous code to have PHP raise an error that we would like to have logged.
<?php
ini_set('log_errors', 1); // enabling error logging
ini_set('error_log', '/path/my-error-file.log'); // specifying log file path
echo $b; // undefined variable should raise error
?>
After opening the web page on our browser, let’s open the ‘my-error-file.log’ file to see if the error message was logged. Here is the log file output:
[28-Feb-2021 13:34:36 UTC] PHP Notice: Undefined variable: b in code/my-php/index.php on line 5
As you can see, our notice error was logged with a timestamp. As our code encounters more and more errors, this file will keep getting populated with corresponding timestamps. Note that we haven’t explicitly turned off display_errors, so these error messages are likely to be logged to the browser web page – something you might want to avoid during production.
This was an example of capturing errors raised by PHP in log files. Now let’s look at how we can raise and log custom error messages for our application.
PHP’s Error Logging Functions
So far, we looked at errors raised by PHP – errors about your code execution. However, oftentimes you would want to also capture custom errors, with custom error messages specific to the functioning of your application. These so-called errors might not necessarily fail your code or halt its execution, but can indicate conditions characterized as erroneous and noteworthy for your application. These can act as indications to the organization about anomalous behavior that the team might want to look into and fix.
To facilitate this, PHP provides a set of functions that we can use to actively log errors in our code.
error_log()
The most common method for actively logging errors is the error_log() function. This sends a string argument for the error message to the log file.
error_log (string $message, int $message_type=0, string $destination=?, string $extra_headers=?) : bool
It also takes many other parameters to send error messages over email or specific log files. However, for the sake of simplicity, we won’t be covering that here.
The interesting thing about this function is it logs your error message to the file specified in the configuration (or to the system log), regardless of the value of the log_errors directive. Let’s take a very simple example of logging an error when a specific condition in our code is met.
<?php
ini_set('error_log', '/path/my-error-file.log');
$a = 5;
$b = 10;
$c = $a + $b;
if ($c < 20) {
error_log("Sum is less than 20."); // logging custom error message
}
?>
Here is the output of the log file:
[28-Feb-2021 13:31:50 UTC] Sum is less than 20
Similarly, you can also log the values of variables in your code to provide additional context about your errors. Let’s see an example for that:
<?php
ini_set('error_log', '/path/my-error-file.log');
$languagesArray = array("PHP", "Python", "Node.js");
error_log("Lorem ipsum. Array data -> ".print_r($languagesArray, true));
?>
Here’s the output of the log file ->
[28-Feb-2021 13:49:28 UTC] Lorem ipsum. Array data -> Array
(
[0] => PHP
[1] => Python
[2] => Node.js
)
trigger_error()
The trigger_error() function can be used to raise a user-defined error/warning/notice. You can also specify the error type based on the condition. This allows you to customize its reporting and other behavior – for example, using an error type of E_USER_ERROR. We can cause the code to exit immediately compared to an E_USER_WARNING error.
trigger_error (string $error_msg, int $error_type=E_USER_NOTICE) : bool
The difference between trigger_error and error_log is that the former only generates a user error and depends on your system’s logging configurations to handle this error message (whether displayed or logged). error_log, on the other hand, will log your message regardless of the system’s configuration.
Here is the code for the same example we saw previously:
<?php
ini_set('log_errors', 1); // enabling error logging
ini_set('error_log', '/path/my-error-file.log'); // specifying log file path
$a = 5;
$b = 10;
$c = $a + $b;
if ($c < 20) {
trigger_error("Sum is less than 20.", E_USER_ERROR);
echo "This will not be printed!";
}
?>
This adds a similar log entry to what we saw previously, but with an error level, plus the conventional error source information (log file output below):
[01-Mar-2021 01:16:56 UTC] PHP Fatal error: Sum is less than 20. in code/my-php/index.php on line 10
syslog()
You can also choose to directly send an error message to the system’s log using the syslog() function.
syslog (int $priority, string $message) : bool
The first argument is the error’s priority level – LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_ALERT, LOG_EMERG, etc. (more about it here). The second argument is the actual message’s text. This is how the function can be used:
<?php
// opening logger connection
openlog('myApp', LOG_CONS | LOG_NDELAY | LOG_PID, LOG_USER | LOG_PERROR
); // more information about params in documentation
syslog(LOG_WARNING, "My error message!");
closelog();
?>
This should reflect in your system’s logger (usually in /var/log/syslog) as:
Mar 1 13:27:15 zsh php: My error message!
set_error_handler()
To customize the handling of all the user-defined errors throughout your code, PHP allows you to specify a custom error handler function to override the default handling of errors. This makes it easy for organizations to modify how they want their errors logged, the corresponding error messages send method, and much more. The set_error_handler() function helps with this.
set_error_handler (callable $error_handler, int $error_types=E_ALL | E_STRICT) : mixed
It takes as an argument our custom error handler function, which will define the handling of our errors, and look something like this:
handler (int $errno, string $errstr, string $errfile=?, int $errline=?, array $errcontext=?) : bool
This takes in many parameters like the error number, error string, corresponding file, etc. Let’s understand this better using the same previous example:
<?php
// custom error handler function ->
function myErrorHandler($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - "); // timestamp in error message
$message .= "My Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, n"; // custom error message
$message .= "Variables:" . print_r($errcontext, true) . "rn";
error_log($message, 3, "/path/my-error-file.log");
die("There was a problem, please try again."); // exit code
}
set_error_handler("myErrorHandler");
$a = 5;
$b = 10;
$c = $a + $b;
if ($c < 20) {
trigger_error("Sum is less than 20.", E_USER_WARNING);
}
echo "This will not be printed!";
?>
Here, we define a custom error handler function where we modify the error message a bit, log it, and exit the code. Then, when we use the trigger_error() function, its logging is handled by the above function, which takes care of the rest. This is what the output in the log file looks like:
2021-03-01 06:58:07 - My Error: [512], Sum is less than 20. in code/my-php/index.php on line 22,
Variables:Array
(
[a] => 5
[b] => 10
[c] => 15
)
As you can see, this can be used to fully customize error logging in applications, allowing organizations to prioritize aspects of errors and contexts that are more important for their application.
Popular PHP Logging Libraries
Thanks to the huge PHP community support on the internet, there have been very many logging libraries that aim to provide more functionality and ease the overall process for developers and organizations. Each of the renowned PHP frameworks that you must have heard of come equipped with logging libraries built-in. There are also now logging standards established, like the PSR-3 (PHP Standards Recommendation) logger interface, that defines a standardized interface to follow for logging libraries.
Below is a list of some of the most popular logging libraries in PHP:
- Monolog
- Analog
- KLogger
- Log4PHP
Feel free to check these out to see what default error logging in PHP is missing out on.
Wrapping Up
In this post, we covered everything about errors and logging in PHP. We discussed the importance of logging mechanisms in your application, looked at the different types of errors in PHP, and explored the various configuration options and PHP functions that we can use to log errors effectively.
Now that you have a decent understanding of everything, go ahead and start implementing error logging for your application! It doesn’t matter if you are working on a small project where things might seem under control even without log files. Logging your errors is considered one of the top “best practices” in software development that becomes exponentially more important as your applications grow and scale.
To learn more about logging in PHP in general, feel free to check out the Tutorial: Log to Console in PHP on our blog!
To up your application monitoring game by identifying bottlenecks and gaining effective application performance insights, check out ScoutAPM to get started with a 14-day free trial!
Happy coding!
shawing at gmail dot com ¶
18 years ago
Although the root user writes to the files 'error_log' and 'access_log', the Apache user has to own the file referenced by 'error_log = filename' or no log entries will be written.
; From php.ini
; Log errors to specified file.
error_log = /usr/local/apache/logs/php.errors
[root@www logs]$ ls -l /usr/local/apache/logs/php.errors
-rw-r--r-- 1 nobody root 27K Jan 27 16:58 php.errors
tracerdx at tracerdx dot com ¶
17 years ago
I keep seeing qualification lists for error types/error-nums as arrays; In user notes and in the manual itself. For example, in this manual entry's example, when trying to seperate behavior for the variable trace in the error report:
<?php //...
// set of errors for which a var trace will be saved
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);//and later...if (in_array($errno, $user_errors)) {
//...whatever
}//... ?>
I was under the impression that PHP error code values where bitwise flag values. Wouldn't bitwise masking be better? So I propose a slightly better way:
<?php //...$user_errors = E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE;//...blah...if ($errno & $user_errors) {
//...whatever
}//... ?>
Or for those of you who don't like the idea of using an integer as the condition in an if statement:
<?php
if (($errno & $user_errors) > 0) {
//...whatever
}
?>
I think that's much more efficient than using _yet another_ array() constuct and an in_array().
If I am wrong, and the E_* constants aren't supposed to be used in this fashion (ie, the constans aren't guaranteed to be bitwise, which would be odd since that's how they're setup in the php.ini file), then delete me. I just don't see why one should be using arrays when bitwise comparisons will work, considering the bitwise method should be MUCH more efficient.
ptah at se dot linux dot org ¶
18 years ago
PHP5 only (only tested with php5.0).
If you, for some reason, prefer exceptions over errors and have your custom error handler (set_error_handler) wrap the error into an exception you have to be careful with your script.
Because if you, instead of just calling the exception handler, throws the exception, and having a custom exception handler (set_exception_handler). And an error is being triggered inside that exception handler, you will get a weird error:
"Fatal error: Exception thrown without a stack frame in Unknown on line 0"
This error is not particulary informative, is it? :)
This example below will cause this error.
<?php
class PHPErrorException extends Exception
{
private $context = null;
public function __construct
($code, $message, $file, $line, $context = null)
{
parent::__construct($message, $code);
$this->file = $file;
$this->line = $line;
$this->context = $context;
}
};
function
error_handler($code, $message, $file, $line) {
throw new PHPErrorException($code, $message, $file, $line);
}
function
exception_handler(Exception $e)
{
$errors = array(
E_USER_ERROR => "User Error",
E_USER_WARNING => "User Warning",
E_USER_NOTICE => "User Notice",
);
echo
$errors[$e->getCode()].': '.$e->getMessage().' in '.$e->getFile().
' on line '.$e->getLine()."n";
echo $e->getTraceAsString();
}set_error_handler('error_handler');
set_exception_handler('exception_handler');// Throw exception with an /unkown/ error code.
throw new Exception('foo', 0);
?>
There are however, easy fix for this as it's only cause is sloppy code.
Like one, directly call exception_handler from error_handler instead of throwing an exception. Not only does it remedy this problem, but it's also faster. Though this will cause a `regular` unhandled exception being printed and if only "designed" error messages are intended, this is not the ultimate solution.
So, what is there to do? Make sure the code in exception_handlers doesn't cause any errors! In this case a simple isset() would have solved it.
regards, C-A B.
Stephen ¶
16 years ago
If you are using PHP as an Apache module, your default behavior may be to write PHP error messages to Apache's error log. This is because the error_log .ini directive may be set equal to "error_log" which is also the name of Apache's error log. I think this is intentional.
However, you can separate Apache errors from PHP errors if you wish by simply setting a different value for error_log. I write mine in the /var/log folder.
mortonda at dgrmm dot net ¶
16 years ago
Note the example code listed here calls date() every time this is called. If you have a complex source base which calls the custom error handler often, it can end up taking quite a bit of time. I ran a profiler on som code and discovered that 50% of the time was spent in the date function in this error handler.
Anonymous ¶
17 years ago
When configuring your error log file in php.ini, you can use an absolute path or a relative path. A relative path will be resolved based on the location of the generating script, and you'll get a log file in each directory you have scripts in. If you want all your error messages to go to the same file, use an absolute path to the file.
In some application development methodologies, there is the concept of an application root directory, indicated by "/" (even on Windows). However, PHP does not seem to have this concept, and using a "/" as the initial character in a log file path produces weird behavior on Windows.
If you are running on Windows and have set, in php.ini:
error_log = "/php_error.log"
You will get some, but not all, error messages. The file will appear at
c:php_error.log
and contain internally generated error messages, making it appear that error logging is working. However, log messages requested by error_log() do NOT appear here, or anywhere else, making it appear that the code containing them did not get processed.
Apparently on Windows the internally generated errors will interpret "/" as "C:" (or possibly a different drive if you have Windows installed elsewhere - I haven't tested this). However, the error_log process apparently can't find "/" - understandably enough - and the message is dropped silently.
theotek AT nowhere DOT org ¶
16 years ago
It is totally possible to use debug_backtrace() inside an error handling function. Here, take a look:
<?php
set_error_handler('errorHandler');
function
errorHandler( $errno, $errstr, $errfile, $errline, $errcontext)
{
echo 'Into '.__FUNCTION__.'() at line '.__LINE__.
"nn---ERRNO---n". print_r( $errno, true).
"nn---ERRSTR---n". print_r( $errstr, true).
"nn---ERRFILE---n". print_r( $errfile, true).
"nn---ERRLINE---n". print_r( $errline, true).
"nn---ERRCONTEXT---n".print_r( $errcontext, true).
"nnBacktrace of errorHandler()n".
print_r( debug_backtrace(), true);
}
function
a( )
{
//echo "a()'s backtracen".print_r( debug_backtrace(), true);
asdfasdf; // oops
}
function
b()
{
//echo "b()'s backtracen".print_r( debug_backtrace(), true);
a();
}b();
?>
Outputs:
<raw>
Into errorhandler() at line 9
---ERRNO---
8
---ERRSTR---
Use of undefined constant asdfasdf - assumed 'asdfasdf'
---ERRFILE---
/home/theotek/test-1.php
---ERRLINE---
23
---ERRCONTEXT---
Array
(
)
Backtrace of errorHandler()
Array
(
[0] => Array
(
[function] => errorhandler
[args] => Array
(
[0] => 8
[1] => Use of undefined constant asdfasdf - assumed 'asdfasdf'
[2] => /home/theotek/test-1.php
[3] => 23
[4] => Array
(
)
)
)
[1] => Array
(
[file] => /home/theotek/test-1.php
[line] => 23
[function] => a
)
[2] => Array
(
[file] => /home/theotek/test-1.php
[line] => 30
[function] => a
[args] => Array
(
)
)
[3] => Array
(
[file] => /home/theotek/test-1.php
[line] => 33
[function] => b
[args] => Array
(
)
)
)
</raw>
So, the first member of the backtrace's array is not really surprising, except from the missing "file" and "line" members.
The second member of the backtrace seem the be a hook inside the zend engine that is used to trigger the error.
Other members are the normal backtrace.
jbq at caraldi dot com ¶
15 years ago
Precision about error_log when configured with syslog: the syslog() call is done with severity NOTICE.
petrov dot michael () gmail com ¶
16 years ago
I have found that on servers that enforce display_errors to be off it is very inconvenient to debug syntax errors since they cause fatal startup errors. I have used the following method to bypass this limitation:
The syntax error is inside the file "syntax.php", therefore I create a file "syntax.debug.php" with the following code:
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
include(
'syntax.php');
?>
The 5 line file is guaranteed to be free of errors, allowing PHP to execute the directives within it before including the file which previously caused fatal startup errors. Now those fatal startup errors become run time fatal errors.