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 ArrayUtil 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 ArrayUtil, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class ArrayUtil |
||
13 | { |
||
14 | /** |
||
15 | * Checks whether the array is associative or sequential. |
||
16 | * |
||
17 | * @param array $array |
||
18 | * |
||
19 | * @return bool |
||
20 | */ |
||
21 | public static function isAssoc(array $array) |
||
25 | |||
26 | /** |
||
27 | * Sorts an array by specified property. |
||
28 | * |
||
29 | * This method uses the stable sorting algorithm. See http://en.wikipedia.org/wiki/Sorting_algorithm#Stability |
||
30 | * Please use this method only if you really need stable sorting because this method is not so fast |
||
31 | * as native PHP sort functions. |
||
32 | * |
||
33 | * @param array $array The array to be sorted |
||
34 | * @param bool $reverse Indicates whether the sorting should be performed |
||
35 | * in reverse order |
||
36 | * @param mixed $propertyPath The property accessor. Can be string or PropertyPathInterface or callable |
||
37 | * @param int $sortingFlags The sorting type. Can be SORT_NUMERIC or SORT_STRING |
||
38 | * Also SORT_STRING can be combined with SORT_FLAG_CASE to sort |
||
39 | * strings case-insensitively |
||
40 | */ |
||
41 | public static function sortBy( |
||
74 | |||
75 | /** |
||
76 | * @param mixed $a |
||
77 | * @param mixed $b |
||
78 | * @param bool $stringComparison |
||
79 | * |
||
80 | * @return int |
||
81 | */ |
||
82 | private static function compare($a, $b, $stringComparison = false) |
||
94 | |||
95 | /** |
||
96 | * @param array $array |
||
97 | * @param string|PropertyPathInterface|callable $propertyPath |
||
98 | * @param bool $reverse |
||
99 | * @param bool $stringComparison |
||
100 | * @param bool $caseInsensitive |
||
101 | * |
||
102 | * @return array|null |
||
103 | * |
||
104 | * @SuppressWarnings(PHPMD.NPathComplexity) |
||
105 | */ |
||
106 | private static function prepareSortable($array, $propertyPath, $reverse, $stringComparison, $caseInsensitive) |
||
150 | |||
151 | /** |
||
152 | * @param array $sortable |
||
153 | * @param bool $stringComparison |
||
154 | * @param bool $reverse |
||
155 | * |
||
156 | * @return array |
||
157 | */ |
||
158 | private static function getSortedKeys($sortable, $stringComparison, $reverse) |
||
176 | |||
177 | /** |
||
178 | * Compares 2 values based on order specified in the argument |
||
179 | * |
||
180 | * @param int[] $order |
||
181 | * |
||
182 | * @return callable |
||
183 | */ |
||
184 | public static function createOrderedComparator(array $order) |
||
198 | |||
199 | /** |
||
200 | * Return true if callback on any element returns truthy value, false otherwise |
||
201 | * |
||
202 | * @param callable $callback |
||
203 | * @param array $array |
||
204 | * |
||
205 | * @return boolean |
||
206 | */ |
||
207 | public static function some(callable $callback, array $array) |
||
217 | |||
218 | /** |
||
219 | * Return first element on which callback returns true value, null otherwise |
||
220 | * |
||
221 | * @param callable $callback |
||
222 | * @param array $array |
||
223 | * |
||
224 | * @return mixed|null |
||
225 | */ |
||
226 | public static function find(callable $callback, array $array) |
||
236 | |||
237 | /** |
||
238 | * Return copy of the array starting with item for which callback returns falsity value |
||
239 | * |
||
240 | * @param callable $callback |
||
241 | * @param array $array |
||
242 | * |
||
243 | * @return array |
||
244 | */ |
||
245 | public static function dropWhile(callable $callback, array $array) |
||
255 | |||
256 | /** |
||
257 | * Recursively merge arrays. |
||
258 | * |
||
259 | * Merge two arrays as array_merge_recursive do, but instead of converting values to arrays when keys are same |
||
260 | * replaces value from first array with value from second |
||
261 | * |
||
262 | * @param array $first |
||
263 | * @param array $second |
||
264 | * |
||
265 | * @return array |
||
266 | */ |
||
267 | public static function arrayMergeRecursiveDistinct(array $first, array $second) |
||
291 | |||
292 | /** |
||
293 | * Return array of ranges (inclusive) |
||
294 | * [[min1, max1], [min2, max2], ...] |
||
295 | * |
||
296 | * @param int[] $ints List of integers |
||
297 | * |
||
298 | * @return array |
||
299 | */ |
||
300 | public static function intRanges(array $ints) |
||
312 | |||
313 | /** |
||
314 | * @param array $sortedUniqueInts |
||
315 | * |
||
316 | * @return array|false Array 2 elements [min, max] or false when the array is empty |
||
317 | */ |
||
318 | public static function shiftRange(array &$sortedUniqueInts) |
||
336 | |||
337 | /** |
||
338 | * Return the values from a single column in the input array |
||
339 | * |
||
340 | * http://php.net/manual/en/function.array-column.php |
||
341 | * |
||
342 | * @param array $array |
||
343 | * @param mixed $columnKey |
||
344 | * @param mixed $indexKey |
||
345 | * |
||
346 | * @return array |
||
347 | */ |
||
348 | public static function arrayColumn(array $array, $columnKey, $indexKey = null) |
||
379 | |||
380 | /** |
||
381 | * @param array $array |
||
382 | * @param array $path |
||
383 | * |
||
384 | * @return array |
||
385 | */ |
||
386 | public static function unsetPath(array $array, array $path) |
||
402 | |||
403 | /** |
||
404 | * Returns the value in a nested associative array, |
||
405 | * where $path is an array of keys. Returns $defaultValue if the key |
||
406 | * is not present, or the not-found value if supplied. |
||
407 | * |
||
408 | * @param array $array |
||
409 | * @param array $path |
||
410 | * @param mixed $defaultValue |
||
411 | * |
||
412 | * @return mixed |
||
413 | */ |
||
414 | public static function getIn(array $array, array $path, $defaultValue = null) |
||
433 | } |
||
434 |
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.