1

I have the following JSON output from an external site:

    {
       "foo":"bar",
       "poo":1,
       "boo":67,
       "articles":{
          "1329800400":[
             {
                "id":"234",
                "title":"Title of This Article",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
                "duration":"287.3200",
             },
             {
                "id":"212",
                "title":"Another Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
                "duration":"199.0530",
             },
             {
                "id":"196",
                "title":"A Third Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
                "duration":"217.0250",
             }
          ],
          "1329714000":[
             {
                "id":"176",
                "title":"Yet Another Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
                "duration":"219.6890",
             },
             {
                "id":"155",
                "title":"The Last Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
                "duration":"228.2570",
             }
          ]
       }
    }

I want to GET the file via PHP and reformat the structure to be like:

    {
        "1": {
            "id":"234",
            "title":"Title of This Article",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
            "duration":"287.3200",
            "pubDate":"1329800400"
        },
        "2": {
            "id":"212",
            "title":"Another Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
            "duration":"199.0530",
            "pubDate":"1329800400"
        },
        "3": {
            "id":"196",
            "title":"A Third Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
            "duration":"217.0250",
            "pubDate":"1329800400"
        },
        "4": {
            "id":"176",
            "title":"Yet Another Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
            "duration":"219.6890",
            "pubDate":"1329714000"
        },
        "5": {
            "id":"155",
            "title":"The Last Article Title",
                "url":"http:\/\/www.test.com\/path-to-article.html",
                "thumb":"http:\/\/www.test.com\/path-to-image.jpg",
                "attachment":"http:\/\/www.test.com\/path-to-attachment.mp3",
            "duration":"228.2570",
            "pubDate":"1329714000"
        }
    }

How hard would this be? Notice how the pubDate goes from being a parent to a child. Also keep in mind that I will never know the values of the pubDates -- they change on a daily basis. Thanks in advance for any suggestions!

2 Answers 2

2

There's a problem with the starting JSON string in that it has trailing commas after the duration properties, which are invalid. So first of all, those trailing commas need to be removed.

// Function lifted from PHP docs...
function removeTrailingCommas($json) {
   $json=preg_replace('/,\s*([\]}])/m', '$1', $json);
    return $json;
}

The articles are objects with numeric property names, so those need to be retrieved with get_object_vars() to be easily iterable.

// Get rid of trailing commas
$json = json = removeTrailingCommas($json);

// Decode your string (already in $json)
$obj = json_decode($json);

// Get the article dates as an array
$articles = (get_object_vars($obj->articles));

// This will be the final output object
$output = new stdClass();
// Since they will be numeric properties starting at 1...
$outkey = 1;
// Loops over article pubdates to get the outer objects
foreach ($articles as $key=>$val) {
  // Loops over the inner objects in each article pubdate
  foreach ($obj->articles->$key as $sub_obj) {

    // Copies the object and adds the pubdate property
    $tmp = clone $sub_obj;
    $tmp->pubDate = $key;

    // Add it onto the output object
    $output->$outkey = $tmp;
    $outkey++;
  }
}
//var_dump($output);
echo json_encode($output);

The PHP object dump:

object(stdClass)#8 (5) {
  ["0"]=>
  object(stdClass)#9 (7) {
    ["id"]=>
    string(3) "234"
    ["title"]=>
    string(21) "Title of This Article"
    ["url"]=>
    string(40) "http://www.test.com/path-to-article.html"
    ["thumb"]=>
    string(37) "http://www.test.com/path-to-image.jpg"
    ["attachment"]=>
    string(42) "http://www.test.com/path-to-attachment.mp3"
    ["duration"]=>
    string(8) "287.3200"
    ["pubDate"]=>
    int(1329800400)
  }
  ["1"]=>
  object(stdClass)#10 (7) {
    ["id"]=>
    string(3) "212"
    ["title"]=>
    string(21) "Another Article Title"
    ["url"]=>
    string(40) "http://www.test.com/path-to-article.html"
    ["thumb"]=>
    string(37) "http://www.test.com/path-to-image.jpg"
    ["attachment"]=>
    string(42) "http://www.test.com/path-to-attachment.mp3"
    ["duration"]=>
    string(8) "199.0530"
    ["pubDate"]=>
    int(1329800400)
  }
  ["2"]=>
  object(stdClass)#11 (7) {
    ["id"]=>
    string(3) "196"
    ["title"]=>
    string(21) "A Third Article Title"
    ["url"]=>
    string(40) "http://www.test.com/path-to-article.html"
    ["thumb"]=>
    string(37) "http://www.test.com/path-to-image.jpg"
    ["attachment"]=>
    string(42) "http://www.test.com/path-to-attachment.mp3"
    ["duration"]=>
    string(8) "217.0250"
    ["pubDate"]=>
    int(1329800400)
  }
  ["3"]=>
  object(stdClass)#12 (7) {
    ["id"]=>
    string(3) "176"
    ["title"]=>
    string(25) "Yet Another Article Title"
    ["url"]=>
    string(40) "http://www.test.com/path-to-article.html"
    ["thumb"]=>
    string(37) "http://www.test.com/path-to-image.jpg"
    ["attachment"]=>
    string(42) "http://www.test.com/path-to-attachment.mp3"
    ["duration"]=>
    string(8) "219.6890"
    ["pubDate"]=>
    int(1329714000)
  }
  ["4"]=>
  object(stdClass)#13 (7) {
    ["id"]=>
    string(3) "155"
    ["title"]=>
    string(22) "The Last Article Title"
    ["url"]=>
    string(40) "http://www.test.com/path-to-article.html"
    ["thumb"]=>
    string(37) "http://www.test.com/path-to-image.jpg"
    ["attachment"]=>
    string(42) "http://www.test.com/path-to-attachment.mp3"
    ["duration"]=>
    string(8) "228.2570"
    ["pubDate"]=>
    int(1329714000)
  }
}

The JSON string:

{"0":
    {"id":"234",
     "title":"Title of This Article",
     "url":"http://www.test.com/path-to-article.html",
     "thumb":"http://www.test.com/path-to-image.jpg",
     "attachment":"http://www.test.com/path-to-attachment.mp3",
     "duration":"287.3200",
     "pubDate":1329800400},
 "1":
    {"id":"212",
     "title":"Another Article Title",
     "url":"http://www.test.com/path-to-article.html",
     "thumb":"http://www.test.com/path-to-image.jpg",
     "attachment":"http://www.test.com/path-to-attachment.mp3",
     "duration":"199.0530",
     "pubDate":1329800400},
 "2":
    {"id":"196",
     "title":"A Third Article Title",
     "url":"http://www.test.com/path-to-article.html",
     "thumb":"http://www.test.com/path-to-image.jpg",
     "attachment":"http://www.test.com/path-to-attachment.mp3",
     "duration":"217.0250",
     "pubDate":1329800400},
 "3":
    {"id":"176",
     "title":"Yet Another Article Title",
     "url":"http://www.test.com/path-to-article.html",
     "thumb":"http://www.test.com/path-to-image.jpg",
     "attachment":"http://www.test.com/path-to-attachment.mp3",
     "duration":"219.6890",
     "pubDate":1329714000},
 "4":
    {"id":"155",
     "title":"The Last Article Title",
     "url":"http://www.test.com/path-to-article.html",
     "thumb":"http://www.test.com/path-to-image.jpg",
     "attachment":"http://www.test.com/path-to-attachment.mp3",
     "duration":"228.2570",
     "pubDate":1329714000}
}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 This answer feels far more thorough and generally better than my own - I did say I was rusty with PHP ;)
0
$jsondata= json_decode($filedata); //Filedata contains your JSON
$reformat = $jsondata['articles'];  //Get only the articles section
$tmp = array(); //Temporary array to store the new JSON data
$i=0; //Create a counter and start at 0

foreach($reformat as $item=>$pubdate_unixtime) {
    $i++;  //Add 1 to the counter
    $item["pubDate"] = $pubdate_unixtime; //Add the pubdate to the array
    $tmp[$i] = $item; //Add the old array to a new one and change the key
}

echo json_encode($tmp); //Change the php to json 

6 Comments

Hmm, this doesn't seem to do what I'm wanting. I need an output formatted exactly as given in the example. Notice how it's more simplified. After trying your code I get a return of NULL. I apologize for being slow -- I'm very new to PHP!
Im sorry im just a bit confused you've moved the pubdates but those other changes with the slashes are those intentional? Your output isnt valid json as it is now
I changed it completely try now?
Sorry -- the changes with the slashes were not intentional. I fixed the OP.
Tried your new code and I get the following error: "Warning: Invalid argument supplied for foreach() in json2.php on line 11 []" --- line 11 is "foreach($reformat as $item=>$pubdate_unixtime) {"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.