PHP Syntactic Sugar

Haoran Un
Haoran Un
May 30 · 2 min read

For a recent project, I had to generate JSON files in a sensible, structured, and extensible way.

In the course of doing so, I developed a neat bit of syntactic sugar that saved me lots of lines of code, and made my PHP a lot more readable.

The End

So here’s my neat little bit of syntactic sugar.

class JsonThing {public function __get($key) {
$this->$key = new JsonThing();
return $this->$key;
}
public function __set($key, $value) {
$this->$key = $value;
}
}class SomeOtherClass extends JsonThing { ... }

The Beginning

Why is this great? Because one might, for instance, want to generate a file like this:

{
"item":
{
"id": 511660,
"title": "article title",
"date": {
"modified": "2016-01-16T10:00:00+01:00",
"published": "2016-01-10T10:00:00+01:00"
}
}
}

The Middle

And now I can write this:

class Document extends JsonThing { ... }// ...$document = new Document();
$document->item->id = 511660;
$document->item->title = 'article title';
$document->item->date->modified = "2016-01-16T10:00:00+01:00";
$document->item->date->published = "2016-01-10T10:00:00+01:00";
return json_encode($document);

The larger my JSON Document gets, the even better this gets, because I can decompose parts of my Document into sensible sections, and replace them with other JsonThing objects as necessary.

class DefaultStyles extends JsonThing {
public $font = 'Georgia';
public $fontSize = 12;
public $colour = '#333';
}
// ...$document->styles = new DefaultStyles();
$document->validate();
return json_encode($document);

(Immediate improvement: implement JsonSerializable and run validate() automatically in jsonSerialize().)

Alternate Versions

The quick n’ dirty way of doing this involves nested arrays.

$document = [];
$document['item'] = [];
$document['item']['id'] = 511660;
$document['item']['title'] = 'article title';
$document['item']['date'] = [];
$document['item']['date']['modified'] = "2016-01-10T10:00:00+01:00";
$document['item']['date']['published'] = "2016-01-16T10:00:00+01:00";
return json_encode($document);

The problem with this is that arrays aren’t objects. Objects are helpful because we can define required values, throw some validation in jsonSerialize() (if we’ve implemented JsonSerializable), and use extensibility in neat ways.

For example, I’d love to be able to do this:

$document->addStyles();$document->setDateModified('yesterday');public function setDateModified($date) {
$this->date->published = strtotime($value);
}
}

Something like that, probably using __set() as well.

The other way of doing this is do lots of objects.

$document = new Document();$document->item = new Item();
$document->item->id = 511660;
$document->item->title = 'article title';
$document->item->date = new DocumentDate();
$document->item->date->modified = '2016-01-16T10:00:00+01:00';
$document->item->date->published= '2016-01-10T10:00:00+01:00';
return json_encode($document);
Haoran Un

Written by

Haoran Un

Code geek. Board game geek. Coffee geek. Bible geek.