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 File 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 File, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class File |
||
14 | { |
||
15 | use \PHPDaemon\Traits\ClassWatchdog; |
||
16 | use \PHPDaemon\Traits\StaticObjectWatchdog; |
||
17 | |||
18 | /** |
||
19 | * @var integer Priority |
||
20 | */ |
||
21 | public $priority = 10; |
||
22 | |||
23 | /** |
||
24 | * @var integer Chunk size |
||
25 | */ |
||
26 | public $chunkSize = 4096; |
||
27 | |||
28 | /** |
||
29 | * @var string $stat hash Stat |
||
30 | */ |
||
31 | protected $stat; |
||
32 | |||
33 | /** |
||
34 | * @var array Cache of statvfs() |
||
35 | */ |
||
36 | protected $statvfs; |
||
37 | |||
38 | /** |
||
39 | * @var integer Current offset |
||
40 | */ |
||
41 | public $offset = 0; |
||
42 | |||
43 | /** |
||
44 | * @var string Cache key |
||
45 | */ |
||
46 | public $fdCacheKey; |
||
47 | |||
48 | /** |
||
49 | * @var boolean Append? |
||
50 | */ |
||
51 | public $append; |
||
52 | |||
53 | /** |
||
54 | * @var string Path |
||
55 | */ |
||
56 | public $path; |
||
57 | |||
58 | /** |
||
59 | * @var boolean Writing? |
||
60 | */ |
||
61 | public $writing = false; |
||
62 | |||
63 | /** |
||
64 | * @var boolean Closed? |
||
65 | */ |
||
66 | public $closed = false; |
||
67 | |||
68 | /** |
||
69 | * @var object File descriptor |
||
70 | */ |
||
71 | protected $fd; |
||
72 | |||
73 | /** |
||
74 | * @var PHPDaemon\Structures\StackCallbacks Stack of callbacks called when writing is done |
||
75 | */ |
||
76 | protected $onWriteOnce; |
||
77 | |||
78 | /** |
||
79 | * File constructor |
||
80 | * @param resource $fd Descriptor |
||
81 | * @param string $path Path |
||
82 | */ |
||
83 | public function __construct($fd, $path) |
||
89 | |||
90 | /** |
||
91 | * Get file descriptor |
||
92 | * @return resource File descriptor |
||
93 | */ |
||
94 | public function getFd() |
||
98 | |||
99 | /** |
||
100 | * Converts string of flags to integer or standard text representation |
||
101 | * @param string $mode Mode |
||
102 | * @param boolean $text Text? |
||
103 | * @return mixed |
||
104 | */ |
||
105 | public static function convertFlags($mode, $text = false) |
||
126 | |||
127 | /** |
||
128 | * Truncates this file |
||
129 | * @param integer $offset Offset. Default is 0 |
||
130 | * @param callable $cb Callback |
||
131 | * @param integer $pri Priority |
||
132 | * @return resource|boolean |
||
133 | */ |
||
134 | View Code Duplication | public function truncate($offset = 0, $cb = null, $pri = EIO_PRI_DEFAULT) |
|
153 | |||
154 | /** |
||
155 | * Stat() |
||
156 | * @param callable $cb Callback |
||
157 | * @param integer $pri Priority |
||
158 | * @return resource|boolean |
||
159 | */ |
||
160 | public function stat($cb, $pri = EIO_PRI_DEFAULT) |
||
183 | |||
184 | /** |
||
185 | * Stat() non-cached |
||
186 | * @param callable $cb Callback |
||
187 | * @param integer $pri Priority |
||
188 | * @return resource|boolean |
||
189 | */ |
||
190 | public function statRefresh($cb, $pri = EIO_PRI_DEFAULT) |
||
209 | |||
210 | /** |
||
211 | * Statvfs() |
||
212 | * @param callable $cb Callback |
||
213 | * @param integer $pri Priority |
||
214 | * @return resource|boolean |
||
215 | */ |
||
216 | public function statvfs($cb, $pri = EIO_PRI_DEFAULT) |
||
240 | |||
241 | /** |
||
242 | * Sync() |
||
243 | * @param callable $cb Callback |
||
244 | * @param integer $pri Priority |
||
245 | * @return resource|false |
||
246 | */ |
||
247 | View Code Duplication | public function sync($cb, $pri = EIO_PRI_DEFAULT) |
|
262 | |||
263 | /** |
||
264 | * Datasync() |
||
265 | * @param callable $cb Callback |
||
266 | * @param integer $pri Priority |
||
267 | * @return resource|false |
||
268 | */ |
||
269 | View Code Duplication | public function datasync($cb, $pri = EIO_PRI_DEFAULT) |
|
284 | |||
285 | /** |
||
286 | * Writes data to file |
||
287 | * @param string $data Data |
||
288 | * @param callable $cb Callback |
||
289 | * @param integer $offset Offset |
||
290 | * @param integer $pri Priority |
||
291 | * @return resource|false |
||
292 | */ |
||
293 | public function write($data, $cb = null, $offset = null, $pri = EIO_PRI_DEFAULT) |
||
341 | |||
342 | /** |
||
343 | * Changes ownership of this file |
||
344 | * @param integer $uid User ID |
||
345 | * @param integer $gid Group ID |
||
346 | * @param callable $cb = null Callback |
||
347 | * @param integer $pri = EIO_PRI_DEFAULT Priority |
||
348 | * @return resource|false |
||
349 | */ |
||
350 | View Code Duplication | public function chown($uid, $gid = -1, $cb = null, $pri = EIO_PRI_DEFAULT) |
|
371 | |||
372 | /** |
||
373 | * touch() |
||
374 | * @param integer $mtime Last modification time |
||
375 | * @param integer $atime Last access time |
||
376 | * @param callable $cb Callback |
||
377 | * @param integer $pri Priority |
||
378 | * @return resource|false |
||
379 | */ |
||
380 | public function touch($mtime, $atime = null, $cb = null, $pri = EIO_PRI_DEFAULT) |
||
398 | |||
399 | /** |
||
400 | * Clears cache of stat() and statvfs() |
||
401 | * @return void |
||
402 | */ |
||
403 | public function clearStatCache() |
||
408 | |||
409 | /** |
||
410 | * Reads data from file |
||
411 | * @param integer $length Length |
||
412 | * @param integer $offset Offset |
||
413 | * @param callable $cb Callback |
||
414 | * @param integer $pri Priority |
||
415 | * @return boolean |
||
416 | */ |
||
417 | public function read($length, $offset = null, $cb = null, $pri = EIO_PRI_DEFAULT) |
||
445 | |||
446 | /** |
||
447 | * sendfile() |
||
448 | * @param mixed $outfd File descriptor |
||
449 | * @param callable $cb Callback |
||
450 | * @param callable $startCb Start callback |
||
451 | * @param integer $offset Offset |
||
452 | * @param integer $length Length |
||
453 | * @param integer $pri Priority |
||
454 | * @return boolean Success |
||
455 | */ |
||
456 | public function sendfile($outfd, $cb, $startCb = null, $offset = 0, $length = null, $pri = EIO_PRI_DEFAULT) |
||
538 | |||
539 | /** |
||
540 | * readahead() |
||
541 | * @param integer $length Length |
||
542 | * @param integer $offset Offset |
||
543 | * @param callable $cb Callback |
||
544 | * @param integer $pri Priority |
||
545 | * @return resource|false |
||
546 | */ |
||
547 | public function readahead($length, $offset = null, $cb = null, $pri = EIO_PRI_DEFAULT) |
||
572 | |||
573 | /** |
||
574 | * Generates closure-callback for readAll |
||
575 | * @param callable $cb |
||
576 | * @param integer $size |
||
577 | * @param integer &$offset |
||
578 | * @param integer &$pri |
||
579 | * @param string &$buf |
||
580 | * @return callable |
||
581 | */ |
||
582 | View Code Duplication | protected function readAllGenHandler($cb, $size, &$offset, &$pri, &$buf) |
|
597 | |||
598 | /** |
||
599 | * Reads whole file |
||
600 | * @param callable $cb Callback |
||
601 | * @param integer $pri Priority |
||
602 | * @return boolean Success |
||
603 | */ |
||
604 | public function readAll($cb, $pri = EIO_PRI_DEFAULT) |
||
640 | |||
641 | /** |
||
642 | * Generates closure-callback for readAllChunked |
||
643 | * @param callable $cb |
||
644 | * @param callable $chunkcb |
||
645 | * @param integer $size |
||
646 | * @param integer $offset |
||
647 | * @param integer $pri |
||
648 | * @return callable |
||
649 | */ |
||
650 | View Code Duplication | protected function readAllChunkedGenHandler($cb, $chunkcb, $size, &$offset, $pri) |
|
672 | |||
673 | /** |
||
674 | * Reads file chunk-by-chunk |
||
675 | * @param callable $cb Callback |
||
676 | * @param callable $chunkcb Callback of chunk |
||
677 | * @param integer $pri Priority |
||
678 | * @return resource|false |
||
679 | */ |
||
680 | public function readAllChunked($cb = null, $chunkcb = null, $pri = EIO_PRI_DEFAULT) |
||
711 | |||
712 | /** |
||
713 | * toString handler |
||
714 | * @return string |
||
715 | */ |
||
716 | public function __toString() |
||
720 | |||
721 | /** |
||
722 | * Set chunk size |
||
723 | * @param integer $n Chunk size |
||
724 | * @return void |
||
725 | */ |
||
726 | public function setChunkSize($n) |
||
730 | |||
731 | /** |
||
732 | * Move pointer to arbitrary position |
||
733 | * @param integer $offset Offset |
||
734 | * @param callable $cb Callback |
||
735 | * @param integer $pri Priority |
||
736 | * @return resource|false |
||
737 | */ |
||
738 | public function seek($offset, $cb, $pri = EIO_PRI_DEFAULT) |
||
747 | |||
748 | /** |
||
749 | * Get current pointer position |
||
750 | * @return integer |
||
751 | */ |
||
752 | public function tell() |
||
759 | |||
760 | /** |
||
761 | * Close the file |
||
762 | * @return resource|false |
||
763 | */ |
||
764 | public function close() |
||
785 | |||
786 | /** |
||
787 | * Destructor |
||
788 | */ |
||
789 | public function __destruct() |
||
793 | } |
||
794 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..