Complex classes like ReflectionClassLikeTrait 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 ReflectionClassLikeTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | trait ReflectionClassLikeTrait |
||
30 | { |
||
31 | use InitializationTrait; |
||
32 | |||
33 | /** |
||
34 | * @var ClassLike |
||
35 | */ |
||
36 | protected $classLikeNode; |
||
37 | |||
38 | /** |
||
39 | * Short name of the class, without namespace |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | protected $className; |
||
44 | |||
45 | /** |
||
46 | * List of all constants from the class |
||
47 | * |
||
48 | * @var array |
||
49 | */ |
||
50 | protected $constants; |
||
51 | |||
52 | /** |
||
53 | * Interfaces, empty array or null if not initialized yet |
||
54 | * |
||
55 | * @var \ReflectionClass[]|array|null |
||
56 | */ |
||
57 | protected $interfaceClasses; |
||
58 | |||
59 | /** |
||
60 | * List of traits, empty array or null if not initialized yet |
||
61 | * |
||
62 | * @var \ReflectionClass[]|array|null |
||
63 | */ |
||
64 | protected $traits; |
||
65 | |||
66 | /** |
||
67 | * Additional list of trait adaptations |
||
68 | * |
||
69 | * @var TraitUseAdaptation[]|array |
||
70 | */ |
||
71 | protected $traitAdaptations; |
||
72 | |||
73 | /** |
||
74 | * @var array|ReflectionMethod[] |
||
75 | */ |
||
76 | protected $methods; |
||
77 | |||
78 | /** |
||
79 | * Namespace name |
||
80 | * |
||
81 | * @var string |
||
82 | */ |
||
83 | protected $namespaceName = ''; |
||
84 | |||
85 | /** |
||
86 | * Parent class, or false if not present, null if uninitialized yet |
||
87 | * |
||
88 | * @var \ReflectionClass|false|null |
||
89 | */ |
||
90 | protected $parentClass; |
||
91 | |||
92 | /** |
||
93 | * @var array|ReflectionProperty[] |
||
94 | */ |
||
95 | protected $properties; |
||
96 | |||
97 | /** |
||
98 | * Returns the string representation of the ReflectionClass object. |
||
99 | * |
||
100 | * @return string |
||
101 | */ |
||
102 | public function __toString() |
||
103 | { |
||
104 | $isObject = $this instanceof \ReflectionObject; |
||
105 | |||
106 | $staticProperties = $staticMethods = $defaultProperties = $dynamicProperties = $methods = []; |
||
107 | |||
108 | $format = "%s [ <user> %sclass %s%s%s ] {\n"; |
||
109 | $format .= " @@ %s %d-%d\n\n"; |
||
110 | $format .= " - Constants [%d] {%s\n }\n\n"; |
||
111 | $format .= " - Static properties [%d] {%s\n }\n\n"; |
||
112 | $format .= " - Static methods [%d] {%s\n }\n\n"; |
||
113 | $format .= " - Properties [%d] {%s\n }\n\n"; |
||
114 | $format .= ($isObject ? " - Dynamic properties [%d] {%s\n }\n\n" : '%s%s'); |
||
115 | $format .= " - Methods [%d] {%s\n }\n"; |
||
116 | $format .= "}\n"; |
||
117 | |||
118 | foreach ($this->getProperties() as $property) { |
||
119 | if ($property->isStatic()) { |
||
120 | $staticProperties[] = $property; |
||
121 | } elseif ($property->isDefault()) { |
||
122 | $defaultProperties[] = $property; |
||
123 | } else { |
||
124 | $dynamicProperties[] = $property; |
||
125 | } |
||
126 | } |
||
127 | |||
128 | foreach ($this->getMethods() as $method) { |
||
129 | if ($method->isStatic()) { |
||
130 | $staticMethods[] = $method; |
||
131 | } else { |
||
132 | $methods[] = $method; |
||
133 | } |
||
134 | } |
||
135 | |||
136 | $buildString = function (array $items, $indentLevel = 4) { |
||
137 | if (!count($items)) { |
||
138 | return ''; |
||
139 | } |
||
140 | $indent = "\n" . str_repeat(' ', $indentLevel); |
||
141 | return $indent . implode($indent, explode("\n", implode("\n", $items))); |
||
142 | }; |
||
143 | $buildConstants = function (array $items, $indentLevel = 4) { |
||
144 | $str = ''; |
||
145 | foreach ($items as $name => $value) { |
||
146 | $str .= "\n" . str_repeat(' ', $indentLevel); |
||
147 | $str .= sprintf( |
||
148 | 'Constant [ %s %s ] { %s }', |
||
149 | gettype($value), |
||
150 | $name, |
||
151 | $value |
||
152 | ); |
||
153 | } |
||
154 | return $str; |
||
155 | }; |
||
156 | $interfaceNames = $this->getInterfaceNames(); |
||
157 | $parentClass = $this->getParentClass(); |
||
158 | $modifiers = ''; |
||
159 | if ($this->isAbstract()) { |
||
160 | $modifiers = 'abstract '; |
||
161 | } elseif ($this->isFinal()) { |
||
162 | $modifiers = 'final '; |
||
163 | }; |
||
164 | |||
165 | $string = sprintf( |
||
166 | $format, |
||
167 | ($isObject ? 'Object of class' : 'Class'), |
||
168 | $modifiers, |
||
169 | $this->getName(), |
||
170 | false !== $parentClass ? (' extends ' . $parentClass->getName()) : '', |
||
171 | $interfaceNames ? (' implements ' . implode(', ', $interfaceNames)) : '', |
||
172 | $this->getFileName(), |
||
173 | $this->getStartLine(), |
||
174 | $this->getEndLine(), |
||
175 | count($this->getConstants()), |
||
176 | $buildConstants($this->getConstants()), |
||
177 | count($staticProperties), |
||
178 | $buildString($staticProperties), |
||
179 | count($staticMethods), |
||
180 | $buildString($staticMethods), |
||
181 | count($defaultProperties), |
||
182 | $buildString($defaultProperties), |
||
183 | $isObject ? count($dynamicProperties) : '', |
||
184 | $isObject ? $buildString($dynamicProperties) : '', |
||
185 | count($methods), |
||
186 | $buildString($methods) |
||
187 | ); |
||
188 | |||
189 | return $string; |
||
190 | } |
||
191 | |||
192 | |||
193 | /** |
||
194 | * {@inheritDoc} |
||
195 | */ |
||
196 | 4 | public function getConstant($name) |
|
197 | { |
||
198 | 4 | if ($this->hasConstant($name)) { |
|
199 | 4 | return $this->constants[$name]; |
|
200 | } |
||
201 | |||
202 | return false; |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * {@inheritDoc} |
||
207 | */ |
||
208 | 23 | public function getConstants() |
|
209 | { |
||
210 | 23 | if (!isset($this->constants)) { |
|
211 | 23 | $directConstants = $this->findConstants(); |
|
212 | $parentConstants = $this->recursiveCollect(function (array &$result, \ReflectionClass $instance) { |
||
213 | 10 | $result += $instance->getConstants(); |
|
214 | 23 | }); |
|
215 | 23 | $constants = $directConstants + $parentConstants; |
|
216 | |||
217 | 23 | $this->constants = $constants; |
|
218 | } |
||
219 | |||
220 | 23 | return $this->constants; |
|
221 | } |
||
222 | |||
223 | /** |
||
224 | * {@inheritDoc} |
||
225 | */ |
||
226 | 13 | public function getConstructor() |
|
227 | { |
||
228 | 13 | $constructor = $this->getMethod('__construct'); |
|
229 | 13 | if (!$constructor) { |
|
230 | 11 | return null; |
|
231 | } |
||
232 | |||
233 | 2 | return $constructor; |
|
234 | } |
||
235 | |||
236 | /** |
||
237 | * Gets default properties from a class (including inherited properties). |
||
238 | * |
||
239 | * @link http://php.net/manual/en/reflectionclass.getdefaultproperties.php |
||
240 | * |
||
241 | * @return array An array of default properties, with the key being the name of the property and the value being |
||
242 | * the default value of the property or NULL if the property doesn't have a default value |
||
243 | */ |
||
244 | 22 | public function getDefaultProperties() |
|
245 | { |
||
246 | 22 | $defaultValues = []; |
|
247 | 22 | $properties = $this->getProperties(); |
|
248 | 22 | $staticOrder = [true, false]; |
|
249 | 22 | foreach ($staticOrder as $shouldBeStatic) { |
|
250 | 22 | foreach ($properties as $property) { |
|
251 | 7 | $isStaticProperty = $property->isStatic(); |
|
252 | 7 | if ($shouldBeStatic !== $isStaticProperty) { |
|
253 | 7 | continue; |
|
254 | } |
||
255 | 7 | $propertyName = $property->getName(); |
|
256 | 7 | $isInternalReflection = get_class($property) == \ReflectionProperty::class; |
|
257 | |||
258 | 7 | if (!$isInternalReflection || $isStaticProperty) { |
|
259 | 7 | $defaultValues[$propertyName] = $property->getValue(); |
|
260 | 1 | } elseif (!$isStaticProperty) { |
|
261 | // Internal reflection and dynamic property |
||
262 | 1 | $classProperties = $property->getDeclaringClass()->getDefaultProperties(); |
|
263 | 22 | $defaultValues[$propertyName] = $classProperties[$propertyName]; |
|
264 | } |
||
265 | } |
||
266 | } |
||
267 | |||
268 | 22 | return $defaultValues; |
|
269 | } |
||
270 | |||
271 | /** |
||
272 | * {@inheritDoc} |
||
273 | */ |
||
274 | 22 | public function getDocComment() |
|
275 | { |
||
276 | 22 | $docComment = $this->classLikeNode->getDocComment(); |
|
277 | |||
278 | 22 | return $docComment ? $docComment->getText() : false; |
|
279 | } |
||
280 | |||
281 | 22 | public function getEndLine() |
|
282 | { |
||
283 | 22 | return $this->classLikeNode->getAttribute('endLine'); |
|
284 | } |
||
285 | |||
286 | 22 | public function getExtension() |
|
287 | { |
||
288 | 22 | return null; |
|
289 | } |
||
290 | |||
291 | 22 | public function getExtensionName() |
|
292 | { |
||
293 | 22 | return false; |
|
294 | } |
||
295 | |||
296 | 7 | public function getFileName() |
|
297 | { |
||
298 | 7 | return $this->classLikeNode->getAttribute('fileName'); |
|
299 | } |
||
300 | |||
301 | /** |
||
302 | * {@inheritDoc} |
||
303 | */ |
||
304 | 22 | public function getInterfaceNames() |
|
308 | |||
309 | /** |
||
310 | * {@inheritDoc} |
||
311 | */ |
||
312 | 22 | public function getInterfaces() |
|
313 | { |
||
314 | 22 | if (!isset($this->interfaceClasses)) { |
|
315 | $this->interfaceClasses = $this->recursiveCollect(function (array &$result, \ReflectionClass $instance) { |
||
316 | 9 | if ($instance->isInterface()) { |
|
317 | 2 | $result[$instance->name] = $instance; |
|
318 | } |
||
319 | 9 | $result += $instance->getInterfaces(); |
|
320 | 22 | }); |
|
321 | } |
||
322 | |||
323 | 22 | return $this->interfaceClasses; |
|
324 | } |
||
325 | |||
326 | /** |
||
327 | * {@inheritdoc} |
||
328 | */ |
||
329 | 21 | public function getMethod($name) |
|
330 | { |
||
331 | 21 | $methods = $this->getMethods(); |
|
332 | 21 | foreach ($methods as $method) { |
|
333 | 15 | if ($method->getName() == $name) { |
|
334 | 15 | return $method; |
|
335 | } |
||
336 | } |
||
337 | |||
338 | 11 | return false; |
|
339 | } |
||
340 | |||
341 | /** |
||
342 | * Returns list of reflection methods |
||
343 | * |
||
344 | * @param null|integer $filter Optional filter |
||
345 | * |
||
346 | * @return array|\ReflectionMethod[] |
||
347 | */ |
||
348 | 66 | public function getMethods($filter = null) |
|
379 | |||
380 | /** |
||
381 | * Returns a bitfield of the access modifiers for this class. |
||
382 | * |
||
383 | * @link http://php.net/manual/en/reflectionclass.getmodifiers.php |
||
384 | * |
||
385 | * NB: this method is not fully compatible with original value because of hidden internal constants |
||
386 | * |
||
387 | * @return int |
||
388 | */ |
||
389 | 21 | public function getModifiers() |
|
416 | |||
417 | /** |
||
418 | * {@inheritDoc} |
||
419 | */ |
||
420 | 76 | public function getName() |
|
426 | |||
427 | /** |
||
428 | * {@inheritDoc} |
||
429 | */ |
||
430 | 25 | public function getNamespaceName() |
|
431 | { |
||
432 | 25 | return $this->namespaceName; |
|
433 | } |
||
434 | |||
435 | /** |
||
436 | * {@inheritDoc} |
||
437 | */ |
||
438 | 96 | public function getParentClass() |
|
439 | { |
||
440 | 96 | if (!isset($this->parentClass)) { |
|
441 | 96 | static $extendsField = 'extends'; |
|
442 | |||
443 | 96 | $parentClass = false; |
|
444 | 96 | $hasExtends = in_array($extendsField, $this->classLikeNode->getSubNodeNames()); |
|
445 | 96 | $extendsNode = $hasExtends ? $this->classLikeNode->$extendsField : null; |
|
446 | 96 | if ($extendsNode instanceof FullyQualified) { |
|
447 | 20 | $extendsName = $extendsNode->toString(); |
|
448 | 20 | $parentClass = class_exists($extendsName, false) ? new parent($extendsName) : new static($extendsName); |
|
|
|||
449 | } |
||
450 | 96 | $this->parentClass = $parentClass; |
|
451 | } |
||
452 | |||
453 | 96 | return $this->parentClass; |
|
454 | } |
||
455 | |||
456 | /** |
||
457 | * Retrieves reflected properties. |
||
458 | * |
||
459 | * @param int $filter The optional filter, for filtering desired property types. |
||
460 | * It's configured using the ReflectionProperty constants, and defaults to all property types. |
||
461 | * |
||
462 | * @return array|\Go\ParserReflection\ReflectionProperty[] |
||
463 | */ |
||
464 | 46 | public function getProperties($filter = null) |
|
497 | |||
498 | /** |
||
499 | * {@inheritdoc} |
||
500 | */ |
||
501 | 3 | public function getProperty($name) |
|
502 | { |
||
503 | 3 | $properties = $this->getProperties(); |
|
504 | 3 | foreach ($properties as $property) { |
|
505 | 3 | if ($property->getName() == $name) { |
|
506 | 3 | return $property; |
|
507 | } |
||
508 | } |
||
509 | |||
510 | return false; |
||
511 | } |
||
512 | |||
513 | /** |
||
514 | * {@inheritDoc} |
||
515 | */ |
||
516 | 76 | public function getShortName() |
|
517 | { |
||
518 | 76 | return $this->className; |
|
519 | } |
||
520 | |||
521 | 22 | public function getStartLine() |
|
522 | { |
||
523 | 22 | return $this->classLikeNode->getAttribute('startLine'); |
|
524 | } |
||
525 | |||
526 | /** |
||
527 | * Returns an array of trait aliases |
||
528 | * |
||
529 | * @link http://php.net/manual/en/reflectionclass.gettraitaliases.php |
||
530 | * |
||
531 | * @return array|null an array with new method names in keys and original names (in the format "TraitName::original") in |
||
532 | * values. |
||
533 | */ |
||
534 | 41 | public function getTraitAliases() |
|
554 | |||
555 | /** |
||
556 | * Returns an array of names of traits used by this class |
||
557 | * |
||
558 | * @link http://php.net/manual/en/reflectionclass.gettraitnames.php |
||
559 | * |
||
560 | * @return array |
||
561 | */ |
||
562 | 22 | public function getTraitNames() |
|
563 | { |
||
564 | 22 | return array_keys($this->getTraits()); |
|
565 | } |
||
566 | |||
567 | /** |
||
568 | * Returns an array of traits used by this class |
||
569 | * |
||
570 | * @link http://php.net/manual/en/reflectionclass.gettraits.php |
||
571 | * |
||
572 | * @return array|\ReflectionClass[] |
||
573 | */ |
||
574 | 96 | public function getTraits() |
|
584 | |||
585 | /** |
||
586 | * {@inheritDoc} |
||
587 | */ |
||
588 | 4 | public function hasConstant($name) |
|
589 | { |
||
590 | 4 | $constants = $this->getConstants(); |
|
591 | 4 | $hasConstant = isset($constants[$name]) || array_key_exists($name, $constants); |
|
592 | |||
593 | 4 | return $hasConstant; |
|
594 | } |
||
595 | |||
596 | /** |
||
597 | * {@inheritdoc} |
||
598 | */ |
||
599 | 15 | public function hasMethod($name) |
|
600 | { |
||
601 | 15 | $methods = $this->getMethods(); |
|
602 | 15 | foreach ($methods as $method) { |
|
603 | 9 | if ($method->getName() == $name) { |
|
604 | 9 | return true; |
|
605 | } |
||
606 | } |
||
607 | |||
608 | 12 | return false; |
|
609 | } |
||
610 | |||
611 | /** |
||
612 | * {@inheritdoc} |
||
613 | */ |
||
614 | public function hasProperty($name) |
||
615 | { |
||
616 | $properties = $this->getProperties(); |
||
617 | foreach ($properties as $property) { |
||
618 | if ($property->getName() == $name) { |
||
619 | return true; |
||
620 | } |
||
621 | } |
||
622 | |||
623 | return false; |
||
624 | } |
||
625 | |||
626 | /** |
||
627 | * {@inheritDoc} |
||
628 | */ |
||
629 | 22 | public function implementsInterface($interfaceName) |
|
630 | { |
||
631 | 22 | $allInterfaces = $this->getInterfaces(); |
|
632 | |||
633 | 22 | return isset($allInterfaces[$interfaceName]); |
|
634 | } |
||
635 | |||
636 | /** |
||
637 | * {@inheritDoc} |
||
638 | */ |
||
639 | 22 | public function inNamespace() |
|
640 | { |
||
641 | 22 | return !empty($this->namespaceName); |
|
642 | } |
||
643 | |||
644 | /** |
||
645 | * {@inheritDoc} |
||
646 | */ |
||
647 | 22 | public function isAbstract() |
|
659 | |||
660 | /** |
||
661 | * Currently, anonymous classes aren't supported for parsed reflection |
||
662 | */ |
||
663 | public function isAnonymous() |
||
664 | { |
||
665 | return false; |
||
666 | } |
||
667 | |||
668 | /** |
||
669 | * {@inheritDoc} |
||
670 | */ |
||
671 | 22 | public function isCloneable() |
|
672 | { |
||
673 | 22 | if ($this->isInterface() || $this->isTrait() || $this->isAbstract()) { |
|
674 | 9 | return false; |
|
675 | } |
||
676 | |||
677 | 13 | if ($this->hasMethod('__clone')) { |
|
678 | 1 | return $this->getMethod('__clone')->isPublic(); |
|
679 | } |
||
680 | |||
681 | 12 | return true; |
|
682 | } |
||
683 | |||
684 | /** |
||
685 | * {@inheritDoc} |
||
686 | */ |
||
687 | 43 | public function isFinal() |
|
688 | { |
||
689 | 43 | $isFinal = $this->classLikeNode instanceof Class_ && $this->classLikeNode->isFinal(); |
|
690 | |||
691 | 43 | return $isFinal; |
|
692 | } |
||
693 | |||
694 | /** |
||
695 | * {@inheritDoc} |
||
696 | */ |
||
697 | public function isInstance($object) |
||
698 | { |
||
699 | if (!is_object($object)) { |
||
700 | throw new \RuntimeException(sprintf('Parameter must be an object, "%s" provided.', gettype($object))); |
||
701 | } |
||
702 | |||
703 | $className = $this->getName(); |
||
704 | |||
705 | return $className === get_class($object) || is_subclass_of($object, $className); |
||
706 | } |
||
707 | |||
708 | /** |
||
709 | * {@inheritDoc} |
||
710 | */ |
||
711 | 22 | public function isInstantiable() |
|
712 | { |
||
713 | 22 | if ($this->isInterface() || $this->isTrait() || $this->isAbstract()) { |
|
714 | 9 | return false; |
|
715 | } |
||
716 | |||
717 | 13 | if (null === ($constructor = $this->getConstructor())) { |
|
718 | 11 | return true; |
|
719 | } |
||
720 | |||
721 | 2 | return $constructor->isPublic(); |
|
722 | } |
||
723 | |||
724 | /** |
||
725 | * {@inheritDoc} |
||
726 | */ |
||
727 | 43 | public function isInterface() |
|
728 | { |
||
729 | 43 | return ($this->classLikeNode instanceof Interface_); |
|
730 | } |
||
731 | |||
732 | /** |
||
733 | * {@inheritDoc} |
||
734 | */ |
||
735 | 22 | public function isInternal() |
|
736 | { |
||
737 | // never can be an internal method |
||
738 | 22 | return false; |
|
739 | } |
||
740 | |||
741 | /** |
||
742 | * {@inheritDoc} |
||
743 | */ |
||
744 | 22 | public function isIterateable() |
|
745 | { |
||
746 | 22 | return $this->implementsInterface('Traversable'); |
|
747 | } |
||
748 | |||
749 | /** |
||
750 | * {@inheritDoc} |
||
751 | */ |
||
752 | public function isSubclassOf($class) |
||
775 | |||
776 | /** |
||
777 | * {@inheritDoc} |
||
778 | */ |
||
779 | 22 | public function isTrait() |
|
780 | { |
||
781 | 22 | return ($this->classLikeNode instanceof Trait_); |
|
782 | } |
||
783 | |||
784 | /** |
||
785 | * {@inheritDoc} |
||
786 | */ |
||
787 | 22 | public function isUserDefined() |
|
788 | { |
||
789 | // always defined by user, because we parse the source code |
||
790 | 22 | return true; |
|
791 | } |
||
792 | |||
793 | /** |
||
794 | * Gets static properties |
||
795 | * |
||
796 | * @link http://php.net/manual/en/reflectionclass.getstaticproperties.php |
||
797 | * |
||
798 | * @return array |
||
799 | */ |
||
800 | 23 | public function getStaticProperties() |
|
801 | { |
||
802 | // In runtime static properties can be changed in any time |
||
803 | 23 | if ($this->isInitialized()) { |
|
804 | 1 | return forward_static_call('parent::getStaticProperties'); |
|
805 | } |
||
806 | |||
807 | 22 | $properties = []; |
|
808 | |||
809 | 22 | $reflectionProperties = $this->getProperties(ReflectionProperty::IS_STATIC); |
|
810 | 22 | foreach ($reflectionProperties as $reflectionProperty) { |
|
811 | 4 | if (!$reflectionProperty instanceof ReflectionProperty) { |
|
812 | 1 | if (!$reflectionProperty->isPublic()) { |
|
813 | 1 | $reflectionProperty->setAccessible(true); |
|
814 | } |
||
815 | } |
||
816 | 4 | $properties[$reflectionProperty->getName()] = $reflectionProperty->getValue(); |
|
817 | } |
||
818 | |||
819 | 22 | return $properties; |
|
820 | } |
||
821 | |||
822 | /** |
||
823 | * Gets static property value |
||
824 | * |
||
825 | * @param string $name The name of the static property for which to return a value. |
||
826 | * @param mixed $default A default value to return in case the class does not declare |
||
827 | * a static property with the given name |
||
828 | * |
||
829 | * @return mixed |
||
830 | * @throws ReflectionException If there is no such property and no default value was given |
||
831 | */ |
||
832 | 1 | public function getStaticPropertyValue($name, $default = null) |
|
833 | { |
||
834 | 1 | $properties = $this->getStaticProperties(); |
|
835 | 1 | $propertyExists = array_key_exists($name, $properties); |
|
836 | |||
837 | 1 | if (!$propertyExists && func_num_args() === 1) { |
|
838 | throw new ReflectionException("Static property does not exist and no default value is given"); |
||
839 | } |
||
840 | |||
841 | 1 | return $propertyExists ? $properties[$name] : $default; |
|
842 | } |
||
843 | |||
844 | |||
845 | /** |
||
846 | * Creates a new class instance from given arguments. |
||
847 | * |
||
848 | * @link http://php.net/manual/en/reflectionclass.newinstance.php |
||
849 | * @param mixed $args Accepts a variable number of arguments which are passed to the class constructor |
||
850 | * |
||
851 | * @return object |
||
852 | */ |
||
853 | 1 | public function newInstance($args = null) |
|
854 | { |
||
855 | 1 | $this->initializeInternalReflection(); |
|
856 | |||
857 | 1 | return call_user_func_array('parent::newInstance', func_get_args()); |
|
858 | } |
||
859 | |||
860 | /** |
||
861 | * Creates a new class instance from given arguments. |
||
862 | * |
||
863 | * @link http://php.net/manual/en/reflectionclass.newinstanceargs.php |
||
864 | * |
||
865 | * @param array $args The parameters to be passed to the class constructor as an array. |
||
866 | * |
||
867 | * @return object |
||
868 | */ |
||
869 | 1 | public function newInstanceArgs(array $args = []) |
|
870 | { |
||
871 | 1 | $function = __FUNCTION__; |
|
872 | 1 | $this->initializeInternalReflection(); |
|
873 | |||
874 | 1 | return parent::$function($args); |
|
875 | } |
||
876 | |||
877 | /** |
||
878 | * Creates a new class instance without invoking the constructor. |
||
879 | * |
||
880 | * @link http://php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php |
||
881 | * |
||
882 | * @return object |
||
883 | */ |
||
884 | 1 | public function newInstanceWithoutConstructor($args = null) |
|
885 | { |
||
886 | 1 | $function = __FUNCTION__; |
|
887 | 1 | $this->initializeInternalReflection(); |
|
888 | |||
889 | 1 | return parent::$function($args); |
|
890 | } |
||
891 | |||
892 | /** |
||
893 | * Sets static property value |
||
894 | * |
||
895 | * @link http://php.net/manual/en/reflectionclass.setstaticpropertyvalue.php |
||
896 | * |
||
897 | * @param string $name Property name |
||
898 | * @param mixed $value New property value |
||
899 | */ |
||
900 | 1 | public function setStaticPropertyValue($name, $value) |
|
901 | { |
||
902 | 1 | $this->initializeInternalReflection(); |
|
903 | |||
904 | 1 | forward_static_call('parent::setStaticPropertyValue', $name, $value); |
|
905 | 1 | } |
|
906 | |||
907 | 96 | private function recursiveCollect(\Closure $collector) |
|
929 | |||
930 | /** |
||
931 | * Returns list of constants from the class |
||
932 | * |
||
933 | * @return array |
||
934 | */ |
||
935 | 23 | private function findConstants() |
|
955 | } |
||
956 |
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.