-
Notifications
You must be signed in to change notification settings - Fork 2
/
Serializor.php
157 lines (140 loc) · 5.18 KB
/
Serializor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
declare(strict_types=1);
use Serializor\Codec;
use Serializor\SecretGenerators\SecretGenerationException;
use Serializor\SecretGenerators\SecretGeneratorFactory;
use Serializor\Transformers\AnonymousClassTransformer;
use Serializor\Transformers\ClosureTransformer;
/**
* Serializor class responsible for serializing and deserializing data,
* particularly closures and anonymous classes. This class allows for the
* serialization of tasks across processes, using a machine-specific secret
* to enhance security and consistency in serialization.
*/
class Serializor
{
/**
* Singleton instance for the default Serializor codec.
*
* This is used by static methods such as:
* - {@see Serializor::serialize()}
* - {@see Serializor::unserialize()}
*/
private static ?Codec $singleton = null;
/** @var string|null The default secret key used for serialization security */
private static ?string $defaultSecret = null;
/** @var array Default transformers for serializing closures and anonymous classes */
private static array $defaultTransformers = [];
/** @var Closure|null Custom function for transforming variables used in closures */
private static ?Closure $transformUseVarsFunc = null;
/** @var Closure|null Custom function for resolving variables used in closures */
private static ?Closure $resolveUseVarsFunc = null;
/**
* Serializes the given value using the default Serializor instance.
* This method acts as a replacement for PHP's native `serialize()` function.
*
* @param mixed $value The value to be serialized
*
* @return string The serialized string
*/
public static function serialize(mixed $value): string
{
return self::getInstance()->serialize($value);
}
/**
* Unserializes the given string using the default Serializor instance.
* This method acts as a replacement for PHP's native `unserialize()` function.
*
* @param string $value The serialized string to be unserialized
*
* @return mixed The unserialized value
*/
public static function &unserialize(string $value): mixed
{
return self::getInstance()->unserialize($value);
}
/**
* Retrieves the default Codec instance. This is a singleton, meaning
* only one instance is created and reused across multiple calls.
*
* @return Codec The codec instance for serializing and deserializing data
*/
public static function getInstance(): Codec
{
if (self::$singleton === null) {
self::$singleton = new Codec();
}
return self::$singleton;
}
/**
* Sets a custom secret key for the default Serializor instance, which can be
* used to secure the serialization process.
*
* @param string $secret The secret key to use for serialization
*/
public static function setDefaultSecret(string $secret): void
{
self::$defaultSecret = $secret;
self::updateSingleton();
}
/**
* Sets a custom closure to transform variables used in closures.
*
* @param Closure|null $transformUseVarsFunc The custom transformation function
*/
public static function setTransformUseVarsFunc(?Closure $transformUseVarsFunc = null): void
{
self::$transformUseVarsFunc = $transformUseVarsFunc;
self::updateSingleton();
}
/**
* Sets a custom closure to resolve variables used in closures.
*
* @param Closure|null $resolveUseVarsFunc The custom resolution function
*/
public static function setResolveUseVarsFunc(?Closure $resolveUseVarsFunc = null): void
{
self::$resolveUseVarsFunc = $resolveUseVarsFunc;
self::updateSingleton();
}
/**
* Returns the default set of transformers used for serializing closures
* and anonymous classes.
*
* @return array The default transformers
*/
public static function getDefaultTransformers(): array
{
if (!empty(self::$defaultTransformers)) {
return self::$defaultTransformers;
}
return [
new ClosureTransformer(self::$transformUseVarsFunc, self::$resolveUseVarsFunc),
new AnonymousClassTransformer(),
];
}
/**
* Updates the singleton Codec instance with the latest settings, such as
* the default secret key or custom variable transformation functions.
*/
private static function updateSingleton(): void
{
self::$singleton = new Codec(self::$defaultSecret);
}
/**
* Automatically identifies a machine-specific secret string.
* This secret is intended to be unique to the machine and persistent across reboots.
*
* @return string A machine-specific secret key
* @throws SecretGenerationException If no suitable secret could be generated
*/
public static function getMachineSecret(): string
{
$factory = new SecretGeneratorFactory(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'machine-secret');
try {
return $factory->create(PHP_OS_FAMILY)->generate();
} catch (SecretGenerationException) {
return $factory->create('fallback')->generate();
}
}
}