/** * Call the event's constructor using serialized data */ public function unserialize($data) { $data = unserialize($data); $class = new \ReflectionObject($this); $params = $class->getConstructor()->getParameters(); $pass = array(); // Iterate through all the parameters of the constructor and try to // locate the value for each one in the serialized data foreach ($params as $param) { if (isset($data[$param->getName()])) { $value = $data[$param->getName()]; // If the serialized data contained a model's ID (and type), // pass a new instance of it if ($this->isModel($param)) { if ($param->getClass()->isInstantiable()) { $value = $param->getClass()->newInstance($value); } else { $id = $value['id']; $type = $value['type']; $value = new $type($id); } } } else { $value = null; } $pass[$param->getName()] = $value; } $class->getConstructor()->invokeArgs($this, $pass); }
/** * @param string $className * @param $document * * @throws \Exception * * @return mixed */ public function hydrate($className, $document) { $reflClass = new ReflectionClass($className); $this->parser->validateClassAnnotation($reflClass); $propertyAnnotations = $this->parser->getProperties($reflClass); $propertyTypes = $this->parser->getPropertyTypes($reflClass); if (is_string($document)) { $document = (array) json_decode($document); } $hydrated = $reflClass->newInstanceWithoutConstructor(); $reflection = new \ReflectionObject($hydrated); $constructor = $reflection->getConstructor(); if ($constructor) { $constructor->setAccessible(true); $constructor->invoke($hydrated); } foreach ($document as $field => $value) { if (is_array($value)) { $hydrated->{$field} = $value; } $this->setIdIfPresent($field, $value, $reflClass, $propertyTypes, $hydrated); if ($this->propertyCanBeSet($hydrated, $field, $propertyAnnotations)) { $field = $propertyAnnotations[$field]; $type = $propertyTypes[$field]; $value = $this->coerceValue($type, $value); $setter = $this->getSetterMethod($field); $hydrated->{$setter}($value); } } return $hydrated; }
class B { function B() { } } class C extends B { function C() { } } class D1 extends C { function __construct() { } } class D2 extends C { } $classes = array('NewCtor', 'ExtendsNewCtor', 'OldCtor', 'ExtendsOldCtor', 'OldAndNewCtor', 'NewAndOldCtor', 'B', 'C', 'D1', 'D2', 'X', 'Y'); foreach ($classes as $class) { $rc = new ReflectionObject(new $class()); $rm = $rc->getConstructor(); if ($rm != null) { echo "Constructor of {$class}: " . $rm->getName() . "\n"; } else { echo "No constructor for {$class}\n"; } }
<?php class C { } $rc = new ReflectionObject(new C()); var_dump($rc->getConstructor(null)); var_dump($rc->getConstructor('X')); var_dump($rc->getConstructor(true)); var_dump($rc->getConstructor(array(1, 2, 3)));
/** * @throws \Exception * @param mixed $callable * @return mixed */ public function invoke($callable) { if (!is_callable($callable, true)) { throw new \Exception("Not a callable"); } $result = null; if (is_array($callable) && count($callable) === 2) { $instance = $callable[0]; if (is_string($instance)) { $instance = $this->getDependency($instance); } $methodName = $callable[1]; $object = new \ReflectionObject($instance); $methodName === "__construct" ? $method = $object->getConstructor() : ($method = $object->getMethod($methodName)); if ($method !== null) { $method->setAccessible(true); $dependencies = $this->getDependenciesForFunctionOrMethod($method); $result = $method->invokeArgs($instance, $dependencies); } } else { $function = new \ReflectionFunction($callable); $dependencies = $this->getDependenciesForFunctionOrMethod($function); $result = $function->invokeArgs($dependencies); } return $result; }
/** * @param $param * @param \ReflectionObject $reflection */ private function buildFromObject($param, $reflection = null) { foreach ($param as $key => $value) { $this->object['Object default'][$key] = $value; } // Get info on the object $this->object['Reflection']['In namespace'] = $reflection->inNamespace() ? 'Yes' : 'No'; if ($reflection->inNamespace()) { $this->object['Class namespace'] = $reflection->getNamespaceName(); } $this->object['Reflection']['Class name'] = $reflection->getName(); $this->object['Reflection']['Is internal'] = $reflection->isInternal() ? 'Yes' : 'No'; $this->object['Reflection']['Is iterable'] = $reflection->isIterateable() ? 'Yes' : 'No'; $this->object['Reflection']['Is abstract'] = $reflection->isAbstract() ? 'Yes' : 'No'; $this->object['Reflection']['Is final'] = $reflection->isFinal() ? 'Yes' : 'No'; $this->object['Reflection']['Is user defined'] = $reflection->isUserDefined() ? 'Yes' : 'No'; $this->object['Reflection']['Is instantiable'] = $reflection->isInstantiable() ? 'Yes' : 'No'; $this->object['Reflection']['Is clonable'] = $reflection->isCloneable() ? 'Yes' : 'No'; $this->object['Reflection']['Is interface'] = $reflection->isInterface() ? 'Yes' : 'No'; $this->object['Reflection']['Class constants'] = !empty($reflection->getConstants()) ? $reflection->getConstants() : 'Class has no constants'; $this->object['Reflection']['Class static properties'] = !empty($reflection->getStaticProperties()) ? $reflection->getStaticProperties() : 'Class has no static properties'; $this->object['Reflection']['Class default properties'] = !empty($reflection->getDefaultProperties()) ? $reflection->getDefaultProperties() : 'Class has no default properties'; if (null === $reflection->getConstructor()) { $this->object['Reflection']['Class construct'] = 'Class has no construct.'; } else { $this->object['Reflection']['Class construct'] = $reflection->getConstructor(); } $this->object['Reflection']['Class interfaces'] = !empty($reflection->getInterfaces()) ? $reflection->getInterfaces() : 'Class implements no interfaces'; $this->object['Reflection']['Class traits'] = !empty($reflection->getTraits()) ? $reflection->getTraits() : 'Class has no traits'; $this->object['Reflection']['Class parent'] = $reflection->getParentClass() !== false ? $reflection->getParentClass() : 'Class has no parent'; if (false === $reflection->getFileName()) { $this->object['Reflection']['Defined in'] = 'Class is internal, no definition to provide.'; } else { $this->object['Reflection']['Defined in'] = $reflection->getFileName(); } if (false === $reflection->getFileName()) { $this->object['Reflection']['Start line'] = 'Class is internal, no start line to provide.'; } else { $this->object['Reflection']['Start line'] = $reflection->getFileName(); } if (false === $reflection->getEndLine()) { $this->object['Reflection']['End line'] = 'Class is internal, no end line to provide.'; } else { $this->object['Reflection']['End line'] = $reflection->getEndLine(); } if (false === $reflection->getDocComment()) { $this->object['Reflection']['Doc comments'] = 'No documents to provide.'; } else { $this->object['Reflection']['Doc comments'] = $reflection->getDocComment(); } // End get info $this->html .= "<span class=\"js-parent-object\">"; if (!empty($this->object['Object default'])) { $this->html .= "<div class=\"js-object-default-tab \"><button class=\"button-reflection button\">Show reflection</button></div>"; $this->html .= "<div class=\"js-object-default \">"; $this->buildFromObjectIterationInformationRecursive($this->object['Object default']); $this->html .= "</div>"; } if ($param instanceof \Closure) { $this->html .= "<div class=\"js-object-default-tab \"><button class=\"button-reflection button\">Show reflection</button></div>"; $this->html .= "<div class=\"js-object-default \">"; $this->html .= "<span class=\"css-type-string\">Nothing here...</span>"; $this->html .= "</div>"; } $this->html .= "<div class=\"js-object-reflection-tab hide\"><button class=\"button-class-default button\">Show default</button></div>"; $this->html .= "<div class=\"js-object-reflection hide\">"; $this->buildFromObjectReflectionInformationRecursive($this->object['Reflection']); $this->html .= "</div>"; $this->html .= "</span>"; $this->object = []; }
/** * Parse a fetched row, using fetch mode. * This method also populates bound columns. * @param array $row Fetched row to parse * @param FetchMode $fetchmode Fetch mode to use * @return mixed Fetched row, after transformation and parsing based on fetch mode */ private final function parseFetched(array $row, FetchMode $fetchmode) { foreach ($row as $tag => $value) { if (isset($this->parameters[$tag])) { $param =& $this->parameters[$tag]['param']; $type = $this->parameters[$tag]['type']; $param = $this->connection->quote($value, $type); } } if ($fetchmode->hasMode(DB::FETCH_BOTH)) { return array_merge($row, array_values($row)); } if ($fetchmode->hasMode(DB::FETCH_ASSOC)) { return $row; } if ($fetchmode->hasMode(DB::FETCH_NUM)) { return array_values($row); } if ($fetchmode->hasMode(DB::FETCH_COLUMN)) { $values = array_values($row); return isset($values[$fetchmode->col]) ? $values[$fetchmode->col] : null; } if ($fetchmode->hasMode(DB::FETCH_OBJ)) { return (object) $row; } if ($fetchmode->hasMode(DB::FETCH_CLASS)) { $classname = $fetchmode->hasMode(DB::FETCH_CLASSTYPE) ? array_shift($row) : $fetchmode->classname; $refl = new \ReflectionClass($classname); $obj = $fetchmode->hasMode(DB::FETCH_PROPS_EARLY) ? $refl->newInstanceWithoutConstructor() : $refl->newInstanceArgs($fetchmode->ctor_args); $refl = new \ReflectionObject($obj); foreach ($row as $tag => $value) { if ($refl->hasProperty($tag)) { $refl->getProperty($tag)->setValue($obj, $value); } else { $obj->{$tag} = $value; } } if ($fetchmode->hasMode(DB::FETCH_PROPS_EARLY)) { $refl->getConstructor()->invokeArgs($obj, $fetchmode->ctor_args); } return $obj; } if ($fetchmode->hasMode(DB::FETCH_INTO)) { $refl = new \ReflectionObject($fetchmode->obj); foreach ($row as $tag => $value) { if ($refl->hasProperty($tag)) { $refl->getProperty($tag)->setValue($obj, $value); } else { $obj->{$tag} = $value; } } } }