Download the PHP package netresearch/jsonmapper without Composer
On this page you can find all versions of the php package netresearch/jsonmapper. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download netresearch/jsonmapper
More information about netresearch/jsonmapper
Files in netresearch/jsonmapper
Package jsonmapper
Short Description Map nested JSON structures onto PHP classes
License OSL-3.0
Informations about the package jsonmapper
JsonMapper - map nested JSON structures onto PHP classes
Takes data retrieved from a JSON web service and converts them into nested object and arrays - using your own model classes.
Starting from a base object, it maps JSON data on class properties, converting them into the correct simple types or objects.
It's a bit like the native SOAP parameter mapping PHP's SoapClient
gives you, but for JSON.
It does not rely on any schema, only your PHP class definitions.
Type detection works by parsing type declarations and @var
docblock annotations of class properties,
as well as type hints in setter methods.
You do not have to modify your model classes by adding JSON specific code; it works automatically by parsing already-existing docblocks.
This library has no dependencies.
Keywords: deserialization, hydration
Pro & contra
Benefits
- Autocompletion in IDEs
- It's easy to add comfort methods to data model classes
- Your JSON API may change, but your models can stay the same - not breaking applications that use the model classes.
Drawbacks
- Model classes need to be written by hand Since JsonMapper does not rely on any schema information (e.g. from json-schema), model classes cannot be generated automatically.
Usage
Basic usage
- Install
netresearch/jsonmapper
with composer - Create a
JsonMapper
object instance - Call the
map
ormapArray
method, depending on your data
Map a normal object:
Map an array of objects:
Instead of array()
you may also use ArrayObject
and derived classes,
as well as classes implementing ArrayAccess
.
Example
JSON from an address book web service:
javascript
{ "name":"Sheldon Cooper", "address": { "street": "2311 N. Los Robles Avenue", "city": "Pasadena" } }
Your local Contact
class:
public ?Address $address;
Your local Address
class:
public function getGeoCoords() { //do something with $street and $city }
Your application code:
echo "Geo coordinates for " . $contact->name . ": " . var_export($contact->address->getGeoCoords(), true);
Property type mapping
JsonMapper
uses several sources to detect the correct type of
a property in the following order:
- Setter method (
set
+ucwords($propertyname)
) Underscores "_
" and hyphens "-
" make the next letter uppercase. Propertyfoo_bar-baz
leads to setter methodsetFooBarBaz
. - If it has a type hint in the method signature then its type used:: public function setPerson(Contact $person) {...}
- The method's docblock is inspected for
@param $type
annotations:: /** - @param Contact $person Main contact for this application */ public function setPerson($person) {...}
- If no type could be detected, the plain JSON value is passed to the setter method.
- Class property types (since PHP 7.4):: public Contact $person;
- Constructor property promotion types (since PHP 8.0):: public function __construct(protected Contact $person) {}
@var $type
docblock annotation of class properties:: /**- @var \my\application\model\Contact
*/
public $person;
The property has to be public to be used directly.
You may also use $bIgnoreVisibility to utilize
protected and private properties.
.. __: #prop-bignorevisibility
If no type could be detected, the property gets the plain JSON value set.
If a property can not be found, JsonMapper tries to find the property
in a case-insensitive manner.
A JSON property
isempty
would then be mapped to a PHP propertyisEmpty
. .. note:: You have to provide the fully qualified namespace for the type to work. Relative class names are evaluated in the context of the current classes namespace, NOT respecting any imports that may be present. PHP does not provide the imports via Reflection; the comment text only contains the literal text of the type. For performance reasons JsonMapper does not parse the source code on its own to detect and expand any imports.
Supported type names
- Simple types
string
bool
,boolean
int
,integer
double
,float
array
object
mixed
- Class names, with and without namespaces
Contact
- exception will be thrown if the JSON value isnull
- Arrays of simple types and class names:
int[]
Contact[]
- Multidimensional arrays:
int[][]
TreeDeePixel[][][]
- ArrayObjects of simple types and class names:
ContactList[Contact]
NumberList[int]
- Backed enums, with and without namespaces
Suit:string|Suit:int
- exception will be thrown if the JSON value is not present in the enum- Nullable types:
int|null
or?int
- will benull
if the value in JSON isnull
, otherwise it will be an integerContact|null
or?Contact
- will benull
if the value in JSON isnull
, otherwise it will be an object of typeContact
ArrayObjects and extending classes are treated as arrays.
Variables without a type or with type mixed
will get the
JSON value set directly without any conversion.
See phpdoc's type documentation for more information.
Simple type mapping
This feature is disabled by default for security reasons since version 5. See $bStrictObjectTypeChecking for details.
When an object shall be created but the JSON contains a simple type only (e.g. string, float, boolean), this value is passed to the classes' constructor. Example:
PHP code:
JSON:
js
{"date":"2014-05-15"}
This will result in new DateTime('2014-05-15')
being called.
Class map
When variables are defined as objects of abstract classes or interfaces, JsonMapper would normally try to instantiate those directly and crash.
Using JsonMapper's $classMap
property, you can specify which classes
shall get instantiated instead:
This would create objects of type Bar
when a variable is defined to be
of type Foo
.
It is also possible to use a callable in case the actual implementation class needs to be determined dynamically (for example in case of a union). The mapped class ('Foo' in the example below) and the Json data are passed as parameters into the call.
$jm = new JsonMapper(); $jm->classMap['Foo'] = $mapper; $jm->map(...);
Nullables
JsonMapper throws an exception when a JSON property is null
,
unless the PHP class property has a nullable type - e.g. Contact|null
or ?Contact
.
If your API contains many fields that may be null
and you do not want
to make all your type definitions nullable, set:
Since version 5.0.0, null
values in arrays lead to a JsonMapper_Exception
unless the type is nullable - e.g. array[?string]
or array[string|null]
.
To get the previous behavior back (allowing nulls even when not declared so) set:
Logging
JsonMapper's setLogger()
method supports all PSR-3 compatible
logger instances.
Events that get logged:
- JSON data contain a key, but the class does not have a property or setter method for it.
- Neither setter nor property can be set from outside because they are protected or private
Handling invalid or missing data
During development, APIs often change. To get notified about such changes, JsonMapper can be configured to throw exceptions in case of either missing or yet unknown data.
Unknown properties
When JsonMapper sees properties in the JSON data that are
not defined in the PHP class, you can let it throw an exception
by setting $bExceptionOnUndefinedProperty
:
You may also choose to handle those properties yourself by setting
a callable to $undefinedPropertyHandler
:
Or if you would let JsonMapper handle the setter for you, you can return a string
from the $undefinedPropertyHandler
which will be used as property name.
Missing properties
This only works when $bStrictObjectTypeChecking stays enabled.
Properties in your PHP classes can be marked as "required" by
putting @required
in their docblock:
When the JSON data do not contain this property, JsonMapper will throw
a JsonMapper_Exception
when $bExceptionOnMissingData
is activated:
Option $bRemoveUndefinedAttributes
causes JsonMapper to remove properties
from the final object if they have not been in the JSON data:
Private properties and functions
You can allow mapping to private and protected properties and
setter methods by setting $bIgnoreVisibility
to true:
Simple types instead of objects
When a variable's type is a class and JSON data is a simple type
like string
, JsonMapper can pass this value to the class' constructor
when configured to do so:
This can be used to automatically initialize DateTime objects from date strings.
Disabling this strict object type checks may lead to problems, though:
- When a class does not have a constructor or no constructor parameter, the value will get lost
- When the constructor has more than 1 required parameter, it will crash.
- When the constructor's parameter type does not match the one of the data in JSON, it will crash
@required
properties will not be filled
The default value changed from false
to true
in version 5 to
increase security.
Now you have to opt in if you want to pass simple types to the class constructor.
Passing arrays to map()
You may wish to pass array data into map()
that you got by calling
Post-mapping callback
JsonMapper is able to call a custom method directly on each object after mapping it is finished:
Now afterMapping()
is called on each mapped object
(if the class has that method).
You may pass additional arguments to the post-mapping callback:
Installation
Via Composer from Packagist:
$ composer require netresearch/jsonmapper
Related software
Alternatives
- Jackson's data binding for Java
- Johannes Schmitt Serializer for PHP
- metassione for PHP
- Cartographer for PHP
- Data Transfer Object for PHP
- Valinor for PHP
- An equally named JsonMapper library that has dependencies.
About JsonMapper
License
JsonMapper is licensed under the OSL 3.0.
Coding style
JsonMapper follows the PEAR Coding Standards.
Author
cweiske.de
All versions of jsonmapper with dependencies
ext-spl Version *
ext-json Version *
ext-pcre Version *
ext-reflection Version *