An open API service indexing awesome lists of open source software.

https://github.com/darsyn/unboxer

Simple utility to unbox complex data structures (objects) to native data types.
https://github.com/darsyn/unboxer

Last synced: 5 months ago
JSON representation

Simple utility to unbox complex data structures (objects) to native data types.

Awesome Lists containing this project

README

          

Simple utility to unbox complex data structures (objects) to native data types,
suitable for encoding (for example, JSON).

# Documentation

## Code of Conduct

This project includes and adheres to the [Contributor Covenant as a Code of
Conduct](CODE_OF_CONDUCT.md).

## Supported Types

This library returns all scalar and null values as-is, plus recursively
processing all array (and `stdClass`) types.

When this library encounters an object that is an instance of a known type, it
will attempt to convert it by using the return value of a specific method.
Object types supported by this library out-of-the-box include:

- Dates (objects implementing `DateTimeInterface`) which are converted to
strings according to RFC3339 (eg, `2019-02-05T12:15:32+00:00`).
- Timezones (objects implementing `DateTimeZone`) which result in a string
containing the timezone name (eg, `America/Vancouver`).
- Exceptions and errors (objects implementing `Throwable`) which result in a
string containing the exception message.
- JSON (objects implementing `JsonSerializable`) which result in the library
recursively iterating over the JSON data returned.
- Doctrine collections (objects implementing `Collection` interface) which
result in the library iterating over each of the items inside the collection.

Additionally, any user-land object can implement `UnboxableInterface`. Similar
to `JsonSerializable::jsonSerialize()` method, the `__unbox` method can return
anything as a representation of its internal state.
It is recommended to return unboxable objects as-is, as everything returned from
`UnboxableInterface::__unbox` is recursively iterated over anyway.

## Brief Example

```php
name;
}
}

class Options implements \JsonSerializable {
public function __construct(
private bool $active,
private bool $verified,
private \DateTimeZone $timezone
) {}

public function jsonSerialize() {
return [
'active' => $this->active,
'verified' => $this->verified,
'tz' => $this->timezone,
];
}
}

class Member implements UnboxableInterface
{
private ArrayCollection $groups;

public function __construct(
private int $id,
private string $username,
array $groups = [],
private ?Options $options = null
) {
$this->groups = new ArrayCollection($groups);
}

public function __unbox()
{
return [
// Scalars are used as-is.
'id' => $this->id,
'username' => $this->username,
// Objects of known types are returned as-is, but recursively iterated over.
'groups' => $this->groups,
// JSON-serializable objects are never actually run through json_encode().
'options' => $this->options ?: [],
];
}
}

$member = new Member(123, 'dr-evil', [
new Group('admin'),
new Group('moderator'),
new Group('sharks-with-lasers'),
], new Options(true, false, new \DateTimeZone('America/Vancouver')));

try {
$output = (new Unboxer)->unbox($member);
var_dump($output);
} catch (UnboxingException $e) {
echo $e->getMessage();
}
```

`var_dump`ing the variable `$output` results in:

```
array(4) {
'id' =>
int(123)
'username' =>
string(7) "dr-evil"
'groups' =>
array(3) {
[0] =>
string(5) "admin"
[1] =>
string(9) "moderator"
[2] =>
string(18) "sharks-with-lasers"
}
'options' =>
array(3) {
'active' =>
bool(true)
'verified' =>
bool(false)
'tz' =>
string(17) "America/Vancouver"
}
}
```

Note that returning multiple nested unboxable objects will result in the output
collapsing down into a single value:

```php
unbox($data);
var_dump($output);
} catch (UnboxingException $e) {
echo $e->getMessage();
}
```

```
string(13) "Error Message"
```

## Extending

Additional known object types can be added by extending `Unboxer` and overriding
the `getKnownDataTypes` method. For each known object type, either a closure or
an array specifying which method to call on the object may can specified:

```php
['format', [\DateTimeInterface::RFC3339]];

// Closure example.
yield \DateTimeInterface::class => function (\DateTimeInterface $date): string {
return $date->format(\DateTimeInterface::RFC3339);
};
}
}
```

The unboxer will, by default, convert any objects with the `__toString()` magic
method to a string. To turn this functionality off, extend `Unboxer` and
override the class constant `STRINGIFY_OBJECTS`.

```php