amphp/serialization
AMPHP serialization tools for IPC and storage in PHP. Provides a Serializer interface with JSON, native PHP serialize/unserialize, and passthrough implementations, plus optional payload compression via a wrapping serializer.
Installation:
composer require amphp/serialization
Ensure your project uses PHP 7.4+ (hard requirement).
First Use Case: Serialize a complex object (e.g., a closure or resource) for IPC in an AMPHP-based worker:
use Amp\Serialization\NativeSerializer;
$serializer = new NativeSerializer();
$data = [
'task' => fn() => 'async-work',
'resource' => fopen('php://memory', 'r+')
];
$serialized = $serializer->serialize($data);
Where to Look First:
Serializer interface: Core contract for serialize()/unserialize().NativeSerializer: For full PHP type support (closures, resources).CompressingSerializer: Wrap any serializer for payload size reduction.SerializationException for debugging.IPC Workflows:
$serializer = new CompressingSerializer(new NativeSerializer());
$payload = $serializer->serialize($taskData);
socket_write($socket, $payload);
$data = $serializer->unserialize(socket_read($socket));
AMPHP Integration:
$serializer = new NativeSerializer();
$closure = fn() => $serializer->unserialize($storedData);
$stream->write($serializer->serialize($closure));
Hybrid Serialization:
$serializer = $isIpc ? new NativeSerializer() : new JsonSerializer();
Compression Strategy:
CompressingSerializer:
$compressedSize = strlen($serializer->serialize($data));
$uncompressedSize = strlen((new NativeSerializer())->serialize($data));
Queue Jobs (AMPHP Workers):
$job = new AsyncJob($data);
$serializer = new CompressingSerializer(new NativeSerializer());
$payload = $serializer->serialize($job);
dispatch($payload)->onQueue('async');
Cache Layer:
Cache::put('template:large', $serializer->serialize($template), now()->addHours(1));
Shared Memory:
NativeSerializer for cross-process object sharing (e.g., Amp\Artisan\Process):
$sharedData = $serializer->serialize($config);
shared_memory_write($segment, $sharedData);
Laravel Service Provider: Bind serializers as singletons for dependency injection:
$this->app->singleton('serializer.native', fn() => new NativeSerializer());
$this->app->singleton('serializer.compressed', fn($app) =>
new CompressingSerializer($app->make('serializer.native'))
);
Middleware for IPC: Wrap AMPHP IPC requests/responses:
public function handle($request, Closure $next) {
$data = $serializer->unserialize($request->getContent());
$response = $next($data);
return response($serializer->serialize($response));
}
Fallback Strategy: Implement a decorator to fallback to JSON for unsupported types:
class SafeSerializer implements Serializer {
public function unserialize(string $data) {
try {
return $this->serializer->unserialize($data);
} catch (SerializationException $e) {
return json_decode($data, true);
}
}
}
PHP 7.4+ Hard Requirement:
#[Override] attributes may conflict with Laravel’s attributes (e.g., #[Cacheable]).Unserialize Security:
NativeSerializer is unsafe for untrusted data. Always validate:
if (!in_array(gettype($data), ['array', 'object', 'string'])) {
throw new \RuntimeException('Unsafe data type');
}
Circular References:
NativeSerializer may fail on circular references. Use JsonSerializer as a fallback:
try {
return $nativeSerializer->unserialize($data);
} catch (SerializationException $e) {
return json_decode($data, true);
}
Resource Leaks:
fclose($resource);
$serialized = $serializer->serialize(['resource' => $resource]);
Compression Overhead:
CompressingSerializer adds CPU overhead. Benchmark for small payloads (<1KB):
$microtime = microtime(true);
$compressed = $compressedSerializer->serialize($data);
$time = microtime(true) - $microtime;
// Abort if compression adds >10% latency
SerializationException:
DateTimeImmutable, Closure):
catch (SerializationException $e) {
Log::error('Unsupported type: ' . gettype($data), ['exception' => $e]);
}
Corrupted Data:
if (!is_string($data) || strlen($data) < 10) {
throw new \InvalidArgumentException('Invalid serialized data');
}
Fiber Context:
Amp\async(function() use ($serializer, $data) {
$serialized = $serializer->serialize($data);
// ...
});
Compression Level:
CompressingSerializer uses default zlib compression. Adjust via constructor:
$compressor = new \Amp\Serialization\CompressingSerializer(
$serializer,
['level' => 9] // Max compression
);
Native Serializer Quirks:
__serialize()/__unserialize().PassthroughSerializer:
$passthrough = new PassthroughSerializer();
$data = $passthrough->unserialize($externalString);
Custom Serializers:
Serializer for domain-specific logic:
class EloquentSerializer implements Serializer {
public function serialize($model) {
return serialize($model->toArray());
}
public function unserialize(string $data) {
return Model::hydrate(unserialize($data));
}
}
Decorator Pattern:
class LoggingSerializer implements Serializer {
public function serialize($data) {
Log::debug('Serializing', ['data' => gettype($data)]);
return $this->serializer->serialize($data);
}
}
Attribute-Based Serialization:
#[Override] for custom logic (PHP 7.4+ only):
#[Override]
public function serialize($data) {
// Custom logic
}
How can I help you explore Laravel packages today?