Reputation: 795
Is there an equivalent to get a reorganized standardized object from a normal class? Something that works along the same lines as PHP's __toString() override method.
Okay, so I have this method that grabs a bunch of stations, and returns an object model, which handles a bunch of other methods to get other related data. So in this instance when I call the object that contains the locations "$locations" I want to get back either a flat associative array of object properties, or an array of objects that I can easily encode to JSON. If I get an array of location objects back, I just want $location to be directly converted to a JSON string. Just like if I were to refer to $location as a location object that contained __toString() and it would automatically produce a string representation. In this case I want an standard object or array, and not a string. Is there a way to do this?
Code sample below:
public function stnSearch() {
$locations = DBO::getInstance()->query("
SELECT " . DBO_Location::COLUMNS . "
FROM " . DBO_Location::TABLE_NAME . " AS a
WHERE a.title LIKE '%" . $_REQUEST['query'] . "%'
")->fetchAll(PDO::FETCH_CLASS, DBO_Location::MODEL);
Util::debug($locations); // want this to produce a standard object for each model without having to do an additional loop
exit();
}
Upvotes: 3
Views: 11305
Reputation: 28056
In php 5.4 and above, if your class impliments JsonSerializable
, you can add a jsonSerialize
method that will be called by json_encode
:
<?php
class MyClass implements JsonSerializable
{
public $foo;
public function jsonSerialize() {
return array(
"foo"=>$this->foo,
"name"=>"MyClass"
);
}
}
$x = new MyClass();
$x->foo = "hello";
echo json_encode($x);
Will print:
{"foo":"hello","name":"MyClass"}
Upvotes: 14
Reputation: 795
Thanks for the feedback everyone! I ended up having to create a standard method in each class (one for toArray(), and one for toJSON()). This is not the desired solution, but it will have to do.
The toArray() method flattens out the complex class so that the array has properties available to either toObject() or toJSON() to digest. For instance I had a few methods that format data for output to HTML, and those do not automatically set to a local property in the class, so I need to set that up manually. via the method I mentioned above.
toArray() example:
public static function toArray($logs) {
$b = new ArrayObject();
$b->offsetSet('id', $logs->getId());
$b->offsetSet('frequency', $logs->getFrequency());
$b->offsetSet('formatted_frequency', number_format($logs->getFrequency(), 2, '.', ''));
$b->offsetSet('mode', $logs->getMode());
$b->offsetSet('time_on', $logs->getTimeOn()->format(self::JSON_DATE_FORMAT));
$b->offsetSet('description', $logs->getDescription());
$b->offsetSet('receive_location', $logs->receiveCoordinates()->toArray());
...
return $b->getArrayCopy();
}
to get JSON object:
public static function toJSON($logs) {
$b = self::toArray($logs);
return json_encode($b);
}
Again this was not the desired result, but it gets the job done. Ideally I would love to have had a way to establish a method in the parent class that could be overridden, if there were extraneous properties that needed handling in a child class.
Upvotes: 4