将属性添加到php中对象顶部的stdClass

When creating a object in php used to return JSON is it possible to add a property and force it to go at the top? I'd like this since the object is exposed via an API and it is nice to have ids at the top.

For example:

$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;

When you json_encode() this, it turns into:

{
    "name": "John",
    "age": 26,
    "id": 3645
}

Is there a way to force id at the top of the object even though it is added last? Note, I can't simply just add id before adding name and age because of other dependent code.

Hmm, nice question!

It is not possible to add a property and force it to go at the top. You have to sort the object properties or the array keys.

Some nitpicking here: JSON is unordered by definition, but the browsers respect the insertion order. More: https://code.google.com/p/v8/issues/detail?id=164

JSON 4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

Check this out: http://ideone.com/Hb4rGQ

<?php

function array_reorder_keys($array, $keynames){
    if(empty($array) || !is_array($array) || empty($keynames)) return;
    if(!is_array($keynames)) $keynames = explode(',',$keynames);
    if(!empty($keynames)) $keynames = array_reverse($keynames);
    foreach($keynames as $n){
        if(array_key_exists($n, $array)){
            $newarray = array($n=>$array[$n]); //copy the node before unsetting
            unset($array[$n]); //remove the node
            $array = $newarray + array_filter($array); //combine copy with filtered array
        }
    }
    return $array;
}

$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;

function get_json_sorted($object, $array) {
    return json_encode(array_reorder_keys(get_object_vars($object), $array));
}

var_dump(get_json_sorted($obj, array('id', 'name', 'age')));

Not very elegant but...

$obj = new stdClass();
$obj->name = 'John';
$obj->age = 26;
$obj->id = 3645;

$name = $obj->name;
$age = $obj->age;

unset($obj->name);
unset($obj->age);

$obj->name = $name;
$obj->age = $age;

echo json_encode($obj);

It's easily possible if you use an associative array instead of an object, i.e.

$x = ['name' => 'john', 'age' => 26]; // or: $x = (array)$obj
$x = ['id' => 123] + $x;
echo json_encode($x);
// {"id":123,"name":"john","age":26}

However, it's important to note that in JSON property ordering is not defined and should not be relied upon. If what you currently have works, this change would be rather useless in fact.

This is a solution. Turn the object into an assoc array. Get the last item (both key and value) off of the array (I'm assuming id is the last element) and move it to the front. Finally convert the assoc array back into an object.

$data_array = json_decode(json_encode($obj), true);
if(is_array($data_array)) {
    end($data_array);
    $data_array = array_merge(array(key($data_array) => array_pop($data_array)), $data_array);
    $data = json_decode(json_encode($data_array), false);
}