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 |
||
9 | class Parser extends Visitor |
||
10 | { |
||
11 | const ENCODING_UTF8 = 'UTF-8'; |
||
12 | const ENCODING_ISO = 'ISO-8859-1'; |
||
13 | const ENCODING_ASCII = 'US-ASCII'; |
||
14 | |||
15 | /** |
||
16 | * @var string input character set encoding (defaults to UTF-8) |
||
17 | * |
||
18 | * @see Parser::ENCODING_UTF8 |
||
19 | * @see Parser::ENCODING_ISO |
||
20 | * @see Parser::ENCODING_ASCII |
||
21 | * |
||
22 | * @see createParser() |
||
23 | */ |
||
24 | public $encoding = self::ENCODING_UTF8; |
||
25 | |||
26 | /** |
||
27 | * @var bool if true, enable case-folding (read all element/attribute-names in lower-case) |
||
28 | */ |
||
29 | public $case_folding = false; |
||
30 | |||
31 | /** |
||
32 | * @var bool if true, ignore whitespace between elements |
||
33 | */ |
||
34 | public $skip_white = true; |
||
35 | |||
36 | /** |
||
37 | * @var bool if true, trim leading/trailing whitespace in text nodes |
||
38 | */ |
||
39 | public $trim_text = true; |
||
40 | |||
41 | /** |
||
42 | * @var int buffer size in bytes (when reading XML files) |
||
43 | * |
||
44 | * @see parseFile() |
||
45 | */ |
||
46 | public $buffer_size = 4096; |
||
47 | |||
48 | /** |
||
49 | * @var Visitor[] $visitors node visitor stack |
||
50 | */ |
||
51 | protected $visitors; |
||
52 | |||
53 | /** |
||
54 | * @var Visitor $visitor most recent Visitor |
||
55 | */ |
||
56 | protected $visitor; |
||
57 | |||
58 | /** |
||
59 | * @var string character data buffer |
||
60 | */ |
||
61 | private $_buffer; |
||
62 | |||
63 | /** |
||
64 | * @var string[][] map where namespace xmlns-prefix => stack of namespace URIs |
||
65 | */ |
||
66 | private $ns_uri = array(); |
||
67 | |||
68 | /** |
||
69 | * @var string[] map where namespace URI => user-defined namespace prefix |
||
70 | */ |
||
71 | private $ns_prefix = array(); |
||
72 | |||
73 | /** |
||
74 | * @var string[][] stack where each entry is a list of namespace prefixes started at the corresponding depth |
||
75 | */ |
||
76 | private $ns_stack = array(); |
||
77 | |||
78 | /** |
||
79 | * @param string $input XML input |
||
80 | * |
||
81 | * @return void |
||
82 | * |
||
83 | * @throws ParserException if the XML input contains error |
||
84 | */ |
||
85 | 1 | public function parse($input) |
|
96 | |||
97 | /** |
||
98 | * Set the alias used for a namespace URI in Visitors. |
||
99 | * |
||
100 | * @param string $uri namespace URI |
||
101 | * @param string $alias |
||
102 | */ |
||
103 | 1 | public function setPrefix($uri, $alias) |
|
107 | |||
108 | /** |
||
109 | * @param string $path absolute path to XML file |
||
110 | * |
||
111 | * @return void |
||
112 | * |
||
113 | * @throws RuntimeException if the XML file was not found |
||
114 | * @throws ParserException if the XML file contains error |
||
115 | */ |
||
116 | 1 | public function parseFile($path) |
|
135 | |||
136 | /** |
||
137 | * Create and configure the XML parser. |
||
138 | * |
||
139 | * @return resource |
||
140 | */ |
||
141 | 1 | protected function createParser() |
|
167 | |||
168 | /** |
||
169 | * @param resource $parser XML parser |
||
170 | * @param string $name element name |
||
171 | * @param string[] $attr map of attributes |
||
172 | * |
||
173 | * @return void |
||
174 | * |
||
175 | * @see parse() |
||
176 | * @see xml_set_element_handler() |
||
177 | */ |
||
178 | 1 | protected function onStartElement($parser, $name, $attr) |
|
226 | |||
227 | /** |
||
228 | * @param resource $parser XML parser |
||
229 | * @param string $name element name |
||
230 | * |
||
231 | * @return void |
||
232 | * |
||
233 | * @see parse() |
||
234 | * @see xml_set_element_handler() |
||
235 | */ |
||
236 | 1 | protected function onEndElement($parser, $name) |
|
268 | |||
269 | /** |
||
270 | * @param resource $parser XML parser |
||
271 | * @param string $data partial text node content |
||
272 | * |
||
273 | * @return void |
||
274 | * |
||
275 | * @see parse() |
||
276 | * @see xml_set_character_data_handler() |
||
277 | */ |
||
278 | 1 | protected function onCharacterData($parser, $data) |
|
284 | |||
285 | /** |
||
286 | * Map namespace prefix defined in XML (by xmlns-attribute) to a user-defined prefix. |
||
287 | * |
||
288 | * For example, `a:foo`, where `a` resolves to `http://foo/`, and a user-defined alias has been |
||
289 | * defined for that URI as `b`, the resolved name is `b_foo` - e.g. suitable for parameter injection. |
||
290 | * |
||
291 | * @param string $name |
||
292 | * @param string $separator |
||
293 | * |
||
294 | * @return string |
||
295 | */ |
||
296 | 1 | private function applyUserPrefix($name, $separator = "_") |
|
320 | |||
321 | /** |
||
322 | * Flush any buffered text node content to the current visitor. |
||
323 | * |
||
324 | * @return void |
||
325 | */ |
||
326 | 1 | private function _flushBuffer() |
|
344 | } |
||
345 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.