Instantiator   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 48
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 48
rs 10
c 0
b 0
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A unserialize() 0 5 1
A construct() 0 8 2
A hydrate() 0 7 2
A instantiate() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Frostaly\VarExporter;
6
7
use Frostaly\VarExporter\Exception\NotInstantiableTypeException;
8
9
final class Instantiator
10
{
11
    /**
12
     * Create an object without invoking its constructor.
13
     */
14
    public static function instantiate(string $class): object
15
    {
16
        try {
17
            $reflector = new \ReflectionClass($class); // @phpstan-ignore-line
18
            return $reflector->newInstanceWithoutConstructor();
19
        } catch (\Throwable $exception) {
20
            throw new NotInstantiableTypeException($class, $exception);
21
        }
22
    }
23
24
    /**
25
     * Create an object with the given properties.
26
     */
27
    public static function construct(string $class, array $properties = [], array $privateProperties = []): object
28
    {
29
        $object = self::instantiate($class);
30
        self::hydrate($object, $properties, $object::class);
31
        foreach ($privateProperties as $scope => $properties) {
32
            self::hydrate($object, $properties, $scope);
33
        }
34
        return $object;
35
    }
36
37
    /**
38
     * Create an object using the __unserialize() method.
39
     */
40
    public static function unserialize(string $class, array $data = []): object
41
    {
42
        $object = self::instantiate($class);
43
        $object->__unserialize($data);
44
        return $object;
45
    }
46
47
    /**
48
     * Hydrate the object with the given properties.
49
     */
50
    private static function hydrate(object $object, array $properties, string $scope): void
51
    {
52
        (function (array $properties) use ($object) {
53
            foreach ($properties as $name => $value) {
54
                $object->{$name} = $value;
55
            }
56
        })->bindTo($object, $scope)($properties);
57
    }
58
}
59