polesphp / json
Type-safe, class-oriented JSON (de)serialization library.
Requires
- php: >=7.2.0
- phpdocumentor/type-resolver: 0.5.1
Requires (Dev)
- phpunit/phpunit: ^7.2
- squizlabs/php_codesniffer: ^3.3
This package is not auto-updated.
Last update: 2024-04-14 02:50:56 UTC
README
poles-json
is a type-safe, class-oriented JSON (de)serialization library.
Goals
- Clean, simple API
- Strict on errors (always throw exceptions)
- Strict type-checking by default
- Encourage clean code by defining pure PHP data structures that describe input.
Non-goals
- Bridging for any PHP web framework
- Mapping JSON properties to getter and setter methods. I don't do the Java Bean thing.
- Value validation. This library will check that your value is a string, but will never validate that this string has a minimum of
n
characters or that it matches a certain regular expression. If you need such validation logic, this library combines nicely with Symfony's Validation component.
Usage
First, define a pure PHP data structure which represents your JSON schema:
<?php class Person { /** @var int */ public $id; /** @var string */ public $firstname; /** @var string */ public $lastname /** @var Address[] */ public $addresses; } class Address { /** int */ public $civicNo; /** string */ public $street; /** string */ public $city; /** string */ public $country; /** string */ public $postalCode; }
Note that type annotations are standard phpDocumentor tags.
Once your structure is properly defined, you can easily convert it to and from JSON like so:
<?php use Poles\Json\ClassSerializer; use Poles\Json\SerializerConfig; $subject = <<<JSON { "id": 5, "firstname": "John", "lastname": "Doe", "addresses": [ { "civicNo": 1080, "street": "Snowboarding Street", "city": "Montreal", "country": "Canada", "postalCode": "H2K1L3" } ] } JSON; $serializer = new ClassSerializer(Person::class, new SerializerConfig()); // ----- De-serialization ------- $personInstance = $serializer->deserialize($subject); // ----- Serialization ----- $originalJson = $serializer->serialize($personInstance);
Errors
This library throws exceptions on error. The possible errors during de-serialization are:
Poles\Json\Exceptions\EncodeException
: An error occured during call tojson_encode
(serialization only).Poles\Json\Exceptions\DecodeException
: An error occured during call tojson_decode
(de-serialization only).Poles\Json\Exceptions\TypeMismatchException
: A JSON value does not match the expected type or shape of a property.Poles\Json\Exceptions\UnsupportedTypeException
: A PHP property is annotated with an unsupported type (see supported types below).Poles\Json\Exceptions\UnresolvableClass
: A PHP property is annotated with a class name, but the class does not exist.
Supported type annotations
The phpDocumentor type annotations supported are:
string
int
orinteger
float
bool
orboolean
array
(elements of the array are NOT type-checked)null
(expects the valuenull
and nothing else)- Class references such as
MyClass
- Typed arrays such as
int[]
,MyClass[]
(in this case, each element of the array is recursively type-checked) - Compound types such as
int|string|null
Configuration
Here's an example of more complex configuration for the serializer:
<?php use Poles\Json\ClassSerializer; use Poles\Json\SerializerConfig; $config = new SerializerConfig(); $config->setCacheDirectory(sys_get_temp_dir()); // Writeable cache directory for production environments $config->setMaxDepth(200); // Same as the "max depth" argument of json_encode $config->setOptions(JSON_PRETTY_PRINT); // Same as the "options" argument of json_encode $serializer = new ClassSerializer(MyClass::class, $config);
Future work
Here is an informal list of future improvements for this library:
- Looser, "coerse" mode that only throws if a type cannot be co-erced into the expected type.
- Define name re-mapping logic, e.g. (
public $dateOfBirth
becomes JSON propertydate_of_birth
) - Have a nice DSL to explicitely define a JSON schema without inferring via Reflection.
License
All work found under this repository is licensed under the Apache License 2.0.
Contributing
If you wish to contribute to this project, make sure to read the Contribution Guidelines first!