1<?php 2 3namespace DeepCopy\Reflection; 4 5use DeepCopy\Exception\PropertyException; 6use ReflectionClass; 7use ReflectionException; 8use ReflectionObject; 9use ReflectionProperty; 10 11class ReflectionHelper 12{ 13 /** 14 * Retrieves all properties (including private ones), from object and all its ancestors. 15 * 16 * Standard \ReflectionClass->getProperties() does not return private properties from ancestor classes. 17 * 18 * @author muratyaman@gmail.com 19 * @see http://php.net/manual/en/reflectionclass.getproperties.php 20 * 21 * @param ReflectionClass $ref 22 * 23 * @return ReflectionProperty[] 24 */ 25 public static function getProperties(ReflectionClass $ref) 26 { 27 $props = $ref->getProperties(); 28 $propsArr = array(); 29 30 foreach ($props as $prop) { 31 $propertyName = $prop->getName(); 32 $propsArr[$propertyName] = $prop; 33 } 34 35 if ($parentClass = $ref->getParentClass()) { 36 $parentPropsArr = self::getProperties($parentClass); 37 foreach ($propsArr as $key => $property) { 38 $parentPropsArr[$key] = $property; 39 } 40 41 return $parentPropsArr; 42 } 43 44 return $propsArr; 45 } 46 47 /** 48 * Retrieves property by name from object and all its ancestors. 49 * 50 * @param object|string $object 51 * @param string $name 52 * 53 * @throws PropertyException 54 * @throws ReflectionException 55 * 56 * @return ReflectionProperty 57 */ 58 public static function getProperty($object, $name) 59 { 60 $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object); 61 62 if ($reflection->hasProperty($name)) { 63 return $reflection->getProperty($name); 64 } 65 66 if ($parentClass = $reflection->getParentClass()) { 67 return self::getProperty($parentClass->getName(), $name); 68 } 69 70 throw new PropertyException( 71 sprintf( 72 'The class "%s" doesn\'t have a property with the given name: "%s".', 73 is_object($object) ? get_class($object) : $object, 74 $name 75 ) 76 ); 77 } 78} 79