3636use Kint \Renderer \RichRenderer ;
3737use Locale ;
3838use LogicException ;
39+ use Throwable ;
3940
4041/**
4142 * This class is the core of the framework, and will analyse the
@@ -164,6 +165,11 @@ class CodeIgniter
164165 */
165166 protected bool $ returnResponse = false ;
166167
168+ /**
169+ * Application output buffering level
170+ */
171+ protected int $ bufferLevel ;
172+
167173 /**
168174 * Constructor.
169175 */
@@ -367,6 +373,7 @@ public function run(?RouteCollectionInterface $routes = null, bool $returnRespon
367373 try {
368374 return $ this ->handleRequest ($ routes , $ cacheConfig , $ returnResponse );
369375 } catch (RedirectException $ e ) {
376+ $ this ->outputBufferingEnd ();
370377 $ logger = Services::logger ();
371378 $ logger ->info ('REDIRECTED ROUTE at ' . $ e ->getMessage ());
372379
@@ -389,6 +396,10 @@ public function run(?RouteCollectionInterface $routes = null, bool $returnRespon
389396 if ($ return instanceof ResponseInterface) {
390397 return $ return ;
391398 }
399+ } catch (Throwable $ e ) {
400+ $ this ->outputBufferingEnd ();
401+
402+ throw $ e ;
392403 }
393404 }
394405
@@ -810,7 +821,7 @@ protected function tryToRouteIt(?RouteCollectionInterface $routes = null)
810821 $ this ->benchmark ->stop ('bootstrap ' );
811822 $ this ->benchmark ->start ('routing ' );
812823
813- ob_start ();
824+ $ this -> outputBufferingStart ();
814825
815826 $ this ->controller = $ this ->router ->handle ($ path );
816827 $ this ->method = $ this ->router ->methodName ();
@@ -979,15 +990,8 @@ protected function display404errors(PageNotFoundException $e)
979990 // Display 404 Errors
980991 $ this ->response ->setStatusCode ($ e ->getCode ());
981992
982- if (ENVIRONMENT !== 'testing ' ) {
983- if (ob_get_level () > 0 ) {
984- ob_end_flush (); // @codeCoverageIgnore
985- }
986- }
987- // When testing, one is for phpunit, another is for test case.
988- elseif (ob_get_level () > 2 ) {
989- ob_end_flush (); // @codeCoverageIgnore
990- }
993+ echo $ this ->outputBufferingEnd ();
994+ flush ();
991995
992996 // Throws new PageNotFoundException and remove exception message on production.
993997 throw PageNotFoundException::forPageNotFound (
@@ -1006,21 +1010,9 @@ protected function display404errors(PageNotFoundException $e)
10061010 */
10071011 protected function gatherOutput (?Cache $ cacheConfig = null , $ returned = null )
10081012 {
1009- $ this ->output = ob_get_contents ();
1010- // If buffering is not null.
1011- // Clean (erase) the output buffer and turn off output buffering
1012- if (ob_get_length ()) {
1013- ob_end_clean ();
1014- }
1013+ $ this ->output = $ this ->outputBufferingEnd ();
10151014
10161015 if ($ returned instanceof DownloadResponse) {
1017- // Turn off output buffering completely, even if php.ini output_buffering is not off
1018- if (ENVIRONMENT !== 'testing ' ) {
1019- while (ob_get_level () > 0 ) {
1020- ob_end_clean ();
1021- }
1022- }
1023-
10241016 $ this ->response = $ returned ;
10251017
10261018 return ;
@@ -1150,4 +1142,22 @@ public function setContext(string $context)
11501142
11511143 return $ this ;
11521144 }
1145+
1146+ protected function outputBufferingStart (): void
1147+ {
1148+ $ this ->bufferLevel = ob_get_level ();
1149+ ob_start ();
1150+ }
1151+
1152+ protected function outputBufferingEnd (): string
1153+ {
1154+ $ buffer = '' ;
1155+
1156+ while (ob_get_level () > $ this ->bufferLevel ) {
1157+ $ buffer = ob_get_contents ();
1158+ ob_end_clean ();
1159+ }
1160+
1161+ return $ buffer ;
1162+ }
11531163}
0 commit comments