Files
michaelschiemer/src/Framework/Serializer
Michael Schiemer cf0ad6e905 refactor: improve logging system and add deployment fixes
- Enhance logging handlers (Console, DockerJson, File, JsonFile, MultiFile)
- Improve exception and line formatters
- Update logger initialization and processor management
- Add Ansible playbooks for staging 502 error troubleshooting
- Update deployment documentation
- Fix serializer and queue components
- Update error kernel and queued log handler
2025-11-02 01:37:49 +01:00
..

Serializer Module

The Serializer module provides a unified way to serialize and deserialize data in various formats. It supports JSON and PHP serialization with plans to add more formats in the future.

Features

  • Unified interface for all serializers
  • Type-safe serialization and deserialization
  • Robust error handling
  • Configurable serialization options
  • Factory methods for common configurations

Usage

Basic Usage

use App\Framework\Serializer\SerializerFactory;

// Create a JSON serializer with default settings (pretty print)
$serializer = SerializerFactory::createJsonSerializer();

// Serialize data
$data = ['name' => 'John', 'age' => 30];
$json = $serializer->serialize($data);

// Deserialize data
$deserializedData = $serializer->deserialize($json);

Serialization Options

The module provides several factory methods for common serialization configurations:

// Pretty-printed JSON (default)
$prettySerializer = SerializerFactory::createPrettyJsonSerializer();
$prettyJson = $prettySerializer->serialize($data);
// Result: {
//     "name": "John",
//     "age": 30
// }

// Compact JSON (no whitespace)
$compactSerializer = SerializerFactory::createCompactJsonSerializer();
$compactJson = $compactSerializer->serialize($data);
// Result: {"name":"John","age":30}

// Minimal JSON (no special flags)
$minimalSerializer = SerializerFactory::createMinimalJsonSerializer();
$minimalJson = $minimalSerializer->serialize($data);
// Result: {"name":"John","age":30}

Custom Configuration

You can create a serializer with custom configuration:

// Custom JSON serializer with specific flags
$customSerializer = SerializerFactory::createCustomJsonSerializer(
    JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE,
    256 // Max depth
);

// Serialize an array as an object
$data = ['a', 'b', 'c'];
$json = $customSerializer->serialize($data);
// Result: {"0":"a","1":"b","2":"c"}

Using Config Objects Directly

You can also create and use config objects directly:

use App\Framework\Serializer\Json\JsonSerializer;
use App\Framework\Serializer\Json\JsonSerializerConfig;

// Create a config object
$config = new JsonSerializerConfig(
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES,
    512
);

// Create a serializer with the config
$serializer = new JsonSerializer($config);

// Or use the factory methods on the config class
$compactConfig = JsonSerializerConfig::compact();
$prettyConfig = JsonSerializerConfig::pretty();
$minimalConfig = JsonSerializerConfig::minimal();

// Create serializers with these configs
$compactSerializer = new JsonSerializer($compactConfig);
$prettySerializer = new JsonSerializer($prettyConfig);
$minimalSerializer = new JsonSerializer($minimalConfig);

Exception Handling

The serializer module provides a dedicated exception hierarchy for better error handling:

  • SerializerException: Base exception for all serializer-related exceptions
    • SerializeException: Thrown when serialization fails
    • DeserializeException: Thrown when deserialization fails

Example of handling deserialization errors:

use App\Framework\Serializer\SerializerFactory;
use App\Framework\Serializer\Exception\SerializeException;
use App\Framework\Serializer\Exception\DeserializeException;

$serializer = SerializerFactory::createJsonSerializer();

try {
    // Try to deserialize invalid JSON
    $data = $serializer->deserialize('{"name": "John", }'); // Invalid JSON
} catch (DeserializeException $e) {
    // Handle deserialization errors
    echo "Deserialization error: " . $e->getMessage();
} catch (SerializeException $e) {
    // Handle serialization errors
    echo "Serialization error: " . $e->getMessage();
} catch (SerializerException $e) {
    // Handle other serializer-related errors
    echo "Serializer error: " . $e->getMessage();
}

MIME Type and File Extension

The serializer provides methods to get the MIME type and file extension:

$serializer = SerializerFactory::createJsonSerializer();

// Get MIME type
$mimeType = $serializer->getMimeType(); // "application/json"

// Get file extension
$extension = $serializer->getFileExtension(); // "json"

Migration from Legacy Serializers

If you're using the legacy serializers, here's how to migrate:

From Cache JsonSerializer

// Old code
use App\Framework\Cache\Serializer\JsonSerializer;
$serializer = new JsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->unserialize($json);

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createJsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);

From Filesystem JsonSerializer

// Old code
use App\Framework\Filesystem\Serializers\JsonSerializer;
$serializer = new JsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);

// Factory methods
$compactSerializer = JsonSerializer::compact();
$prettySerializer = JsonSerializer::pretty();
$minimalSerializer = JsonSerializer::minimal();

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createJsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);

// Factory methods
$compactSerializer = SerializerFactory::createCompactJsonSerializer();
$prettySerializer = SerializerFactory::createPrettyJsonSerializer();
$minimalSerializer = SerializerFactory::createMinimalJsonSerializer();

Direct Usage of JsonSerializer

If you need direct access to the JsonSerializer class:

use App\Framework\Serializer\Json\JsonSerializer;

// Create with default settings
$serializer = new JsonSerializer();

// Create with custom settings
$serializer = new JsonSerializer(
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES,
    512
);

// Use factory methods
$compactSerializer = JsonSerializer::compact();
$prettySerializer = JsonSerializer::pretty();
$minimalSerializer = JsonSerializer::minimal();

PHP Serialization

The module also provides PHP serialization capabilities with a focus on security.

Basic Usage

use App\Framework\Serializer\SerializerFactory;

// Create a PHP serializer with default settings (safe with no allowed classes)
$serializer = SerializerFactory::createPhpSerializer();

// Serialize data
$data = ['name' => 'John', 'age' => 30];
$serialized = $serializer->serialize($data);

// Deserialize data
$deserializedData = $serializer->deserialize($serialized);

Security Considerations

PHP serialization can be a security risk if used improperly, as it allows arbitrary code execution through object deserialization. The PHP serializer in this module is designed with security in mind:

  • By default, no classes are allowed to be unserialized (only primitive types and arrays)
  • You can explicitly specify which classes are allowed to be unserialized
  • You can create an unsafe serializer if you need to deserialize any class (use with caution)

Safe and Unsafe Deserialization

use App\Framework\Serializer\SerializerFactory;

// Safe serializer with specific allowed classes
$safeSerializer = SerializerFactory::createSafePhpSerializer(['stdClass', 'DateTime']);

// Unsafe serializer (allows all classes - use with caution)
$unsafeSerializer = SerializerFactory::createUnsafePhpSerializer();

Custom Configuration

You can create a serializer with custom options:

use App\Framework\Serializer\SerializerFactory;

// Custom PHP serializer with specific allowed classes and max depth
$customSerializer = SerializerFactory::createCustomPhpSerializer(
    ['MyClass', 'MyOtherClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);

Using PhpSerializer with Config Objects

You can create and use PHP serializer config objects directly:

use App\Framework\Serializer\Php\PhpSerializer;
use App\Framework\Serializer\Php\PhpSerializerConfig;

// Create with default settings (safe with no allowed classes)
$serializer = new PhpSerializer();

// Create a config object with custom options
$config = new PhpSerializerConfig(
    ['MyClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);

// Create a serializer with the config
$serializer = new PhpSerializer($config);

// Or use the factory methods on the config class
$safeConfig = PhpSerializerConfig::safe(
    ['stdClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);
$unsafeConfig = PhpSerializerConfig::unsafe(
    4096 // max depth (optional, defaults to 4096)
);

// Create serializers with these configs
$safeSerializer = new PhpSerializer($safeConfig);
$unsafeSerializer = new PhpSerializer($unsafeConfig);

Migration from Legacy PHP Serializers

If you're using the legacy PHP serializers, here's how to migrate:

From Cache PhpSerializer

// Old code
use App\Framework\Cache\Serializer\PhpSerializer;
$serializer = new PhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->unserialize($serialized);

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createUnsafePhpSerializer(); // For backward compatibility
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($serialized);

From Filesystem PhpSerializer

// Old code
use App\Framework\Filesystem\Serializers\PhpSerializer;
$serializer = new PhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($data);

// Factory methods
$safeSerializer = PhpSerializer::safe(['stdClass']);
$unsafeSerializer = PhpSerializer::unsafe();

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createPhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($serialized);

// Factory methods
$safeSerializer = SerializerFactory::createSafePhpSerializer(['stdClass']);
$unsafeSerializer = SerializerFactory::createUnsafePhpSerializer();