JSON_ENCODE ведет себя отличным на ArrayObject VS Array ()
Вопрос
У меня была функция в 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);
Это выходы:
"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"
}
}
Теперь я переписал массив, чтобы стать таким предметом:
//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);
Но это меняет вывод на:
"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"
}
}
}
},
Что делает его непригодным, как Geojson для OpenLayers. Почему функция json_encode ведет себя таким образом? Могу ли я отключить настройку номеров индекса? Это возможная ошибка?
Решение
json_encode
будет отображать то же поведение с любым объектом, даже те, которые реализуют ArrayAccess
интерфейс как ArrayObject
делает; Общественные свойства используются.
Чтобы получить поведение, которое вы хотите, вы должны пройти его реальный массив, который может быть получен, позвонив ArrayObject::getArrayCopy()
(или вы можете отбросить объект на массив).
echo json_encode($newsensors->getArrayCopy());
Другие советы
Пришлось конвертировать деревья данных, которые содержат ArrayObject на разном уровне, поэтому я написал кусок кода для обработки и преобразования каждого ArrayObject перед выводом JSON, надеюсь, что это поможет:https://github.com/nfroidure/rest4/blob/master/php/class.json.php.
Использовать Jsonserializable Интерфейс (PHP 5> = 5.4.0, PHP 7), и вы должны быть в безопасности:
public function jsonSerialize()
{
return $this->getArrayCopy();
}