Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Daemon 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 Daemon, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class Daemon |
||
18 | { |
||
19 | use \PHPDaemon\Traits\ClassWatchdog; |
||
20 | use \PHPDaemon\Traits\StaticObjectWatchdog; |
||
21 | |||
22 | /** |
||
23 | * Support of runkit sandbox functionality |
||
24 | * @var integer |
||
25 | */ |
||
26 | const SUPPORT_RUNKIT_SANDBOX = 0; |
||
27 | |||
28 | /** |
||
29 | * Support of runkit on-the-fly userland code modification functionality |
||
30 | * @var integer |
||
31 | */ |
||
32 | const SUPPORT_RUNKIT_MODIFY = 1; |
||
33 | |||
34 | /** |
||
35 | * Support of runkit on-the-fly internal code modification functionality |
||
36 | * @var integer |
||
37 | */ |
||
38 | const SUPPORT_RUNKIT_INTERNAL_MODIFY = 2; |
||
39 | |||
40 | /** |
||
41 | * Support of runkit on-the-fly userland code import functionality |
||
42 | * @var integer |
||
43 | */ |
||
44 | const SUPPORT_RUNKIT_IMPORT = 3; |
||
45 | |||
46 | /** |
||
47 | * Worker state: idle. It means that the worker IS NOT in the middle of execution valuable callback (e.g. request) at this moment of time. Currently, it does not mean that worker not have any pending operations. |
||
48 | * @var integer |
||
49 | */ |
||
50 | const WSTATE_IDLE = 1; |
||
51 | |||
52 | /** |
||
53 | * Worker state: busy. It means that the worker IS in the middle of execution valuable callback. |
||
54 | */ |
||
55 | const WSTATE_BUSY = 2; |
||
56 | |||
57 | /** |
||
58 | * Worker state: shutdown. It means that worker is shutdown. Nothing special. |
||
59 | * @var integer |
||
60 | */ |
||
61 | const WSTATE_SHUTDOWN = 3; |
||
62 | |||
63 | /** |
||
64 | * Worker state: shutdown. It means that worker is shutdown. |
||
65 | * @var integer |
||
66 | */ |
||
67 | const WSTATE_PREINIT = 4; |
||
68 | |||
69 | /** |
||
70 | * Worker state: initialization. It means that worker is starting right now. |
||
71 | * @var integer |
||
72 | */ |
||
73 | const WSTATE_INIT = 5; |
||
74 | |||
75 | /** |
||
76 | * Hash of possible worker states |
||
77 | * @var array |
||
78 | */ |
||
79 | public static $wstateRev = [ |
||
80 | 1 => 'IDLE', |
||
81 | 2 => 'BUSY', |
||
82 | 3 => 'SHUTDOWN', |
||
83 | 4 => 'PREINIT', |
||
84 | 5 => 'INIT', |
||
85 | ]; |
||
86 | |||
87 | /** |
||
88 | * Shared memory WSTATE segment size |
||
89 | * @var integer |
||
90 | */ |
||
91 | const SHM_WSTATE_SIZE = 1024; |
||
92 | |||
93 | /** |
||
94 | * PHPDaemon version |
||
95 | * @var string |
||
96 | */ |
||
97 | public static $version; |
||
98 | |||
99 | /** |
||
100 | * PHPDaemon start time |
||
101 | * @var integer |
||
102 | */ |
||
103 | public static $startTime; |
||
104 | |||
105 | /** |
||
106 | * Log file resource |
||
107 | * @var resource |
||
108 | */ |
||
109 | public static $logpointer; |
||
110 | |||
111 | /** |
||
112 | * Log file async. resource |
||
113 | * @var object |
||
114 | */ |
||
115 | public static $logpointerAsync; |
||
116 | |||
117 | /** |
||
118 | * Supported things array |
||
119 | * @var string |
||
120 | */ |
||
121 | protected static $support = []; |
||
122 | |||
123 | /** |
||
124 | * Current thread object |
||
125 | * @var \PHPDaemon\Thread\Master|\PHPDaemon\Thread\IPC|\PHPDaemon\Thread\Worker |
||
126 | */ |
||
127 | public static $process; |
||
128 | |||
129 | /** |
||
130 | * AppResolver |
||
131 | * @var \PHPDaemon\Core\AppResolver |
||
132 | */ |
||
133 | public static $appResolver; |
||
134 | |||
135 | /** |
||
136 | * Running application instances |
||
137 | * @var array |
||
138 | */ |
||
139 | public static $appInstances = []; |
||
140 | |||
141 | /** |
||
142 | * Running request |
||
143 | * @var \PHPDaemon\Request\Generic |
||
144 | */ |
||
145 | public static $req; |
||
146 | |||
147 | /** |
||
148 | * Running context |
||
149 | * @var object |
||
150 | */ |
||
151 | public static $context; |
||
152 | |||
153 | /** |
||
154 | * Collection of workers |
||
155 | * @var \PHPDaemon\Thread\Collection |
||
156 | */ |
||
157 | protected static $workers; |
||
158 | |||
159 | /** |
||
160 | * Collection of masters |
||
161 | * @var \PHPDaemon\Thread\Collection |
||
162 | */ |
||
163 | protected static $masters; |
||
164 | |||
165 | /** |
||
166 | * Copy of $_SERVER on the daemon start |
||
167 | * @var array |
||
168 | */ |
||
169 | protected static $initservervar; |
||
170 | |||
171 | /** |
||
172 | * Shared memory 'WSTATE' entity |
||
173 | * @var ShmEntity |
||
174 | */ |
||
175 | public static $shm_wstate; |
||
176 | |||
177 | /** |
||
178 | * Running under Apache/PHP-FPM in compatibility mode? |
||
179 | * @var boolean |
||
180 | */ |
||
181 | public static $compatMode = false; |
||
182 | |||
183 | /** |
||
184 | * Base name of daemon instance |
||
185 | * @var string |
||
186 | */ |
||
187 | public static $runName = 'phpdaemon'; |
||
188 | |||
189 | /** |
||
190 | * Configuration object |
||
191 | * @var \PHPDaemon\Config\_Object |
||
192 | */ |
||
193 | public static $config; |
||
194 | |||
195 | /** |
||
196 | * Path to application resolver |
||
197 | * @var string |
||
198 | */ |
||
199 | public static $appResolverPath; |
||
200 | |||
201 | |||
202 | /** |
||
203 | * Restrict error control. When true, operator '@' means nothing. |
||
204 | * @var boolean |
||
205 | */ |
||
206 | public static $restrictErrorControl = false; |
||
207 | |||
208 | /** |
||
209 | * Default error reporting level |
||
210 | * @var integer |
||
211 | */ |
||
212 | public static $defaultErrorLevel; |
||
213 | |||
214 | /** |
||
215 | * Is it running under master-less 'runworker' mode? |
||
216 | * @var bool |
||
217 | */ |
||
218 | public static $runworkerMode = false; |
||
219 | |||
220 | /** |
||
221 | * Whether if the current execution stack contains ob-filter |
||
222 | * @var bool |
||
223 | */ |
||
224 | public static $obInStack = false; |
||
225 | |||
226 | /** |
||
227 | * Mechanism of catching errors. Set it to true, then run your suspect code, and then check this property again. If false, there was error message. |
||
228 | * @var bool |
||
229 | */ |
||
230 | public static $noError = false; |
||
231 | |||
232 | /** |
||
233 | * Loads default setting. |
||
234 | * @return void |
||
235 | */ |
||
236 | public static function initSettings() |
||
247 | |||
248 | /** |
||
249 | * Glob function with support of include_path |
||
250 | * @param string $pattern |
||
251 | * @param int $flags |
||
252 | * @return array |
||
253 | */ |
||
254 | public static function glob($pattern, $flags = 0) |
||
262 | |||
263 | /** |
||
264 | * Generate a unique ID. |
||
265 | * @return string Returns the unique identifier, as a string. |
||
266 | */ |
||
267 | public static function uniqid() |
||
280 | |||
281 | /** |
||
282 | * Load PHP extension (module) if absent |
||
283 | * @param string $mod |
||
284 | * @param string $version |
||
|
|||
285 | * @param string $compare |
||
286 | * @return bool $success |
||
287 | */ |
||
288 | public static function loadModuleIfAbsent($mod, $version = null, $compare = '>=') |
||
308 | |||
309 | /** |
||
310 | * Call automatic garbage collector |
||
311 | * @return void |
||
312 | */ |
||
313 | public static function callAutoGC() |
||
319 | |||
320 | /** |
||
321 | * Check if we need to run automatic garbage collector |
||
322 | * @return bool |
||
323 | */ |
||
324 | public static function checkAutoGC() |
||
335 | |||
336 | /** |
||
337 | * Output filter |
||
338 | * @return string Output |
||
339 | */ |
||
340 | public static function outputFilter($s) |
||
358 | |||
359 | /** |
||
360 | * Uncaught exception handler |
||
361 | * @param \Throwable $e |
||
362 | * @return void |
||
363 | */ |
||
364 | public static function uncaughtExceptionHandler(\Throwable $e) |
||
377 | |||
378 | /** |
||
379 | * Error handler |
||
380 | * @param integer $errno |
||
381 | * @param string $errstr |
||
382 | * @param string $errfile |
||
383 | * @param integer $errline |
||
384 | * @param array $errcontext |
||
385 | */ |
||
386 | public static function errorHandler($errno, $errstr, $errfile, $errline, $errcontext = []) |
||
418 | |||
419 | /** |
||
420 | * Performs initial actions. |
||
421 | * @return void |
||
422 | */ |
||
423 | public static function init(bool $master = true) |
||
448 | |||
449 | /** |
||
450 | * Is thing supported |
||
451 | * @param integer $what Thing to check |
||
452 | * @return boolean |
||
453 | */ |
||
454 | public static function supported($what) |
||
458 | |||
459 | /** |
||
460 | * Method to fill $support array |
||
461 | * @return void |
||
462 | */ |
||
463 | protected static function checkSupports() |
||
481 | |||
482 | /** |
||
483 | * Check file syntax via runkit_lint_file if supported or via php -l |
||
484 | * @param string File name |
||
485 | * @return boolean |
||
486 | */ |
||
487 | public static function lintFile($filename) |
||
504 | |||
505 | /** |
||
506 | * It allows to run your simple web-apps in spawn-fcgi/php-fpm environment. |
||
507 | * @return boolean|null - Success. |
||
508 | */ |
||
509 | public static function compatRunEmul() |
||
566 | |||
567 | /** |
||
568 | * Load config-file |
||
569 | * @param string $paths Path |
||
570 | * @return boolean - Success. |
||
571 | */ |
||
572 | public static function loadConfig($paths) |
||
589 | |||
590 | /** |
||
591 | * Open logs |
||
592 | * @return void |
||
593 | */ |
||
594 | public static function openLogs() |
||
619 | |||
620 | /** |
||
621 | * Get state of workers. |
||
622 | * @return array - information. |
||
623 | */ |
||
624 | public static function getStateOfWorkers() |
||
683 | |||
684 | /** |
||
685 | * Send message to the log |
||
686 | * |
||
687 | * @param array ...$args |
||
688 | */ |
||
689 | public static function log(...$args) |
||
712 | |||
713 | /** |
||
714 | * Spawn a master process |
||
715 | * @return null|integer - success |
||
716 | */ |
||
717 | public static function spawnMaster() |
||
729 | |||
730 | /** |
||
731 | * Run worker thread |
||
732 | * @return void |
||
733 | */ |
||
734 | public static function runWorker() |
||
740 | } |
||
741 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.