Example #1
0
 /**
  * Recreates object by calling the constructor with parameters
  * that match the array keys (recursively for objects)
  *
  * Example:
  * <pre>
  * public static function fromArray($obj) {
  *     return SerializeHelper::createClassFromArray(get_called_class(), $obj);
  * }
  * </pre>
  *
  * Requirements:
  *
  * 1) Constructor parameters that are objects need to be type hinted
  *
  * 2) Constructor parameters that are objects need to implement {@see SerializableInterface}
  *
  * 3) Constructor parameter names need to match the class variable names
  *
  * @param string $className
  * @param array $obj
  * @throws NotSerializableException If a constructor takes an object that
  *                                  does not implement {@see SerializableInterface}
  *                                  or if the class does not exist
  * @return $this
  */
 public static function createClassFromArray($className, $obj)
 {
     if (!class_exists($className)) {
         throw new NotSerializableException($className . ' does not exist');
     }
     $cls = new \ReflectionClass($className);
     $refParams = $cls->getConstructor()->getParameters();
     $params = array();
     foreach ($refParams as $refParam) {
         try {
             $paramCls = $refParam->getClass();
         } catch (\ReflectionException $e) {
             throw new NotSerializableException(sprintf('The constructor parameter "%s" of class "%s" is type hinting a nonexistent class', $refParam->getName(), $className));
         }
         if (!array_key_exists($refParam->name, $obj)) {
             $params[] = $refParam->isOptional() ? $refParam->getDefaultValue() : null;
             continue;
         }
         if (!$paramCls) {
             $params[] = $obj[$refParam->name];
         } elseif ($paramCls->name === "DateTime") {
             $timestamp = $obj[$refParam->name];
             $params[] = DateTime::fromArray($timestamp);
         } elseif ($paramCls->isSubclassOf('GMO\\Common\\ISerializable')) {
             /** @var SerializableInterface|string $clsName */
             $clsName = $paramCls->name;
             if (!class_exists($clsName)) {
                 throw new NotSerializableException($className . ' does not exist');
             }
             $params[] = $clsName::fromArray($obj[$refParam->name]);
         } elseif ($paramCls->isSubclassOf('\\Exception') || $paramCls->getName() === 'Exception') {
             $params[] = unserialize($obj[$refParam->name]);
         } else {
             throw new NotSerializableException($paramCls->name . ' does not implement GMO\\Common\\ISerializable');
         }
     }
     return $cls->newInstanceArgs($params);
 }