40

Summary

Amazingly I could find nothing about this on Google or SO. When I throw an exception in PHP it appears in my console twice, complete with error message and stack trace. The first time it's printed it says "PHP Fatal error: ..." and the second time it just says "Fatal error: ...". I haven't tested this is the Apache plugin version.

Example

With some namespaces and paths shortened with '...' for safety:

$ php code/com/.../tabular_data.php
PHP Fatal error:  Uncaught exception 'Exception' with message 'File type not supported' in /home/codemonkey/.../tabular_data.php:56
Stack trace:
#0 /home/codemonkey/.../tabular_data.php(88): com\...\Tabular_Data->loadFromFile('/home/codemonke...', false)
#1 /home/codemonkey/.../tabular_data.php(95): com\...\Tabular_Data::fromFile('/home/codemonke...')
#2 {main}
  thrown in /home/codemonkey/.../tabular_data.php on line 56

Fatal error: Uncaught exception 'Exception' with message 'File type not supported' in /home/codemonkey/.../tabular_data.php:56
Stack trace:
#0 /home/codemonkey/.../tabular_data.php(88): com\...\Tabular_Data->loadFromFile('/home/codemonke...', false)
#1 /home/codemonkey/.../tabular_data.php(95): com\...\Tabular_Data::fromFile('/home/codemonke...')
#2 {main}
  thrown in /home/codemonkey/.../tabular_data.php on line 56

Question

I assume it has something to do with stderr and stdout both printing the error. In any case how do I ask PHP nicely to only print it once, preferably to stderr?


Version output

PHP 5.3.9 (cli) (built: Jan 11 2012 17:09:48)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

The code

http://pastebin.com/iBUGJ2eY
This is the exact code that displays double exceptions for me, with namespaces and paths edited to foos. Note that I always get double exceptions in the command line on this installation. I'm all but certain that the issue lies in the PHP configuration.

Hubro
  • 56,214
  • 69
  • 228
  • 381
  • 2
    Any custom error handlers involved? Using `5.3.9-1~dotdeb.3` I can't seem to reproduce this by just throwing an exception. I only get the second message. – Linus Kleen Jan 25 '12 at 11:34
  • Do you have any custom error handlers defined? Are you redirecting error outputs or something like that? Please show a minimal, complete script that reproduces this problem. – deceze Jan 25 '12 at 11:34
  • The code in question is a class definition and a class instantiation. The exceptions occur during instantiation. There's nothing fancy in this code yet. Just in case you can [check it out here](http://pastebin.com/iBUGJ2eY). It's impressively unimpressive and short. Out of curiosity I ran `echo ini_get('error_reporting');` and got *32767*. What's that about? Isn't that supposed to return a string like *E_ALL*? – Hubro Jan 25 '12 at 11:55
  • 1
    `E_ALL` is just a bitmask of `E_NOTICE`, `E_WARNING` etc. Try `print E_ALL`; you'll get a number, because it's just a constant. – Linus Kleen Jan 25 '12 at 12:02

2 Answers2

52

Got it reproduced. The first error message is a result of the log_errors setting and goes to STDERR.

The second is a result of display_errors and goes to STDOUT.

Both settings can be altered during runtime. So in order to "ask PHP nicely", this suffices:

ini_set('log_errors', 1);
ini_set('display_errors', 0);
Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
  • 5
    this reminds me of the article "PHP: a fractal of bad design" http://t.co/ytXaNjV – Taras Oct 02 '12 at 10:54
  • THX, that was the half of the answer I needed. I added an own answer to complete your informations ;) – Radon8472 Dec 04 '19 at 13:04
  • If I set `ini_set('log_errors', 1);` and `ini_set('display_errors', 0);` and I run my PHP script throwing an exception from the CLI, I don't see any output. The uncaught exception message is outputted twice on the stdout. Any idea? Thank you! – tonix Oct 05 '20 at 21:52
  • 1
    You _don't_ see anything or it's displayed twice? Which is it? – Linus Kleen Nov 02 '20 at 21:40
1

Like written in the answer of Linus Kleen the reason for the double messages is that the display_errors go to stdout. I found out that since php 5.2.4 this even happens when display_errors is set to 1 or "on".

To restore the normal behavoir it is the best way to define file where logged errors should be stored e.g. add this:

error_log = 'd:/logs/php_error.log'

to your php.ini. When the file for error_log is defined, you get only one message to stdout what you would need for testing. And for production state you can set display_errors to 0.

Radon8472
  • 4,285
  • 1
  • 33
  • 41