Download the PHP package ddn/jsonobject without Composer

On this page you can find all versions of the php package ddn/jsonobject. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package jsonobject

TypedObject

TypedObject is a PHP class that enables to parse JSON objects into PHP objects, and later getting them back into JSON objects.

At the end, this library can be used as a DTO (Data Transfer Object) backend for PHP. It is possible to define the types for the attributes of the objects, and the TypedObject base class will parse the JSON objects into the PHP objects, and will take care of checking the types of the attributes, or and/or converting them into the appropriate types when setting their values.

In this way, it makes it easier to implement the data model of the application, and to deal with the data that comes from other layers, such a REST API.

The library also includes the classes TypedDict and TypedList that are used to deal with dictionaries and lists, respectively. These classes are used by TypedObject to manage the attributes that are defined as dictionaries or lists, but they can be used independently.

Why TypedObject

I had to use an API from PHP, and that API returned me JSON Objects. So I needed to parse them into PHP objects that I was able to use in the app.

The workflow is

  1. retrieve a JSON object definition
  2. use TypedObject to parse the JSON definition
  3. use the resulting objects in the application
  4. get the JSON definition back
  5. send the JSON definition to the API

Use case

Let's take the following JSON example:

Using TypedObject, I will be able to define my data model using the following classes:

And then add the following command:

The TypedObject class will carry out with parsing the content into objects, and we would be able to use its attributes as defined:

During the usage of the objects, the library will take care of checking the types of the attributes, and will convert the values into the expected types. So that we can use the objects without worrying about the types of the attributes.

e.g.

And the result will be:

In this case, the library will convert the PHP list of emails into a TypedList object, and the PHP array of the address into an Address object without the intervention of the user. But also verifies that the age is an integer, and that the emails are strings, and the attributes in the address are those expected.

And even simpler, if we use the TypedObjectSimple class, we can define the classes like this:

And we will be able to parse the JSON object in the same way:

... the rest of the example will work the same way.

The TypedObjectSimple class is a simpler version of the TypedObject class, that uses the PHP 7.4 typed attributes to define the attributes of the class. It is simpler to use, but it has some limitations and lack of expressiveness when defining the data model.

Extending the data model

The classes can also have methods that will make it easier to implement the application's data model. E.g. it would possible to define the class User like this:

The methods that use the attributes of the object will also be subject to the type checking, so that the values will be converted to the expected types. In this sense, the implementation is also type-safe.

Features of TypedObject

  1. Type checking: The attributes of the objects are typed, so that the library will check the types of the attributes when setting their values. If the value does not match the type, an exception will be raised. That means that the types of the attributes of an object will be those that are expected to be without the need to check them.
  2. Default values: It is possible to set default values for the attributes, so that if the data comes from the API without some attributes, they will be initialized with the default values. This feature enables a more flexible way to upgrade the data model of the application, and keep the compatibility with the previous versions of the API.
  3. Nullable attributes: It is possible to define attributes as nullable. That means that they can be set to null, but it also enables more control over the values of the attributes, as they can be set to null only if they are defined as nullable.
  4. Type conversion: The library will convert the values to the expected types, even if they are not strictly the same type. This feature enables a more flexible way to deal with the data, as the values will be converted to the expected types.
  5. Inheritance: The objects can inherit attributes from their parent classes. That means that the attributes of the parent class will be available in the child class. This feature enables a more flexible way to define the data model of the application.

Installing

The library can be installed using composer:

And then it can be included in the PHP script:

Using TypedObject

The idea of the TypedObject class is to use it to parse json data into objects. So that these objects may contain other methods that will help to implement the data model of the application.

When the json object (or array) is parsed, its content are recursively parsed according to the types defined in the ATTRIBUTES constant. If the data is not valid, because it does not contain the expected values, an exception is thrown.

To use TypedObject one must subclass TypedObject and define the ATTRIBUTES constant for that class so that it defines the attributes expected for the objects of that class, along with the type of each one.

Defining the types for the attributes

The ATTRIBUTES constant is an associative array where the keys are the name for each attribute, and the values are the type for each attribute.

The possible types can be:

e.g.

Then it is possible to instantiate the object using the static method fromArray or fromObject, or directly using the constructor:

Alternatively, it is possible to not to specify the type for any of the attributes. In that case, the attribute will be considered to be of type mixed.

e.g.

Using typed attributes and the TypedObjectSimple class

The preferred method to use the TypedObject library is by using the TypedObject class, and defining the data model using the constant ATTRIBUTES, and then do not define the attributes in the class definition (or at least do not define them as PHP 7.4 typed attributes) and let the library to take care of them.

But there is also a simpler version of the class, the TypedObjectSimple class, that avoids the use of the ATTRIBUTES constant, and uses the PHP 7.4 typed attributes to define the attributes of the class.

e.g.

In this case, if we have the a JSON fragment that accomplishes the data model, we can use the following code to get an instance of the User class:

The only advise is that every public attribute in the class is considered to be part of the data model, and so it will be parsed when creating the object. So, if the class has attributes that are not part of the data model, they must be defined as private or protected.

Notes on TypedObjectSimple

This class is simpler to use, but it has some limitations:

Anyway, if your data model is simple and you do not need to define the types for the values of lists or dicts, the TypedObjectSimple class may be a good choice.

Default values for the attributes

It is possible to set default values for the attributes. This is done either in the attribute definition or in the class definition.

e.g. in the attribute definition:

In this example, the attribute name will be initialized to John Doe if not set. In case that the default value is either a function or a method in the class, the default value will be the result of the call to that function or method. This is the case of the attribute id in the example, which will be initialized to the result of the method generate_id.

e.g. in the class definition:

This is an equivalent way to set the default values for the attributes. In this case, the default value is set in the class definition by means of setting the value of the corresponding properties, and it is used when the attribute is not set when creating the object.

One can think that an uninitialized attribute may have a default value, as in non typed attributes. But in the case of TypedObject, an uninitialized attribute is not considered to have a default value, as they are typed attributes and it observes Typed Properties in PHP 7.4 behavior.

If wanted to control this behavior, we can use the constant ddn\typedobject\USE_DEFAULT_VALUES. If set to true, the uninitialized attributes that do not have a default value will be initialized with the following default values:

The default value for ddn\typedobject\USE_DEFAULT_VALUES is false, so the uninitialized attributes will not have a default value.

Uninitialized attributes

If an attribute is not initialized (either because its value is set or it has a default value), it cannot be retrieved. So, if we try to get its value, it will raise an exception.

e.g.

This will raise an exception because the attribute name has not been initialized.

To check whether an attribute has been initialized or not, the function isset can be used.

e.g.

The use of the uninitialized state can be controlled by the constant ddn\typedobject\USE_UNINITIALIZED_STATE. If it is set to true, the TypedObject will consider the uninitialized state as a valid state for the attributes. If so, an attribute may be initialized later than the object creation.

e.g.

In this example, if we set the constant ddn\typedobject\USE_UNINITIALIZED_STATE to true, the output will be John Doe. Otherwise, it will raise an exception when trying to instantiate the object ($user = new User()) because the attribute name has not been initialized when instantiating the object, and it does not have a default value.

If ddn\typedobject\USE_UNINITIALIZED_STATE is set to false, in case that an attribute is not initialized during the creation of the object, and it has not a default value, an exception will be raised.

e.g.

In this example, an exception will be raised because the attribute name has not been initialized and it does not have a default value.

To check if the object is fully initialized (i.e has all its attributes initialized), the function is_initialized can be used, and to get the list of the attributes that have not been initialized, the function get_uninitialized_attributes can be used.

The default value for ddn\typedobject\USE_UNINITIALIZED_STATE is true, so not initializating an attribute will not raise an exception.

Nullable attributes

To be able to assign the null value to an attribute, it needs to be defined as nullable. To mark a property can be null, prefix its type with a question mark, e.g: ?string.

e.g.

In this example, the attribute age is defined as nullable, so it is possible to assign null to it. If the attribute is not defined as nullable, assigning null to it will raise an exception of type TypeError.

It may be weird that an uninitialized nullable attribute is not considered to be null. But as of Typed Properties in PHP 7.4, the uninitialized state is different from setting it to be null.

To control the behavior of the uninitialized nullable attributes, the constant ddn\typedobject\UNINITIALIZED_NULLABLE_IS_NULL can be set to true. If so, the uninitialized nullable attributes will be considered to be null as a default. Otherwise, they will be considered to be uninitialized.

While PHP considers the uninitialized state of a nullable attribute to not to be null, the TypedObject library sets constant ddn\typedobject\UNINITIALIZED_NULLABLE_IS_NULL is set to true by default, as I found it more intuitive and code-friendly.

Type checking

The TypedObject class will check the types of the attributes when setting their values. If the value does not match the type, an exception will be raised.

e.g.

In this example, an exception will be raised because the attribute name is defined as a string, and we are trying to assign an integer to it.

To control this behavior, the constant ddn\typedobject\STRICT_TYPE_CHECKING can be set to false. If that case, some type conversions will be done when setting the values of the attributes:

The default value for ddn\typedobject\STRICT_TYPE_CHECKING is true, so the types will be strictly checked.

If wanted and extended type conversion, the constant ddn\typedobject\EXTENDED_TYPE_CONVERSION can be set to true. If so, the following type conversions will be done:

The default value for ddn\typedobject\EXTENDED_TYPE_CONVERSION is false, so the types will be strictly checked.

Note: The extended type conversion has only sense if ddn\typedobject\STRICT_TYPE_CHECKING is set to false.

Enumerations

The library also supports enumerations. To define an attribute as an enumeration, the type must be defined as enum[<EnumValues derived class>], where EnumValues is a subclass of the EnumValues class.

To define an enumeration, the class must extend the EnumValues class and define the possible values by means of the VALUES constant, which must be a list of the possible values for the enumeration, where the first value is the default value.

e.g.

Then, the attribute can be defined as an enumeration:

And then we can use the enumeration like this:

In this example, the attribute type is defined as an enumeration, so it can only be set to one of the possible values defined in the UserType class. If we try to set it to a value that is not in the list, an exception will be raised.

Advanced usage of enumerations

The possible values in the VALUES constant do not need to be strings. They can be any type, even mixed types. In any case, the first value in the list will be considered to be the default value for the enumeration.

e.g.

In this example, the possible values are 0, user, 1.0 and true. If we try to set the attribute type to any of these values, it will be accepted.

The key point for the enumerations is that the class must implement the EnumValues interface:

The default implementation of the EnumValues class is based on the existence of the VALUES constant. But it is possible to implement the interface in any way that is needed.

Inheritance

TypedObjects are also able to inherit attributes from their parent classes. Take the following example:

In this example, class Vehicle will only have attribute brand and color, but class Car will have brand, color and wheels attributes, while class Boat will have brand, color and length attributes.

Creation of objects

Objects from children classes of TypedObject can be created using the static method ::fromArray or ::fromObject, starting from a json parsed object.

In the previous example, if we have a file car.json with the following content:

We can use the following code to get an instance of the Vehicle class:

An alternative is to instantiate objects like in the next example

* PHP 8 and over:

* previous PHP versions:

Methods for the objects

TypedObject

The TypedObject is the core class for this library. Its methods are:

TypedDict

This object is used to deal with a typed dictionary. The TypedDict class is typed to that each of the elements must be from a given type. The TypedDict objects can be used as array-like objects (e.g. $dict["key1"]).

To use a TypedDict (i.e. a dictionary) for the type of an attribute of a TypedObject, the type must be defined as dict[type], where type is the type of the elements in the dictionary.

e.g.

This code will convert the array into a TypedDict object.

But the TypedDict object can be used directly, by creating a new object of that type. In that case, the type of the elements must be defined when creating the object.

e.g.

The methods are:

These methods are interpreted in the same way than in the case of TypedObject. And the type of the elements in the dict may refer to complex types that will be considered recursively when parsing the content.

e.g. type TypedDict("list[int]") will be used to parse [ [ 1, 2, 3], [ 4, 5, 6 ]]

TypedList

This object is very much the same than TypedDict with the exception that the indexes must be integer numbers. In this case $value["key1"] will produce an exception.

The idea is to use the object as an array-like object, but with the type of the elements defined.

e.g.

In the code above, the attribute phones is defined as a list of strings. So, it is possible to append a new string to the list, and to get the first and the last elements of the list.

The methods are:

A list in PHP is an array with integer keys starting from 0 and increasing by 1 for each element. But one can use any integer key to set a value in an array. That means that if $l = [ 1, 2, 3 ]; $l[8] = 4; echo(count($l)); will output 4. That means that it has somehow converted to a dictionary. This feature is not supported in TypedList, so that it will raise an exception if a non-sequential index is used to set a value.

Controlling the behavior of the library

The behavior of the library can be controlled by setting some constants before including the library. The constants are:

Take into account that the constants must be set before including the library, and they will affect the behavior of the library for the whole script.

e.g.

The constants are defined in the namespace ddn\typedobject, so they must be accessed as ddn\typedobject\STRICT_TYPE_CHECKING.


All versions of jsonobject with dependencies

PHP Build Version
Package Version
Requires php Version >=7.4
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ddn/jsonobject contains the following files

Loading the files please wait ....