Problems with parsing JSON objects

2019-08-31 05:14发布

问题:

My website calls the Spotify Web API and gets all the public playlists for a given user. The response is originally in JSON but my code decodes it.

The next thing I want the code to do, is to display only the objects [external_urls], [name] and [tracks] for each item in the response. For that I've tried this:

foreach($response_2['items'] as $item) {
echo 'Link: ' . $item['external_urls'] . '<br />'; 
echo 'Name: ' . $item['name'] . '<br />';
echo 'Tracks: ' . $item['tracks'] . '<br />'; }

...but it doesn't work as properly. All the [name]-objects (which is a string) are echoed correctly but for all [external_urls] and [tracks] (which are objects) it only says "Array" in the browser.

I guess I should be using print_r() for those objects but I can't get it to work.

Any suggestions?

My code:

<?php

$url = 'https://accounts.spotify.com/api/token';
$method = 'POST';

$credentials = "hidden:hidden";

$headers = array(
        "Accept: */*",
        "Content-Type: application/x-www-form-urlencoded",
        "Authorization: Basic " . base64_encode($credentials));
$data = 'grant_type=client_credentials';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_1 = curl_exec($ch);

curl_close($ch);

$response_1 = json_decode($response_1, true);

$token = $response_1['access_token'];

$headers_2 = array(
        "Accept: */*",
        "Content-Type: application/x-www-form-urlencoded",
        ('Authorization: Bearer ' . $token));

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://api.spotify.com/v1/users/wizzler/playlists');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_2);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_2 = curl_exec($ch);

curl_close($ch);

$response_2 = json_decode($response_2, true);

?>

The API-response:

{
    "href": "https://api.spotify.com/v1/users/wizzler/playlists",
    "items": [
        {
            "collaborative": false,
            "external_urls": {
                "spotify": "http://open.spotify.com/user/wizzler/playlists/53Y8wT46QIMz5H4WQ8O22c"
            },
            "href": "https://api.spotify.com/v1/users/wizzler/playlists/53Y8wT46QIMz5H4WQ8O22c",
            "id": "53Y8wT46QIMz5H4WQ8O22c",
            "name": "Wizzlers Big Playlist",
            "owner": {
                "external_urls": {
                    "spotify": "http://open.spotify.com/user/wizzler"
                },
                "href": "https://api.spotify.com/v1/users/wizzler",
                "id": "wizzler",
                "type": "user",
                "uri": "spotify:user:wizzler"
            },
            "public": true,
            "tracks": {
                "href": "https://api.spotify.com/v1/users/wizzler/playlists/53Y8wT46QIMz5H4WQ8O22c/tracks",
                "total": 30
            },
            "type": "playlist",
            "uri": "spotify:user:wizzler:playlist:53Y8wT46QIMz5H4WQ8O22c"
        },
        {
            "collaborative": false,
            "external_urls": {
                "spotify": "http://open.spotify.com/user/wizzlersmate/playlists/1AVZz0mBuGbCEoNRQdYQju"
            },
            "href": "https://api.spotify.com/v1/users/wizzlersmate/playlists/1AVZz0mBuGbCEoNRQdYQju",
            "id": "1AVZz0mBuGbCEoNRQdYQju",
            "name": "Another Playlist",
            "owner": {
                "external_urls": {
                    "spotify": "http://open.spotify.com/user/wizzlersmate"
                },
                "href": "https://api.spotify.com/v1/users/wizzlersmate",
                "id": "wizzlersmate",
                "type": "user",
                "uri": "spotify:user:wizzlersmate"
            },
            "public": true,
            "tracks": {
                "href": "https://api.spotify.com/v1/users/wizzlersmate/playlists/1AVZz0mBuGbCEoNRQdYQju/tracks",
                "total": 58
            },
            "type": "playlist",
            "uri": "spotify:user:wizzlersmate:playlist:1AVZz0mBuGbCEoNRQdYQju"...
        }
    ],
    "limit": 9,
    "next": null,
    "offset": 0,
    "previous": null,
    "total": 9
}

回答1:

Both external_urls and tracks are objects. In order to get the data, you either need to know the exact properties or cast them to an array (array) and traverse the newly created array to ensure you output all values. Since the names are pluralized I'm assuming you could have more than one external url and more than one track. For this reason, I've casted the properties to arrays and traversed through them:

foreach($response_2['items'] as $item) {
    echo "LINKS <br />";
    $item['external_urls'] = (array)$item['external_urls'];
    foreach($item['external_urls'] as $key => $value) {
        echo ucfirst($key) . ": " . $value . "<br />";
    }
    echo "Name: " . $item['name'] . "<br />";
    echo "TRACKS <br />";
    $item['tracks'] = (array)$item['tracks'];
    foreach($item['tracks'] as $key => $value) {
        echo ucfirst($key) . ": " . $value . "<br />";
    } 
}

Alternatively, if you know that you will only have one url and one track and you know the property names, you can access the properties using object syntax object->key; The same example from above is rewritten below using object syntax:

foreach($response_2['items'] as $item) {
    echo "LINKS <br />";
    echo "Spotify: " . $item['external_urls']->spotify . "<br />";
    echo "Name: " . $item['name'] . "<br />";
    echo "TRACKS <br />";
    echo "Href: " . $item['tracks']->href . "<br />";
    echo "Total: " . $item['tracks']->total . "<br />";
}

Sample Output for Item 1:

LINKS
Spotify: http://open.spotify.com/user/wizzler/playlists/53Y8wT46QIMz5H4WQ8O22c
Name: Wizzlers Big Playlist
TRACKS
Href: https://api.spotify.com/v1/users/wizzler/playlists/53Y8wT46QIMz5H4WQ8O22c/tracks
Total: 30