- Target .NET 10.0 (now targeting 8, 9 and 10).
- Fixed
nullvalues cause improper de-referencing when they occur before a reference. - Fixed a similar issue caused by the handling of value references (as opposed to variable references).
- Deserializing into a
PhpObjectDictionarywith an integer key failed with an invalid cast exception. #43.
- Some minor performance improvements in the validation step of deserialization.
- Add support for references (
r:1;)
- Fixed a bug where integers with a plus sign where deserialized incorrectly
i:+1;was deserialized as49.
- Fixed validation error when deserializing a list of objects. The deserializer would check the wrong token for it's
datatype and throw and exception like this:
Can not deserialize array at position [x] to list: It has a non-integer key 'name' at element [y]GH #40 - Related to the above: Some nested arrays or arrays with object values would never implicetly deserialize into a
List<object>because the check if the array keys are consecutive integers was faulty. - Do not throw when a property or field is decorated with it's own name such as
[PhpProperty["A"]] public int A;.
- Now targets .NET 8.0 and .NET 9.0
PhpTokenizerclass is now internal.- Removed support for
net6.0andnet7.0. - The default implicit type for numeric values is now
intinstead oflong1.x:PhpSerialization.Deserialize("i:42;") == 42L2.x:PhpSerialization.Deserialize("i:42;") == 42 - Changed the signature of
[PhpPropery(long)]to[PhpPropery(long)]to align with the above change.
- Added
PhpSerialization.DeserializeUtf8(ReadOnlySpan<byte>)overloads for cases in which consumers directly work with UTF8 inputs and can skip the re-encoding. - Added
PhpSerializationFilterattribute base class, allowing customization of class and struct member serialization. See thePhpSerializationFilterTestfor an example. See also Issue #33.
- Integers and doubles without a value now give a better error message (
i:;andd:;).
- Reduced time to decode / re-encode the input string.
- Reduced memory allocations both in the input re-encoding and the deserialization.
- Delay the materialization of strings when deserializing. This can avoid string allocations entirely for integers, doubles and booleans.
- Improved performance for implicit deserialization of integers as well as minor improvements for implicit deserialization of arrays.
- Improved serialization performance for strings, integers,
IList<T>,ExpandoObject, Dictionaries andPhpDynamicObject
Split the deserialization into 3 phases:
- Validation of the input and counting of the data tokens.
- Parsing of the input into tokens
- Deserializations of the tokens into the target C# objects/structs.
In version 1.4 and prior, this was a 2 step process. This is slightly slower on some inputs, but overall a little neater because we're cleanly separating the tasks.
- Now targets .NET 6.0, 7.0 and 8.0
- Improved tokenization performance by allowing and forcing more aggresive inlining.
- In my benchmark, this is about 8 to 9% faster
- Removed net5 support and added net7 support
- Added overload of
[PhpProperty()]that accepts integer / long keys. See #32 - Allow deserialization of Objects with integer keys
- Made type information caches thread safe.
- Added support for PhpProperty on enums, allowing consumers to specify different field names
- Performance: Cache enum field information with
TypeCacheFlag.PropertyInfo.
This is just 0.11.0 packaged as a new version to mark it as stable.
Deserialization:
- Added
string Serialize(object? input, PhpSerializiationOptions? options = null)toPhpSerializationso the target type can be specified at run time. PhpSerialization(entry point of the library) is now null reference aware, aiding library consumers in cachingNullReferenceException.PhpSerializationthrowsArgumentOutOfRangeExceptioninstead of the more generalisedArgumentException- Bugfix: "INF" and "-INF" would not be handled correctly when using explicit typing (
Deserialize<T>) for some target types. - Bugfix: Properly set classname when deserializing with explicit types that implement IPhpObject.
- Bugfix: With the AllowExcessKeys, the deserialization of the given struct or object would abort when an excess key was encountered, leaving the properties after the excess key unassigned. See issue #27.
- Performance tweaks:
- Minor improvements on memory use during deserialization.
- Improved performance for deserializing Double and Integer values with explicit types.
General:
- Bugfix:
PhpSerialization.ClearTypeCache()was not exposed. - Bugfix:
PhpSerialization.ClearPropertyInfoCache()was not exposed.
- Trying to set the classname on PhpDateTime will throw an exception now instead of doing nothing.
- Behavior of the option
EmptyStringToDefaultchanged:- And empty string will now result in
default(string)(which is null) instead of an empty string. - For some target types, the return value might have changed due to better checks for the proper default value.
- And empty string will now result in
Beware: EmptyStringToDefault is enabled by default.
Deserialization:
- Added support for
Nullable<> - Added
PhpSerializerNET.ClearTypeCache() - Added
TypeCachedeserialization option- Allows to disable the classname type cache. (enabled by default)
- Allows to enable a property information cache. (disabled by default)
- Added
PhpSerializerNET.ClearPropertyInfoCache() - When converting to an enum member that is not known a better exception is thrown instead of a nullref (because the fieldinfo cannot be found)
- Added support for arrays
Serialization:
- Added support for serializing
PhpDynamicObjectandExpandoObject. - Always serialize implementations of
IPhpObjectusing object notation. This is technically a breaking change, but it was always intended to work that way.
- Targeting net6.0
- Type lookup: Now negative lookup results are also cached.
- This may also lead to undeseriable results when adding classes and structs at runtime.
- May increase the memory footprint over time faster than before.
- On the upside: It is significantly faster when dealing with objects where automapping doesn't work without having to disable the feature entirely.
- Different exception (System.ArgumentException) on empty input for
PhpSerialization.Deserialize<T>()
- Rewrote the parsing and validation logic, which results in different exception messages in many cases.
- Parsing: A very slight performance gain for some deserialization workloads.
- Object / struct creation: Improved performance.
- General: Reduced amount of memory allocated while deserializing.
- Fixed exception message for non-integer keys in lists.
- Fixed exception message for failed field / property assignments / binding.
- Improved performance of the validation step of deserialization.
- Sped up deserializing into explicit types (particularly structs and classes) significantly.
- Sped up serialization, especially when using attribute annotated classes and structs.
- Improved exception messages on malformed inputs when deserializing.
- Cleaner exception when trying to deserialize into incompatible types (i.e. "a" to int32.).
- Improved deserialization performance.
- Fixed invalid output when using PhpSerializiationOptions.NumericEnums = false
- Fixed an issue with empty string deserialization, caused by the
EmptyStringToDefaultcode in 0.7.2.
- Added
EmptyStringToDefaultdeserialization option, defaults to true.- When true, empty strings will be deserialized into the default value of the target IConvertible.
For example
s:0:"";deserialized to an integer yields0. See issue #13 for details.
- When true, empty strings will be deserialized into the default value of the target IConvertible.
For example
- Fixed a regression introduced in 0.7.1 where some data would no longer parse correctly (#12) due to improper handling of array brackets.
- Fixed issue with nested array / object validation (issue #11)
- Added support for System.Guid (issue #10)
- Support de/serialization of enums
- Added serialization option
NumericEnums: Whether or not to serialize enums as integer values Defaults to true. If set to false, the enum.ToString() representation will be used.
- Allow more (valid) characters in object class names.
- Added public interface IPhpObject
- Added public class PhpObjectDictionary (implementing IPhpObject).
- This replaces
IDictionary<string, object>as the default deserialization target of objects.
- This replaces
- Added public class PhpDynamicObject (implementing IPhpObject)
- Added PhpDateTime to avoid conflicts with System.DateTime.
With IPhpObjects, you can get the class name specified in the serialized data via GetClassName().
Known issues:
- Can not deserialize dynamic objects.
- Fixed misleading exception message on malformed objects.
- Fixed valid classnames being rejected as malformed.
- Fixed type-lookup logic trying to deserialize with
nullType information.
Known issues:
Objects with classname(fixed since)DateTimewill fail to deserialize, unless the optionEnableTypeLookupis set tofalse.
BREAKING
- Renamed the static class
PhpSerializertoPhpSerialization
Other changes:
- Added support for object de/serialization (
O:4:"name":n:{...}). - Added
[PhpClass()]attribute. - Added
StdClassandEnableTypeLookupto deserialization options - Added options for
PhpSerialization.Serialize().ThrowOnCircularReferences- whether or not to throw on circular references, defaults to false (this might change in the future.)
- Updated and adjusted some of the XML documentation.
- Support for structs.
- Fixed performance drop due to over-checking the input string.
- Refactored deserializer to work in less steps and with cleaner code.
- Slight tweaks of some error messages.
- Added InputEncoding option.
- Added ability to deserialize into
List<MyClass>specifically- Currently only works when also setting UseList = Never
- Fixed a big issue with nested arrays stepping over keys.
- Added tests.
- Added option to convert strings "1" and "0" into bools when deserializing an object.
- Changed how validation is handled and moved validation out of the tokenization step.
- Added
[PhpIgnore]and[PhpProperty("name")]
- Initial release.