-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
PHP Version
8.0
CodeIgniter4 Version
4.1.8
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
apache
Database
No response
What happened?
If for some reason the application has already sent headers it causes another error in the exception handler and fails to properly handle this circumstance. This allows php to output error in production environment.
Steps to Reproduce
In a controller add the following lines:
echo 'Some output<br>';
flush();
setcookie("printer", 37);
return;Expected Output
It is expected to receive an error that you cannot modify headers because they are already sent.
However if in production or development environments the error is dumped by php as well as an additional similar error caused in the call to header() in CodeIgniter\Debug\Exceptions::exceptionHandler()
if (! is_cli()) {
$this->response->setStatusCode($statusCode);
header(sprintf('HTTP/%s %s %s', $this->request->getProtocolVersion(), $this->response->getStatusCode(), $this->response->getReasonPhrase()), true, $statusCode);
if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) {
$this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send();
exit($exitCode);
}
}The screen as well as log files show:
CRITICAL - 2022-02-11 11:32:34 --> Cannot modify header information - headers already sent
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 16)
#1 C:\xampp\portal\app\Controllers\Admin\Test.php(16): setcookie('printer', '37')
#2 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(825): App\Controllers\Admin\Test->index()
#3 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(412): CodeIgniter\CodeIgniter->runController(Object(App\Controllers\Admin\Test))
#4 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(320): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#5 C:\xampp\portal\public\index.php(79): CodeIgniter\CodeIgniter->run()
#6 {main}
CRITICAL - 2022-02-11 11:32:34 --> Uncaught ErrorException: Cannot modify header information - headers already sent in C:\xampp\portal\vendor\codeigniter4\framework\system\Debug\Exceptions.php:115
Stack trace:
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 115)
#1 C:\xampp\portal\vendor\codeigniter4\framework\system\Debug\Exceptions.php(115): header('HTTP/1.1 500 In...', true, 500)
#2 [internal function]: CodeIgniter\Debug\Exceptions->exceptionHandler(Object(ErrorException))
#3 {main}
thrown
#0 [internal function]: CodeIgniter\Debug\Exceptions->shutdownHandler()
#1 {main}
Anything else?
Its a messy situation I know.. Not sure the best way to handle it. If we suppress the second error by using @Header() at least the page will continue to render in development and in production will render error page instead of outputting errors.
if (! is_cli()) {
$this->response->setStatusCode($statusCode);
@header(sprintf('HTTP/%s %s %s', $this->request->getProtocolVersion(), $this->response->getStatusCode(), $this->response->getReasonPhrase()), true, $statusCode);
if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) {
$this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send();
exit($exitCode);
}
} Then our log outputs only the first error:
CRITICAL - 2022-02-11 11:52:34 --> Cannot modify header information - headers already sent
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 16)
#1 C:\xampp\portal\app\Controllers\Admin\Test.php(16): setcookie('printer', '37')
#2 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(825): App\Controllers\Admin\Test->index()
#3 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(412): CodeIgniter\CodeIgniter->runController(Object(App\Controllers\Admin\Test))
#4 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(320): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#5 C:\xampp\portal\public\index.php(79): CodeIgniter\CodeIgniter->run()
#6 {main}