Universal.Common.Serialization.Php 1.1.1

dotnet add package Universal.Common.Serialization.Php --version 1.1.1
                    
NuGet\Install-Package Universal.Common.Serialization.Php -Version 1.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Universal.Common.Serialization.Php" Version="1.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Universal.Common.Serialization.Php" Version="1.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Universal.Common.Serialization.Php" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Universal.Common.Serialization.Php --version 1.1.1
                    
#r "nuget: Universal.Common.Serialization.Php, 1.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Universal.Common.Serialization.Php@1.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Universal.Common.Serialization.Php&version=1.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Universal.Common.Serialization.Php&version=1.1.1
                    
Install as a Cake Tool

Universal.Common.Serialization.Php

A .NET library for deserializing PHP serialized data into .NET objects. Deserialization only - this library focuses on reading PHP serialized data, not writing it.

Note: This library exists to help you escape PHP serialization hell. If you had a choice, I know you would have chosen JSON instead. This library is here to do this one thing well - deserialize PHP data with the same level of quality and performance as System.Text.Json does for JSON.

Scope

  • ✅ Deserializes PHP serialize() output to .NET types
  • ✅ Handles primitives, arrays, objects, references, and enums
  • Maps PHP arrays/objects to strongly-typed C# classes (most libraries only support dictionaries)
  • ✅ Supports constructor parameter binding and property mapping
  • ❌ Does not serialize .NET objects to PHP format
  • ❌ Does not map PHP class names to C# class names (use property mapping instead)
  • ❌ Does not preserve PHP visibility modifiers (public/protected/private)

Quick Start

using Universal.Common.Serialization.Php;

// Recommended: From byte array (most PHP data comes base64-encoded)
byte[] phpData = Convert.FromBase64String("czoxMToiaGVsbG8gd29ybGQiOw==");
string greeting = PhpSerializer.Deserialize<string>(phpData);
// Result: "hello world"

// Deserialize to strongly-typed class
string phpUserData = "a:2:{s:4:\"name\";s:4:\"John\";s:3:\"age\";i:30;}";
var user = PhpSerializer.Deserialize<User>(
    phpUserData, 
    Encoding.UTF8);
// user.Name = "John", user.Age = 30

// Or as a dictionary when structure is unknown
var data = PhpSerializer.Deserialize<Dictionary<string, object>>(
    phpUserData, 
    Encoding.UTF8);
// data["name"] = "John", data["age"] = 30L

Supported Types

Primitives

  • Strings: s:5:"hello";string
  • Integers: i:42;int, long
  • Booleans: b:1;bool
  • Doubles: d:3.14;double, float
  • Null: N;null

Collections

  • PHP arrays → Dictionary<TKey, TValue>, List<T>, T[], HashSet<T>
  • Nested arrays supported

Objects

  • PHP objects → Custom classes via property mapping
  • Supports parameterless constructors and constructor parameter binding
  • Case-insensitive property matching (configurable)

Advanced

  • References: r:2; and R:1; (requires TrackReferences = true)
  • PHP 8.1+ Enums: E:25:"Permission:manage";
  • DateTime from strings or Unix timestamps
  • GUIDs from string representations

Configuration

var options = new PhpSerializerOptions
{
    TrackReferences = true,                    // Handle PHP references
    MaxDepth = 64,                              // Prevent stack overflow
    PropertyNameCaseInsensitive = true,         // Case-insensitive property matching
    DefaultEncoding = Encoding.UTF8,            // String encoding (important!)
    AllowTrailingData = false,                  // Reject extra data after valid PHP
    IgnoreNullValues = false,                   // How to handle null values
    NumberHandling = PhpNumberHandling.Strict   // String-to-number coercion
};

var result = PhpSerializer.Deserialize<MyClass>(data, options);

Custom Converters

public class CustomDateTimeConverter : PhpConverter<DateTime>
{
    public override DateTime Read(ref PhpReader reader, Type typeToConvert, 
        PhpSerializerOptions options, PhpDeserializationContext context)
    {
        string dateStr = reader.GetString(options.DefaultEncoding);
        return DateTime.ParseExact(dateStr, "Y-m-d H:i:s", CultureInfo.InvariantCulture);
    }
}

var options = new PhpSerializerOptions();
options.Converters.Add(new CustomDateTimeConverter());

Attributes

public class User
{
    // Could also use PhpNamingPolicy.SnakeCaseToPascalCase
    [PhpPropertyName("user_id")] 
    public int UserId { get; set; }
    
    [PhpIgnore]
    public string InternalField { get; set; }
    
    [PhpExtensionData]
    public Dictionary<string, object> ExtraData { get; set; }
}

Important: String Encoding

PHP strings are byte strings with no inherent encoding. Always specify the encoding used by your PHP application:

// UTF-8 (most common)
PhpSerializer.Deserialize<T>(data, Encoding.UTF8, options);

// Latin-1 (ISO-8859-1)
PhpSerializer.Deserialize<T>(data, Encoding.GetEncoding("ISO-8859-1"), options);

// Windows-1252
PhpSerializer.Deserialize<T>(data, Encoding.GetEncoding("windows-1252"), options);

Wrong encoding = garbage data. When in doubt, ask your PHP developers.

Mapping PHP Property Names

PHP often uses snake_case while C# uses PascalCase. Choose your strategy:

Strategy 1: Attributes (Fine-grained Control)

public class User
{
    [PhpPropertyName("user_id")]
    public int UserId { get; set; }
    
    [PhpPropertyName("first_name")]
    public string FirstName { get; set; }
}

Pros: Explicit, works for one-off mappings
Cons: Verbose if you have many properties

Strategy 2: Naming Policy (Convention-based)

var options = new PhpSerializerOptions
{
    PropertyNamingPolicy = PhpNamingPolicy.SnakeCaseToPascalCase
};

var user = PhpSerializer.Deserialize<User>(data, options);

public class User
{
    public int UserId { get; set; }      // Matches "user_id"
    public string FirstName { get; set; } // Matches "first_name"
}

Pros: Clean, works across all types, no attributes needed
Cons: All-or-nothing, can't override individual properties

Strategy 3: Hybrid (Best of Both)

var options = new PhpSerializerOptions
{
    PropertyNamingPolicy = PhpNamingPolicy.SnakeCaseToPascalCase
};

public class User
{
    public int UserId { get; set; }      // Uses naming policy
    
    [PhpPropertyName("legacy_field_name")]  // Override for exceptions
    public string WeirdField { get; set; }
}

Note: [PhpPropertyName] takes precedence over naming policies.

Error Handling

try
{
    var result = PhpSerializer.Deserialize<MyClass>(data);
}
catch (PhpSerializationException ex)
{
    // Invalid PHP format, type mismatch, or reference error
    Console.WriteLine($"Deserialization failed: {ex.Message}");
}

Thread Safety

  • PhpSerializerOptions is thread-safe and can be reused
  • PhpSerializer static methods are thread-safe
  • PhpDeserializationContext is per-operation and NOT thread-safe

Limitations

If you need to:

  • Serialize .NET objects back to PHP format → Not supported
  • Preserve PHP class names so we can round-trip the data → Not our problem
  • Handle PHP's Serializable interface → Write a custom converter
  • Deal with recursive references without TrackReferences → Enable TrackReferences

Good luck!

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.1 714 12/3/2025
1.1.0 677 12/3/2025
1.0.0 680 12/3/2025

Fixed custom converter precedence.