PHP code example of farzai / json-serializer

1. Go to this page and download the library: Download farzai/json-serializer library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

farzai / json-serializer example snippets


use Farzai\JsonSerializer\JsonSerializer;

// Simple array to JSON
$data = ['name' => 'John', 'age' => 30];
$json = JsonSerializer::encode($data);
// {"name":"John","age":30}

// Object to JSON
class User {
    public function __construct(
        public string $name,
        public int $age
    ) {}
}

$user = new User('John Doe', 30);
$json = JsonSerializer::encode($user);
// {"name":"John Doe","age":30}

// Pretty print
$json = JsonSerializer::encode($user, prettyPrint: true);

// JSON to array
$json = '{"name":"John","age":30}';
$data = JsonSerializer::decode($json);
// ['name' => 'John', 'age' => 30]

// JSON to class
class User {
    public string $name;
    public int $age;
}

$user = JsonSerializer::decodeToClass($json, User::class);
// User instance with name='John', age=30

// JSON array to array of objects
$json = '[{"name":"John","age":30},{"name":"Jane","age":25}]';
$users = JsonSerializer::decodeArray($json, User::class);
// Array of User instances

use Farzai\JsonSerializer\Attributes\Type;
use Farzai\JsonSerializer\JsonSerializer;

class Address {
    public string $street;
    public string $city;
    public string $country;
}

class Author {
    public string $name;
    public string $email;
}

class Book {
    public string $title;
    public Address $publisher;

    #[Type('array<Author>')]
    public array $authors;
}

// Deserialize nested objects and collections
$json = '{
    "title": "PHP Guide",
    "publisher": {
        "street": "123 Main St",
        "city": "NYC",
        "country": "USA"
    },
    "authors": [
        {"name": "John Doe", "email": "[email protected]"},
        {"name": "Jane Smith", "email": "[email protected]"}
    ]
}';

$book = JsonSerializer::decodeToClass($json, Book::class);
// $book->publisher is an Address instance
// $book->authors is an array of Author instances

use Farzai\JsonSerializer\Attributes\{
    SerializedName,
    Ignore,
    DateFormat,
    Since,
    Until,
    VirtualProperty,
    NamingStrategy
};

#[NamingStrategy('snake_case')]
class User {
    #[SerializedName('user_id')]
    public int $id;

    public string $name;

    #[Ignore]
    public string $password;

    #[DateFormat('Y-m-d')]
    public DateTime $createdAt;

    #[Since('2.0')]
    public ?string $email = null;

    #[Until('3.0')]
    public ?string $legacyField = null;

    #[VirtualProperty]
    public function getDisplayName(): string {
        return strtoupper($this->name);
    }
}

// Serialize for version 1.0 (excludes email, ersion('1.0')
    ->build()
    ->encode($user);

// Serialize for version 2.0 (er::builder()
    ->withVersion('3.0')
    ->build()
    ->encode($user);

use Farzai\JsonSerializer\Attributes\Transformer;
use Farzai\JsonSerializer\Attributes\DateFormat;

class Event {
    public string $name;

    #[DateFormat('Y-m-d H:i:s')]
    public DateTime $startTime;

    #[DateFormat(DateFormat::ISO8601)]
    public DateTime $endTime;

    #[Transformer(MyCustomTransformer::class, ['option' => 'value'])]
    public mixed $customField;
}

class FlexibleData {
    public string|int $id;  // Can be string or int
    public User|null $owner; // Can be User object or null
    public string|float $value; // Can be string or float
}

$json = '{"id": "abc123", "owner": null, "value": 3.14}';
$data = JsonSerializer::decodeToClass($json, FlexibleData::class);
// Automatically handles union types

use Farzai\JsonSerializer\Exceptions\DeserializationException;

try {
    $json = '{"name":"John","address":"invalid"}'; // address should be object
    $user = JsonSerializer::decodeToClass($json, UserWithAddress::class);
} catch (DeserializationException $e) {
    echo $e->getMessage();
    // "Type mismatch during deserialization. Property path: address. Type mismatch: expected Address, got string"

    echo $e->getPropertyPath(); // "address"
    echo $e->getExpectedType(); // "Address"
    echo $e->getActualType();   // "string"
}

use Farzai\JsonSerializer\JsonSerializer;
use Farzai\JsonSerializer\Exceptions\SerializationException;

class Node {
    public string $name;
    public ?Node $parent = null;
    public ?Node $child = null;
}

// Create circular reference
$parent = new Node();
$parent->name = 'Parent';

$child = new Node();
$child->name = 'Child';
$child->parent = $parent;

$parent->child = $child; // Circular reference!

try {
    $json = JsonSerializer::encode($parent);
} catch (SerializationException $e) {
    echo $e->getMessage();
    // "Circular reference detected for object of class Node"
}

// Disable circular reference detection if needed
$serializer = JsonSerializer::builder()
    ->withCircularReferenceDetection(false)
    ->build();

// Now it will serialize (may cause infinite loop!)
$json = $serializer->encode($parent);

use Farzai\JsonSerializer\Builder\SerializerBuilder;

$serializer = SerializerBuilder::create()
    ->withVersion('2.0')
    ->withMaxDepth(100)
    ->withPrettyPrint(true)
    ->build();

$json = $serializer->encode($data);

use Farzai\JsonSerializer\JsonSerializer;
use Farzai\JsonSerializer\Exceptions\SerializationException;

// Configure security limits
$serializer = JsonSerializer::builder()
    ->withMaxDepth(50)                          // Prevent deeply nested structures
    ->withCircularReferenceDetection(true)      // Detect circular references (default: true)
    ->withStrictTypes(true)                     // Enable strict type checking (default: true)
    ->build();

// Example: Max depth protection
class DeepNested {
    public ?DeepNested $child = null;
}

$root = new DeepNested();
$current = $root;
for ($i = 0; $i < 100; $i++) {
    $current->child = new DeepNested();
    $current = $current->child;
}

try {
    $json = $serializer->encode($root);
} catch (SerializationException $e) {
    echo $e->getMessage();
    // "Maximum depth of 50 exceeded"
}

// Strict types mode prevents unsafe type coercion
$strictSerializer = JsonSerializer::builder()
    ->withStrictTypes(true)
    ->build();

// Disable strict mode for more lenient serialization
$lenientSerializer = JsonSerializer::builder()
    ->withStrictTypes(false)
    ->build();

use Farzai\JsonSerializer\Engine\DeserializerEngine;
use Farzai\JsonSerializer\Engine\DeserializationContext;
use Farzai\JsonSerializer\Types\TypeCoercionMode;
use Farzai\JsonSerializer\JsonSerializer;

class TypedData {
    public int $id;
    public string $name;
    public float $score;
    public bool $active;
}

// STRICT Mode - No coercion, throw on mismatch
$context = new DeserializationContext(
    typeCoercionMode: TypeCoercionMode::STRICT
);
$deserializer = new DeserializerEngine;
$data = $deserializer->deserializeToClass($json, TypedData::class, $context);
// {"id": "123"} → Throws DeserializationException

// SAFE Mode - Conservative coercion (DEFAULT)
$context = new DeserializationContext(
    typeCoercionMode: TypeCoercionMode::SAFE  // This is the default
);
$deserializer = new DeserializerEngine;
$data = $deserializer->deserializeToClass($json, TypedData::class, $context);
// {"id": "123"} → id = 123 (int)
// {"score": "3.14"} → score = 3.14 (float)
// {"active": "true"} → active = true (bool)
// {"active": 1} → active = true (bool)

// LENIENT Mode - Aggressive coercion
$context = new DeserializationContext(
    typeCoercionMode: TypeCoercionMode::LENIENT
);
$deserializer = new DeserializerEngine;
$data = $deserializer->deserializeToClass($json, TypedData::class, $context);
// {"id": "abc123"} → id = 123 (extracts number)
// {"name": 123} → name = "123" (cast to string)
// {"active": "yes"} → active = true (bool)
// {"active": "no"} → active = false (bool)

// Configure default deserializer for all static methods
$customDeserializer = new DeserializerEngine(
    defaultTypeCoercionMode: TypeCoercionMode::LENIENT
);
JsonSerializer::setDefaultDeserializer($customDeserializer);

// Now all JsonSerializer::decodeToClass() calls use LENIENT mode
$data = JsonSerializer::decodeToClass($json, TypedData::class);

use Farzai\JsonSerializer\Contracts\TypeHandlerInterface;
use Farzai\JsonSerializer\Engine\SerializationContext;
use Farzai\JsonSerializer\JsonSerializer;

// Custom type handler for Money objects
class MoneyTypeHandler implements TypeHandlerInterface
{
    public function supports(mixed $value): bool
    {
        return $value instanceof Money;
    }

    public function serialize(mixed $value, SerializationContext $context): string
    {
        /** @var Money $value */
        return json_encode([
            'amount' => $value->getAmount(),
            'currency' => $value->getCurrency()
        ]);
    }

    public function getPriority(): int
    {
        return 100; // Higher priority = checked first
    }
}

// Register custom handler
$serializer = JsonSerializer::builder()
    ->addTypeHandler(new MoneyTypeHandler())
    ->build();

// Use with custom type
$price = new Money(1999, 'USD');
$json = $serializer->encode($price);
// {"amount":1999,"currency":"USD"}

use Farzai\JsonSerializer\JsonSerializer;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;

// Create PSR-16 cache (using Symfony Cache as example)
$filesystemAdapter = new FilesystemAdapter();
$cache = new Psr16Cache($filesystemAdapter);

// Configure serializer with cache
$serializer = JsonSerializer::builder()
    ->withCache($cache)
    ->build();

// Metadata for classes is now cached
// First serialization: analyzes class metadata
$json1 = $serializer->encode($user);

// Subsequent serializations: uses cached metadata (much faster!)
$json2 = $serializer->encode($anotherUser);

use Farzai\JsonSerializer\JsonSerializer;

// Stream large JSON file
$stream = JsonSerializer::streamFromFile('large-data.json');

// Iterate over array elements
foreach ($stream->iterateArray() as $item) {
    // Process each item without loading entire array
    echo $item['name'];
}

// Iterate over object fields
foreach ($stream->iterateObject() as [$key, $value]) {
    echo "$key => $value\n";
}

class User {
    public string $name;
    public string $email;
}

// Lazy load and deserialize array elements
$iterator = JsonSerializer::iterateFile('users.json', User::class);

// Only loads items as you iterate
foreach ($iterator as $user) {
    echo $user->name; // User object created on-demand
}

// Functional operations without loading all data
$adults = $iterator->filter(fn($user) => $user->age >= 18);
$names = $iterator->map(fn($user) => $user->name);
$first10 = $iterator->take(10);
$afterFirst100 = $iterator->skip(100);

// Extract single value
$name = JsonSerializer::extractPath('data.json', '.user.name');

// Extract nested field
$email = JsonSerializer::extractPath('data.json', '.user.profile.email');

// Extract array element
$firstItem = JsonSerializer::extractPath('data.json', '.items[0]');

// Extract multiple paths at once
$values = JsonSerializer::extractPaths('data.json', [
    '.user.name',
    '.user.email',
    '.settings.theme'
]);

// Process 1GB+ JSON file with constant memory usage
$iterator = JsonSerializer::iterateFile('huge-dataset.json');

$count = 0;
$sum = 0;

foreach ($iterator->take(1000) as $item) {
    $count++;
    $sum += $item['value'];
}

echo "Average: " . ($sum / $count);

use Farzai\JsonSerializer\JsonSerializer;

// Simple generator - sequential array
function getUsers(): Generator {
    for ($i = 1; $i <= 1000; $i++) {
        yield ['id' => $i, 'name' => "User {$i}"];
    }
}

$json = JsonSerializer::encode(getUsers());
// [{"id":1,"name":"User 1"},{"id":2,"name":"User 2"},...]

// Generator yielding objects
function getUserObjects(): Generator {
    for ($i = 1; $i <= 1000; $i++) {
        yield new User(id: $i, name: "User {$i}");
    }
}

$json = JsonSerializer::encode(getUserObjects());

// Associative generator - JSON object
function getConfig(): Generator {
    yield 'app_name' => 'MyApp';
    yield 'version' => '1.0.0';
    yield 'debug' => false;
}

$json = JsonSerializer::encode(getConfig());
// {"app_name":"MyApp","version":"1.0.0","debug":false}

// Nested generators
function getCategories(): Generator {
    yield 'electronics' => getProducts('electronics');
    yield 'books' => getProducts('books');
}

function getProducts(string $category): Generator {
    // Fetch products from database one at a time
    foreach ($db->query("SELECT * FROM products WHERE category = ?", [$category]) as $row) {
        yield $row;
    }
}

// Serialize nested generators without loading all data into memory
$json = JsonSerializer::encode(getCategories());

// Problem: Fatal error: Allowed memory size exhausted
// Solution 1: Use streaming for large files
$iterator = JsonSerializer::iterateFile('large-file.json', User::class);
foreach ($iterator as $user) {
    // Process one at a time
}

// Solution 2: Increase max depth limit
$serializer = JsonSerializer::builder()
    ->withMaxDepth(100) // Reduce if hitting memory limits
    ->build();

// Problem: Type mismatch during deserialization
// Solution: Use LENIENT type coercion mode
use Farzai\JsonSerializer\Types\TypeCoercionMode;
use Farzai\JsonSerializer\Engine\DeserializationContext;

$context = new DeserializationContext(
    typeCoercionMode: TypeCoercionMode::LENIENT
);

$deserializer = new DeserializerEngine;
$data = $deserializer->deserializeToClass($json, MyClass::class, $context);

// Problem: Circular reference detected
// Solution 1: Fix data structure (recommended)
// Solution 2: Disable detection (use with caution)
$serializer = JsonSerializer::builder()
    ->withCircularReferenceDetection(false)
    ->build();

// Problem: Serialization too slow
// Solution 1: Use native functions for simple data
$json = json_encode($simpleArray);

// Solution 2: Enable PSR-16 cache for metadata
$serializer = JsonSerializer::builder()
    ->withCache($psr16Cache)
    ->build();

// Solution 3: Use streaming for large data
JsonSerializer::encodeToFile($data, 'output.json');

// Problem: Maximum depth exceeded
// Solution: Increase max depth limit
$serializer = JsonSerializer::builder()
    ->withMaxDepth(1000) // Default is 512
    ->build();