Skip to content

Instantly share code, notes, and snippets.

@genxoft
Last active July 18, 2022 17:13
Show Gist options
  • Save genxoft/90a4f8e8bc4842f61adb01a5ecdf37ef to your computer and use it in GitHub Desktop.
Save genxoft/90a4f8e8bc4842f61adb01a5ecdf37ef to your computer and use it in GitHub Desktop.
Json serialization trait
<?php
declare(strict_types=1);
use RuntimeException;
use ReflectionClass;
use ReflectionProperty;
/**
* Model to json serrializaton helper
*/
trait JsonSerializableTrait
{
/**
* @return array|null
*/
public function fields(): ?array
{
return null;
}
/**
* @see \JsonSerializable
*/
public function jsonSerialize(): array
{
$fields = $this->fields();
$props = [];
if ($fields !== null) {
foreach ($fields as $attribute => $callable) {
if (!is_string($attribute)) {
if (!$this->canGetProperty($callable)) {
throw new RuntimeException("Property $callable is undefined");
}
$props[$callable] = $this->$callable;
continue;
}
if (is_string($callable)) {
if (!$this->canGetProperty($callable)) {
throw new RuntimeException("Property $callable is undefined");
}
$props[$attribute] = $this->$callable;
} else if (is_callable($callable)) {
$props[$attribute] = ($callable)();
} else {
throw new RuntimeException("Property $callable is undefined");
}
}
} else {
$reflect = new ReflectionClass($this);
$properties = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $property) {
$props[$property->getName()] = $this->{$property->getName()};
}
}
return $props;
}
/**
* @param string $property
* @return bool
*/
public function canGetProperty(string $property): bool
{
if (isset($this->$property)) {
return true;
}
return false;
}
}
<?php
declare(strict_types=1);
class Model
{
use JsonSerializableTrait;
const STATUSES = ['pass', 'warn', 'fail'];
public string $title = "Default title";
public string $shortDescription = "Some description";
private int $status = 0;
public function fields(): array
{
return [
'title',
'short_description' => 'shortDescription',
'status' => function () {
return self::STATUSES[$this->status];
},
];
}
}
{
"title": "Default title",
"short_description": "Some description",
"status": "pass"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment