JSON Unmarshal using PHP 8 Attributes

I was un-marshalling some JSON data onto my class and realised we could use PHP 8 attributes to make it cleaner and more easier to use.

Let me walk you through a quick example, imagine you have some JSON data:

{
"airline": "Foo Airlines",
"aircraft": {
"type": "Boeing 747"
},
"route": [
{
"sequence": 1,
"cost": 50.25,
"luggageIncluded": true,
"airline": "Foo Airlines",
"departureAirport": "London Gatwick",
"arrivalAirport": "Malta International"
},
{
"sequence": 2,
"cost": 20.25,
"luggageIncluded": true,
"airline": "Foo Airlines",
"departureAirport": "Malta International",
"arrivalAirport": "London Gatwick"
}
]
}

The above data represents a flight departing from London Gatwick to Malta International.

Let’s assume we have the following 2 classes, a Flight class and a FlightRoute class that represents the above data structure.

Flight.php

class Flight
{
#[JSON(field: 'airline')]
public string $airlineName;

#[JSON(field: 'aircraft.type')]
public string $aircraftType;

#[JSON(field: 'route', type: FlightRoute::class)]
public array $route;
}

FlightRoute.php

class FlightRoute
{
#[JSON('sequence')]
public int $sequence;

#[JSON('cost')]
public float $cost;

#[JSON('luggageIncluded')]
public bool $luggageIncluded;

#[JSON('airline')]
public string $airline;

#[JSON('departureAirport')]
public string $departureAirport;

#[JSON('arrivalAirport')]
public string $arrivalAirport;
}

As you can see we are using the JSON attribute from the library to declare the field in the JSON data and the type if the data is an array of something.

Let’s un-marshal this data :)

// Create a new flight class
$flight = new Flight();

// Load our JSON data from file
$jsonData = json_decode(file_get_contents('flight.json'), true);

// Unmarshal JSON
Unmarshal::decode($flight, $jsonData);

and voila!

class Flight#3 (3) {
public string $airlineName =>
string(12) "Foo Airlines"
public string $aircraftType =>
string(10) "Boeing 747"
public array $route =>
array(2) {
[0] =>
class FlightRoute#11 (6) {
public int $sequence =>
int(1)
public float $cost =>
double(50.25)
public bool $luggageIncluded =>
bool(true)
public string $airline =>
string(12) "Foo Airlines"
public string $departureAirport =>
string(14) "London Gatwick"
public string $arrivalAirport =>
string(19) "Malta International"
}
[1] =>
class FlightRoute#8 (6) {
public int $sequence =>
int(2)
public float $cost =>
double(20.25)
public bool $luggageIncluded =>
bool(true)
public string $airline =>
string(12) "Foo Airlines"
public string $departureAirport =>
string(19) "Malta International"
public string $arrivalAirport =>
string(14) "London Gatwick"
}
}
}

If you want to use the package you can install it with:

composer require mrbenosborne/json-unmarshal

Feel free to contribute https://github.com/mrbenosborne/json-unmarshal

Credit: Hero image, https://php.watch/articles/php-attributes

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store