Complex classes like CsvReader 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 CsvReader, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class CsvReader extends AbstractCsv implements \Iterator, \Countable |
||
13 | { |
||
14 | /** |
||
15 | * |
||
16 | * @var int |
||
17 | */ |
||
18 | private $position = 0; |
||
19 | |||
20 | /** |
||
21 | * |
||
22 | * @var array |
||
23 | */ |
||
24 | private $currentValues = []; |
||
25 | |||
26 | /** |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | protected $detectedEncoding; |
||
31 | |||
32 | /** |
||
33 | * |
||
34 | * Default Excel Reading configuration |
||
35 | * |
||
36 | * available options : |
||
37 | * - delimiter : (default = ';') |
||
38 | * - enclosure : (default = '"') |
||
39 | * - encoding : (default = 'CP1252') |
||
40 | * - eol : (default = "\r\n") |
||
41 | * - escape : (default = "\\") |
||
42 | * - first_row_header : (default = false) use the first CSV row as header |
||
43 | * - bom : (default = false) add UTF8 BOM marker |
||
44 | * - translit : (default = 'translit') iconv translit option possible values : 'translit', 'ignore', null |
||
45 | * - force_encoding_detect : (default = false) |
||
46 | * - skip_empty : (default = false) remove lines with empty values |
||
47 | * - trim : (default = false) trim each values on each line |
||
48 | * |
||
49 | * N.B. : Be careful, the options 'force_encoding_detect', 'skip_empty' and 'trim' |
||
50 | * decrease significantly the performances |
||
51 | * |
||
52 | * @param array $options Dialect Options to describe CSV file parameters |
||
53 | */ |
||
54 | 29 | public function __construct($options = []) |
|
60 | |||
61 | 3 | protected function getCompatibleFileHanderModes() |
|
65 | |||
66 | /** |
||
67 | * open a csv file to read |
||
68 | * |
||
69 | * @param string|resource $file filename or stream resource, default = null |
||
70 | * @return CsvReader |
||
71 | */ |
||
72 | 16 | public function open($file = null) |
|
80 | |||
81 | /** |
||
82 | * Detect current file encoding if ForceEncodingDetection is set to true or encoding parameter is null |
||
83 | */ |
||
84 | 14 | protected function detectEncoding() |
|
101 | |||
102 | /** |
||
103 | * |
||
104 | * @param resource|null $fileHandler |
||
105 | * @return array |
||
106 | * |
||
107 | * @throws \InvalidArgumentException |
||
108 | */ |
||
109 | 16 | protected function readLine($fileHandler) |
|
158 | |||
159 | /** |
||
160 | * return the current row and go to the next row |
||
161 | * |
||
162 | * @return array|false |
||
163 | */ |
||
164 | 12 | public function getRow() |
|
175 | |||
176 | /** |
||
177 | * get All rows as an array |
||
178 | * |
||
179 | * N.B.: Be careful, this method can consume a lot of memories on large CSV files. |
||
180 | * |
||
181 | * You should prefer iterate over the reader instead. |
||
182 | * |
||
183 | * @return array all rows in the CSV files |
||
184 | */ |
||
185 | 12 | public function getRows() |
|
197 | |||
198 | /** |
||
199 | * reset CSV reading to 1st line |
||
200 | * |
||
201 | * aliases for iterator rewind |
||
202 | */ |
||
203 | 12 | public function reset() |
|
207 | |||
208 | /** |
||
209 | * |
||
210 | * @return array |
||
211 | */ |
||
212 | 15 | public function current() |
|
216 | |||
217 | /** |
||
218 | * |
||
219 | * @return int |
||
220 | */ |
||
221 | 13 | public function key() |
|
225 | |||
226 | 16 | public function next() |
|
237 | |||
238 | 16 | public function rewind() |
|
256 | |||
257 | /** |
||
258 | * |
||
259 | * @return bool |
||
260 | */ |
||
261 | 15 | public function valid() |
|
265 | |||
266 | 9 | public function count() |
|
306 | } |
||
307 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.