filp / whoops

PHP errors for cool kids
http://filp.github.io/whoops/
MIT License
13.18k stars 603 forks source link

Running php from cli, Whoop does not show the file, where first output or headers sent. #629

Open arnisjuraga opened 5 years ago

arnisjuraga commented 5 years ago

Reproduce:

Tested PHP version: 7.2.19, 7.3.6, Whoops version: 2.3.1

I recently missed "space" into some configuration file. With Whoops turned off, php output shows:

php -r "include 'index.php';"
PHP Warning:  Cannot modify header information - headers already sent by (output started at /home/www/public_html/config/dev/database.php:1)

But with Whoops enabled, I have no idea, which file to blame:

PHP Fatal error:  Uncaught Whoops\Exception\ErrorException: session_set_save_handler(): Cannot change save handler when headers already sent in /home/www/public_html/system/library/session.php:19
Stack trace:
#0 [internal function]: Whoops\Run->handleError(2, 'session_set_sav...', '/home/www/publi...', 19, Array)
#1 /home/www/public_html/system/library/session.php(19): session_set_save_handler(Object(Session\Native))
#2 /home/www/public_html/system/framework.php(85): Session->__construct()
#3 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(764): {closure}(Object(Registry), Array)
#4 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(646): Illuminate\Container\Container->build(Object(Closure))
#5 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(601): Illuminate\Container\Container->resolve('session', Array)
#6 /home/www/publi in /home/www/public_html/system/library/session.php on line 19
Whoops\Exception\ErrorException: Uncaught Whoops\Exception\ErrorException: session_set_save_handler(): Cannot change save handler when headers already sent in /home/www/public_html/system/library/session.php:19
Stack trace:
#0 [internal function]: Whoops\Run->handleError(2, 'session_set_sav...', '/home/www/publi...', 19, Array)
#1 /home/www/public_html/system/library/session.php(19): session_set_save_handler(Object(Session\Native))
#2 /home/www/public_html/system/framework.php(85): Session->__construct()
#3 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(764): {closure}(Object(Registry), Array)
#4 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(646): Illuminate\Container\Container->build(Object(Closure))
#5 /home/www/public_html/vendor/laravel/framework/src/Illuminate/Container/Container.php(601): Illuminate\Container\Container->resolve('session', Array)
#6 /home/www/publi in file /home/www/public_html/system/library/session.php on line 19
Stack trace:
  1. Whoops\Exception\ErrorException->() /home/www/public_html/system/library/session.php:19

Is there something to be done?

denis-sokolov commented 5 years ago

Is the latter output after the same php -r "include 'index.php';" command?

arnisjuraga commented 5 years ago

Correct! Both outputs are from the same php -r "include 'index.php';"

One more example:

Whoops disabled:

server@user:~/public_html$ php -r "include 'index.php';" 2>&1 |grep database
PHP Warning:  Cannot modify header information - headers already sent by (output started at /public_html/config/dev/database.php:1) in /public_html/system/library/session.php on line 54
PHP Warning:  Cannot modify header information - headers already sent by (output started at /public_html/config/dev/database.php:1) in /public_html/system/library/session.php on line 54
PHP Warning:  Cannot modify header information - headers already sent by (output started at /public_html/config/dev/database.php:1) in /public_html/catalog/controller/startup/startup.php on line 139
PHP Warning:  Cannot modify header information - headers already sent by (output started at /public_html/config/dev/database.php:1) in /public_html/catalog/controller/startup/startup.php on line 222

With Whoops enabled - Output does not have anything about database.php:

server@user:~/public_html$ php -r "include 'index.php';" 2>&1 |grep database
server@user:~/public_html$
denis-sokolov commented 5 years ago

And that’s only in CLI, not if you run it through the HTTP server?

arnisjuraga commented 5 years ago

Yes, correct. The problem is with calling php from command line. Running the same script from WEB (nginx + php-fpm, to be honest, does not display ANY error or warning at all).

I had xdebug module enabled, I disabled it so output is a little bit different. But problem persists. Could it be some PHP specific? I noticed even more strange results.

So, I created test script. I have compared php.ini versions for both, php 7.0 and php 7.3 - did not notice any different settings regarding sessions or debug output. PHP 7.0 does display warning correctly but PHP 7.3 doesn't.

Test case - both, with Whoops disabled (let's narrow to vanila PHP):

Create arnis.php (it creates and includes 'bogus.php'. Tested with static files, result is the same):

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

file_put_contents('bogus.php', "<?php echo 'x'; ");
require_once "bogus.php";

session_start();

And here are 2 outputs from PHP 7.0

server@user:~/public_html$ /usr/bin/php7.0 -r "include 'arnis.php';"

server@user:~/public_html$ /usr/bin/php7.0 -r "include 'arnis.php';"
xPHP Warning:  session_start(): Cannot send session cookie - headers already sent by (output started at /public_html/bogus.php:1) in /public_html/arnis.php on line 9

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /public_html/bogus.php:1) in /public_html/arnis.php on line 9
PHP Warning:  session_start(): Cannot send session cache limiter - headers already sent (output started at /public_html/bogus.php:1) in /public_html/arnis.php on line 9

and PHP 7.3

server@user:~/public_html$ /usr/bin/php7.3 -r "include 'arnis.php';"
xPHP Warning:  session_start(): Cannot start session when headers already sent in /public_html/arnis.php on line 9

Warning: session_start(): Cannot start session when headers already sent in /public_html/arnis.php on line 9
denis-sokolov commented 5 years ago

Thanks for an extensive report. I don’t have a quick fix right now, hopefully we figure it out in time, let’s keep it open.

arnisjuraga commented 4 years ago

This is simple solution, how to check "Headers already sent" lines https://stackoverflow.com/a/31246850/1720476

Itach1Uchixa commented 1 year ago

Problem arises because of disabled output buffering of php. In php cli output buffering is disabled and can not be enabled in any way. But whoops relies on output buffering when handling exceptions