1919use function ini_set ;
2020use function http_response_code ;
2121use function register_shutdown_function ;
22- use function restore_error_handler ;
23- use function restore_exception_handler ;
2422use function set_error_handler ;
2523use function set_exception_handler ;
2624use function str_repeat ;
2725
2826/**
29- * ErrorHandler handles out of memory errors, fatals, warnings, notices and exceptions.
27+ * ` ErrorHandler` handles out of memory errors, fatals, warnings, notices and exceptions.
3028 */
3129final class ErrorHandler
3230{
@@ -40,6 +38,8 @@ final class ErrorHandler
4038 private string $ memoryReserve = '' ;
4139 private bool $ debug = false ;
4240 private ?string $ workingDirectory = null ;
41+ private bool $ enabled = false ;
42+ private bool $ initialized = false ;
4343
4444 private LoggerInterface $ logger ;
4545 private ThrowableRendererInterface $ defaultRenderer ;
@@ -106,22 +106,35 @@ public function memoryReserveSize(int $size): void
106106 }
107107
108108 /**
109- * Register this error handler.
109+ * Register PHP exception and error handlers and enable this error handler.
110110 */
111111 public function register (): void
112112 {
113- // Disables the display of error.
114- if (function_exists ('ini_set ' )) {
115- ini_set ('display_errors ' , '0 ' );
113+ if ($ this ->enabled ) {
114+ return ;
115+ }
116+
117+ if ($ this ->memoryReserveSize > 0 ) {
118+ $ this ->memoryReserve = str_repeat ('x ' , $ this ->memoryReserveSize );
116119 }
117120
121+ $ this ->initializeOnce ();
122+
118123 // Handles throwable, echo output and exit.
119124 set_exception_handler (function (Throwable $ t ): void {
125+ if (!$ this ->enabled ) {
126+ return ;
127+ }
128+
120129 $ this ->renderThrowableAndTerminate ($ t );
121130 });
122131
123132 // Handles PHP execution errors such as warnings and notices.
124- set_error_handler (static function (int $ severity , string $ message , string $ file , int $ line ): bool {
133+ set_error_handler (function (int $ severity , string $ message , string $ file , int $ line ): bool {
134+ if (!$ this ->enabled ) {
135+ return false ;
136+ }
137+
125138 if (!(error_reporting () & $ severity )) {
126139 // This error code is not included in error_reporting.
127140 return true ;
@@ -130,12 +143,40 @@ public function register(): void
130143 throw new ErrorException ($ message , $ severity , $ severity , $ file , $ line );
131144 });
132145
133- if ($ this ->memoryReserveSize > 0 ) {
134- $ this ->memoryReserve = str_repeat ('x ' , $ this ->memoryReserveSize );
146+ $ this ->enabled = true ;
147+ }
148+
149+ /**
150+ * Disable this error handler.
151+ */
152+ public function unregister (): void
153+ {
154+ if (!$ this ->enabled ) {
155+ return ;
156+ }
157+
158+ $ this ->memoryReserve = '' ;
159+
160+ $ this ->enabled = false ;
161+ }
162+
163+ private function initializeOnce (): void
164+ {
165+ if ($ this ->initialized ) {
166+ return ;
167+ }
168+
169+ // Disables the display of error.
170+ if (function_exists ('ini_set ' )) {
171+ ini_set ('display_errors ' , '0 ' );
135172 }
136173
137174 // Handles fatal error.
138175 register_shutdown_function (function (): void {
176+ if (!$ this ->enabled ) {
177+ return ;
178+ }
179+
139180 $ this ->memoryReserve = '' ;
140181 $ e = error_get_last ();
141182
@@ -148,15 +189,8 @@ public function register(): void
148189 if (!(PHP_SAPI === 'cli ' || PHP_SAPI === 'phpdbg ' )) {
149190 $ this ->workingDirectory = getcwd ();
150191 }
151- }
152192
153- /**
154- * Unregisters this error handler by restoring the PHP error and exception handlers.
155- */
156- public function unregister (): void
157- {
158- restore_error_handler ();
159- restore_exception_handler ();
193+ $ this ->initialized = true ;
160194 }
161195
162196 /**
@@ -178,6 +212,7 @@ private function renderThrowableAndTerminate(Throwable $t): void
178212 if ($ this ->eventDispatcher !== null ) {
179213 $ this ->eventDispatcher ->dispatch (new ApplicationError ($ t ));
180214 }
215+
181216 register_shutdown_function (static function (): void {
182217 exit (1 );
183218 });
0 commit comments