json_encode comportarsi diverso su arrayObject vs array ()
Domanda
ho avuto una funzione 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);
che uscite:
"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"
}
}
Ora ho riscritto la matrice di diventare un oggetto come questo:
//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);
Ma questo cambia l'output:
"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"
}
}
}
},
Il che lo rende inutilizzabile come GeoJSON per OpenLayers. Perché la funzione json_encode comportarsi in questo modo? Posso disattivare l'impostazione dei numeri indice? È questo un possibile piccolo bug?
Soluzione
json_encode
visualizza lo stesso comportamento con qualsiasi oggetto, anche quelli che implementano l'interfaccia ArrayAccess
come ArrayObject
fa; le proprietà pubbliche vengono utilizzate.
Per ottenere il comportamento desiderato lo dia mai una matrice reale che può essere recuperato chiamando ArrayObject::getArrayCopy()
(o si può lanciare l'oggetto in un array).
echo json_encode($newsensors->getArrayCopy());
Altri suggerimenti
Ha dovuto alberi di dati che contengono convertire ArrayObject a livello diverso, quindi ho scritto un pezzo di codice per gestire e convertire ogni ArrayObject prima di emettere JSON, spero che aiuta: https://github.com/nfroidure/Rest4/blob/master /php/class.Json.php
Utilizza la JsonSerializable Interface (PHP 5> = 5.4.0 , PHP 7) e si dovrebbe essere al sicuro:
public function jsonSerialize()
{
return $this->getArrayCopy();
}