milovanderlinden milovanderlinden - 5 months ago 20
JSON Question

json_encode behaving different on arrayObject vs array()

I had a function in php:

//simple method with array()
$sensors = array();
$query = "select id, x(transform(wkb_geometry,". $epsg . ")) as lon, y(transform(wkb_geometry,". $epsg . ")) as lat from mytable;";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
while ($row = pg_fetch_assoc($result)) {
//var_dump($row);
$mySensor = new sensor($row['id'],$row['lat'],$row['lon']);
$sensors[] = $mySensor->geoJSON();
}

echo json_encode($sensors);


that outputs:

"features": [{
"type": "Feature",
"id": 1579028,
"x": 4.85310557823,
"y": 52.7205622103,
"geometry": {
"type": "Point",
"coordinates": [4.85310557823, 52.7205622103],
"crs": {
"type": "OGC",
"properties": {
"urn": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
}


Now I have rewritten the array to become an object like this:

//advanced method with arrayObject:
class sensors extends ArrayObject {
function __construct($epsg){
$query = "select id, x(transform(wkb_geometry,". $epsg . ")) as lon, y(transform(wkb_geometry,". $epsg . ")) as lat from mytable;";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
while ($row = pg_fetch_assoc($result)) {
//var_dump($row);
$mySensor = new sensor($row['id'],$row['lat'],$row['lon']);
$this[] = $mySensor->geoJSON();
}
}
}
$newsensors = new sensors($epsg);
echo echo json_encode($newsensors);


But this changes the output to:

"features": {
"0": {
"type": "Feature",
"id": 1579028,
"x": 4.85310557823,
"y": 52.7205622103,
"geometry": {
"type": "Point",
"coordinates": [4.85310557823, 52.7205622103],
"crs": {
"type": "OGC",
"properties": {
"urn": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
}
}
},


Which makes it unusable as geoJSON for OpenLayers. Why does the json_encode function behave this way? Can I turn off the setting of the index numbers? Is this a possible little bug?

Answer

json_encode will display the same behaviour with any object, even ones implementing the ArrayAccess interface as ArrayObject does; the public properties are used.

To get the behaviour that you want you should pass it an actual array which can be retrieved by calling ArrayObject::getArrayCopy() (or you can cast the object to an array).

echo json_encode($newsensors->getArrayCopy());