Complex classes like Handler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Handler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | class Handler { |
||
20 | |||
21 | const ERRORS_RECURSION_LIMIT = 3; |
||
22 | |||
23 | /** @var Handler */ |
||
24 | protected static $instance; |
||
25 | |||
26 | /** @var Connector */ |
||
27 | protected $connector; |
||
28 | protected $isStarted = false; |
||
29 | protected $isHandling = false; |
||
30 | protected $errorsHandlerLevel; |
||
31 | protected $handleErrors = true; |
||
32 | protected $handleExceptions = true; |
||
33 | protected $callOldHandlers = true; |
||
34 | protected $oldErrorsHandler; |
||
35 | protected $oldExceptionsHandler; |
||
36 | protected $recursiveHandlingLevel = 0; |
||
37 | |||
38 | /** |
||
39 | * @return static |
||
40 | */ |
||
41 | 22 | public static function getInstance() { |
|
47 | |||
48 | 1 | protected function __construct() { |
|
51 | |||
52 | /** |
||
53 | * @codeCoverageIgnore |
||
54 | */ |
||
55 | private final function __clone() { |
||
57 | |||
58 | /** |
||
59 | * Start errors & exceptions handlers |
||
60 | * @throws \Exception |
||
61 | */ |
||
62 | 16 | public function start() { |
|
75 | |||
76 | /** |
||
77 | * Validate that method is called before start. Required for handlers configuration methods. |
||
78 | * @throws \Exception |
||
79 | */ |
||
80 | 4 | protected function checkIsCalledBeforeStart() { |
|
85 | |||
86 | /** |
||
87 | * Enable or disable errors handler |
||
88 | * @param bool $isEnabled |
||
89 | */ |
||
90 | 1 | public function setHandleErrors($isEnabled) { |
|
94 | |||
95 | /** |
||
96 | * Enable or disable exceptions handler |
||
97 | * @param bool $isEnabled |
||
98 | */ |
||
99 | 1 | public function setHandleExceptions($isEnabled) { |
|
103 | |||
104 | /** |
||
105 | * Enable or disable calling overridden errors & exceptions |
||
106 | * @param bool $isEnabled |
||
107 | */ |
||
108 | 2 | public function setCallOldHandlers($isEnabled) { |
|
111 | |||
112 | /** |
||
113 | * @return Connector |
||
114 | */ |
||
115 | 2 | public function getConnector() { |
|
118 | |||
119 | /** |
||
120 | * Check if PHP Console handler is started |
||
121 | * @return bool |
||
122 | */ |
||
123 | public function isStarted() { |
||
126 | |||
127 | /** |
||
128 | * Override PHP exceptions handler to PHP Console handler |
||
129 | */ |
||
130 | 16 | protected function initExceptionsHandler() { |
|
133 | |||
134 | /** |
||
135 | * Set custom errors handler level like E_ALL ^ E_STRICT |
||
136 | * But, anyway, it's strongly recommended to configure ignore some errors type in PHP Console extension options |
||
137 | * IMPORTANT: previously old error handler will be called only with new errors level |
||
138 | * @param int $level see http://us1.php.net/manual/ru/function.error-reporting.php |
||
139 | */ |
||
140 | 2 | public function setErrorsHandlerLevel($level) { |
|
144 | |||
145 | /** |
||
146 | * Override PHP errors handler to PHP Console handler |
||
147 | */ |
||
148 | 16 | protected function initErrorsHandler() { |
|
155 | |||
156 | /** |
||
157 | * Method is called by register_shutdown_function(), it's required to handle fatal PHP errors. Never call it manually. |
||
158 | * @codeCoverageIgnore |
||
159 | */ |
||
160 | public function checkFatalErrorOnShutDown() { |
||
168 | |||
169 | /** |
||
170 | * Handle error data |
||
171 | * @param int|null $code |
||
172 | * @param string|null $text |
||
173 | * @param string|null $file |
||
174 | * @param int|null $line |
||
175 | * @param null $context |
||
176 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore |
||
177 | */ |
||
178 | 7 | public function handleError($code = null, $text = null, $file = null, $line = null, $context = null, $ignoreTraceCalls = 0) { |
|
189 | |||
190 | /** |
||
191 | * Method is called before handling any error or exception |
||
192 | */ |
||
193 | 9 | protected function onHandlingStart() { |
|
196 | |||
197 | /** |
||
198 | * Method is called after handling any error or exception |
||
199 | */ |
||
200 | 9 | protected function onHandlingComplete() { |
|
203 | |||
204 | /** |
||
205 | * Check if errors/exception handling is disabled |
||
206 | * @return bool |
||
207 | */ |
||
208 | 10 | protected function isHandlingDisabled() { |
|
211 | |||
212 | /** |
||
213 | * Handle exception object |
||
214 | * @param \Exception|\Throwable $exception |
||
215 | */ |
||
216 | 5 | public function handleException($exception) { |
|
235 | |||
236 | /** |
||
237 | * Handle debug data |
||
238 | * @param mixed $data |
||
239 | * @param string|null $tags Tags separated by dot, e.g. "low.db.billing" |
||
240 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore |
||
241 | */ |
||
242 | 1 | public function debug($data, $tags = null, $ignoreTraceCalls = 0) { |
|
247 | } |
||
248 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.