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:
1 | <?php |
||
28 | abstract class Driver extends PDODriver |
||
29 | { |
||
30 | /** |
||
31 | * Schema table class. |
||
32 | */ |
||
33 | const TABLE_SCHEMA_CLASS = ''; |
||
34 | |||
35 | /** |
||
36 | * Commander used to execute commands. :). |
||
37 | */ |
||
38 | const COMMANDER = ''; |
||
39 | |||
40 | /** |
||
41 | * Query compiler class. |
||
42 | */ |
||
43 | const QUERY_COMPILER = ''; |
||
44 | |||
45 | /** |
||
46 | * Associated cache store, if any. |
||
47 | * |
||
48 | * @var StoreInterface |
||
49 | */ |
||
50 | protected $cacheStore = null; |
||
51 | |||
52 | /** |
||
53 | * @var FactoryInterface |
||
54 | */ |
||
55 | protected $factory = null; |
||
56 | |||
57 | /** |
||
58 | * @param string $name |
||
59 | * @param array $options |
||
60 | * @param FactoryInterface $factory Required to build instances of query builders and compilers. |
||
61 | * @param StoreInterface $store Cache store associated with driver (optional). |
||
62 | */ |
||
63 | public function __construct( |
||
74 | |||
75 | /** |
||
76 | * Set cache store to be used by driver. |
||
77 | * |
||
78 | * @param StoreInterface $store |
||
79 | * |
||
80 | * @return self|$this |
||
81 | */ |
||
82 | public function setStore(StoreInterface $store): Driver |
||
88 | |||
89 | /** |
||
90 | * Execute statement or fetch result from cache and return cached query iterator. |
||
91 | * |
||
92 | * @param string $query |
||
93 | * @param array $parameters Parameters to be binded into query. |
||
94 | * @param int $lifetime Cache lifetime in seconds. |
||
95 | * @param string $key Cache key to be used to store query result. |
||
96 | * @param StoreInterface $store Cache store to store result in, if null default store will |
||
97 | * be used. |
||
98 | * |
||
99 | * @return CachedResult |
||
100 | * |
||
101 | * @throws DriverException |
||
102 | * @throws QueryException |
||
103 | */ |
||
104 | public function cachedQuery( |
||
130 | |||
131 | /** |
||
132 | * Check if table exists. |
||
133 | * |
||
134 | * @param string $name |
||
135 | * |
||
136 | * @return bool |
||
137 | */ |
||
138 | abstract public function hasTable(string $name): bool; |
||
139 | |||
140 | /** |
||
141 | * Clean (truncate) specified driver table. |
||
142 | * |
||
143 | * @param string $table Table name with prefix included. |
||
144 | */ |
||
145 | abstract public function truncateData(string $table); |
||
146 | |||
147 | /** |
||
148 | * Get every available table name as array. |
||
149 | * |
||
150 | * @return array |
||
151 | */ |
||
152 | abstract public function tableNames(): array; |
||
153 | |||
154 | /** |
||
155 | * Get Driver specific AbstractTable implementation. |
||
156 | * |
||
157 | * @param string $table Table name without prefix included. |
||
158 | * @param string $prefix Database specific table prefix, this parameter is not required, |
||
159 | * but if provided all |
||
160 | * foreign keys will be created using it. |
||
161 | * |
||
162 | * @return AbstractTable |
||
163 | */ |
||
164 | public function tableSchema(string $table, string $prefix = ''): AbstractTable |
||
171 | |||
172 | /** |
||
173 | * Get instance of Driver specific QueryCompiler. |
||
174 | * |
||
175 | * @param string $prefix Database specific table prefix, used to quote table names and build |
||
176 | * aliases. |
||
177 | * |
||
178 | * @return QueryCompiler |
||
179 | */ |
||
180 | public function queryCompiler(string $prefix = ''): QueryCompiler |
||
187 | |||
188 | /** |
||
189 | * Get InsertQuery builder with driver specific query compiler. |
||
190 | * |
||
191 | * @param string $prefix Database specific table prefix, used to quote table names and build |
||
192 | * aliases. |
||
193 | * @param array $parameters Initial builder parameters. |
||
194 | * |
||
195 | * @return InsertQuery |
||
196 | */ |
||
197 | View Code Duplication | public function insertBuilder(string $prefix, array $parameters = []): InsertQuery |
|
204 | |||
205 | /** |
||
206 | * Get SelectQuery builder with driver specific query compiler. |
||
207 | * |
||
208 | * @param string $prefix Database specific table prefix, used to quote table names and build |
||
209 | * aliases. |
||
210 | * @param array $parameters Initial builder parameters. |
||
211 | * |
||
212 | * @return SelectQuery |
||
213 | */ |
||
214 | View Code Duplication | public function selectBuilder(string $prefix, array $parameters = []): SelectQuery |
|
221 | |||
222 | /** |
||
223 | * Get DeleteQuery builder with driver specific query compiler. |
||
224 | * |
||
225 | * @param string $prefix Database specific table prefix, used to quote table names and build |
||
226 | * aliases. |
||
227 | * @param array $parameters Initial builder parameters. |
||
228 | * |
||
229 | * @return DeleteQuery |
||
230 | */ |
||
231 | View Code Duplication | public function deleteBuilder(string $prefix, array $parameters = []): DeleteQuery |
|
239 | |||
240 | /** |
||
241 | * Get UpdateQuery builder with driver specific query compiler. |
||
242 | * |
||
243 | * @param string $prefix Database specific table prefix, used to quote table names and build |
||
244 | * aliases. |
||
245 | * @param array $parameters Initial builder parameters. |
||
246 | * |
||
247 | * @return UpdateQuery |
||
248 | */ |
||
249 | View Code Duplication | public function updateBuilder(string $prefix, array $parameters = []): UpdateQuery |
|
256 | } |
||
257 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.