Complex classes like Statement 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 Statement, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class Statement implements StatementInterface |
||
14 | { |
||
15 | |||
16 | use StatementTrait; |
||
17 | |||
18 | /** |
||
19 | * @var MysqliAdapter |
||
20 | */ |
||
21 | protected $connection; |
||
22 | |||
23 | /** |
||
24 | * @var mysqli_stmt |
||
25 | */ |
||
26 | protected $stmt; |
||
27 | |||
28 | /** |
||
29 | * @var string |
||
30 | */ |
||
31 | protected $queryString; |
||
32 | |||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | protected $runnableQueryString; |
||
37 | |||
38 | /** |
||
39 | * MysqliStatement constructor. |
||
40 | * @param MysqliAdapter $connection |
||
41 | * @param mysqli_stmt $stmt |
||
42 | * @param array $values |
||
43 | * @param string $queryString |
||
44 | * @param string $runnableQueryString |
||
45 | */ |
||
46 | public function __construct(MysqliAdapter $connection, mysqli_stmt $stmt, array $values = null, string $queryString, string $runnableQueryString = null) |
||
54 | |||
55 | /** |
||
56 | * @return MysqliAdapter |
||
57 | */ |
||
58 | final public function getConnection(): AdapterInterface |
||
62 | |||
63 | /** |
||
64 | * @inheritDoc |
||
65 | */ |
||
66 | public function getQueryString(): string |
||
70 | |||
71 | /** |
||
72 | * @inheritDoc |
||
73 | */ |
||
74 | public function getWrappedStatement() |
||
78 | |||
79 | /** |
||
80 | * @inheritDoc |
||
81 | */ |
||
82 | public function bind(): void |
||
96 | |||
97 | /** |
||
98 | * @param array $values |
||
99 | * @return string |
||
100 | */ |
||
101 | private function getTypesFor(array $values): string |
||
109 | |||
110 | /** |
||
111 | * @return array |
||
112 | */ |
||
113 | private function resolveValues(): array |
||
129 | |||
130 | /** |
||
131 | * Attempt to convert non-scalar values. |
||
132 | * |
||
133 | * @param $value |
||
134 | * @return string |
||
135 | */ |
||
136 | protected function toScalar($value) |
||
156 | |||
157 | /** |
||
158 | * @inheritDoc |
||
159 | */ |
||
160 | public function preview(): string |
||
216 | |||
217 | /** |
||
218 | * @param $value |
||
219 | * @return string |
||
220 | */ |
||
221 | protected function getMysqliType($value) |
||
236 | /** |
||
237 | * @return Result |
||
238 | */ |
||
239 | public function createResult(): ResultInterface |
||
247 | |||
248 | /** |
||
249 | * @inheritDoc |
||
250 | */ |
||
251 | public function __toString(): string |
||
255 | } |
||
256 |
Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.
To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.
The function can be called with either null or an array for the parameter
$needle
but will only accept an array as$haystack
.