1

I get the error

Warning: Illegal string offset '@name' in ...

but only in 22 row based on this particular example.

I looked for a solution, that this might be from taking a string as an array, but I don't get a clue how to deal with this. Here is the code:

$setlista="23e278a7";  

$url = "http://api.setlist.fm/rest/0.1/setlist/".$setlista.".json";

  $json = file_get_contents($url);
  $obj = json_decode($json, true);

  $setlistByEvent = $obj['setlist']['sets']['set'];

  $countSongs = 1;

  for ($i = 0; $i <= count($setlistByEvent) - 1; $i++) {

  echo "<ul>";

  if($i > 0) {
    echo "Encore " . $setlistByEvent[$i]['@encore'] ;
  }

  foreach($setlistByEvent[$i]['song'] as $row) {
      echo "<li>";
      echo $countSongs . ". ";
      echo $row['@name'];
      echo "</li>";
    $countSongs++;
  }

  echo "</ul>"; 

  }  

The output is:

  1. This House Is Not for Sale
  2. Raise Your Hands
  3. Knockout
  4. You Give Love a Bad Name
  5. Born to Be My Baby
  6. Lost Highway
  7. We Weren't Born to Follow
  8. Lay Your Hands On Me
  9. In These Arms
  10. New Year's Day
  11. (You Want to) Make a Memory
  12. Bed of Roses
  13. It's My Life
  14. Someday I'll Be Saturday Night
  15. Wanted Dead or Alive
  16. I'll Sleep When I'm Dead
  17. Have a Nice Day
  18. Keep the Faith
  19. Bad Medicine Encore 1
  20. Always
  21. Livin' on a Prayer Encore 2
  22. Warning: Illegal string offset '@name' in...
2
  • Then remove the @ Commented Oct 7, 2017 at 12:30
  • Removing @ in @name makes it not showing names at all, and the error is still there Commented Oct 7, 2017 at 12:35

2 Answers 2

1

Fiddle Demo

I looked for a solution, that this might be from taking a string as an array, but I don't get a clue how to deal with this. Here is the code:

Warning: Illegal string offset '@name' in ...

Cause :

You got error because api response was not array for last one, for remaining all it was "song":[]

            {
               "@encore":"2",
               "song":{
                  "@name":"These Days"
               }
            }

So for last set $row = "These Days"

Here is difference which you can make out easily

(
    [@encore] => 1
    [song] => Array
        (
            [0] => Array
                (
                    [@name] => Always
                )

            [1] => Array
                (
                    [@name] => Livin' on a Prayer
                )

        )

)
Array
(
    [@encore] => 2
    [song] => Array
        (
            [@name] => These Days
        )

)

Same in json

enter image description here

So you can check before whether its array like below

foreach($setlistByEvent[$i]['song'] as $row) {
      if(is_array($row) && isset($row['@name']))
      {

      }
}

Below one may help you, which gives all song names in array,

<?php

$setlista="23e278a7";  
$url = "http://api.setlist.fm/rest/0.1/setlist/".$setlista.".json";
$arr = json_decode(file_get_contents($url),true);

$songs = array();
foreach($arr['setlist']['sets']['set'] as $list){

    // if you want filter by @encore for example, then uncomment below line
    // if($list['@encore']==1)

    // this is where we got issue, lets make array
    if(!isset($list['song'][0])){ $list['song']=array($list['song']); }

    $songs = array_merge($songs, array_column($list['song'],'@name'));
}
print_r($songs);

// Now you got array of songnames, you may use loop now

?>

Output:

akshay@db-3325:/tmp$ php test.php 
Array
(
    [0] => This House Is Not for Sale
    [1] => Raise Your Hands
    [2] => Knockout
    [3] => You Give Love a Bad Name
    [4] => Born to Be My Baby
    [5] => Lost Highway
    [6] => We Weren't Born to Follow
    [7] => Lay Your Hands On Me
    [8] => In These Arms
    [9] => New Year's Day
    [10] => (You Want to) Make a Memory
    [11] => Bed of Roses
    [12] => It's My Life
    [13] => Someday I'll Be Saturday Night
    [14] => Wanted Dead or Alive
    [15] => I'll Sleep When I'm Dead
    [16] => Have a Nice Day
    [17] => Keep the Faith
    [18] => Bad Medicine
    [19] => Always
    [20] => Livin' on a Prayer
    [21] => These Days
)

Json response, from api

{
   "setlist":{
      "@id":"23e278a7",
      "@versionId":"7343f625",
      "@tour":"This House Is Not for Sale",
      "@eventDate":"23-09-2017",
      "@lastUpdated":"2017-09-24T16:26:18.000+0000",
      "artist":{
         "@mbid":"5dcdb5eb-cb72-4e6e-9e63-b7bace604965",
         "@tmid":"734608",
         "@name":"Bon Jovi",
         "@sortName":"Bon Jovi",
         "@disambiguation":"group",
         "url":"https://www.setlist.fm/setlists/bon-jovi-33d6b851.html"
      },
      "venue":{
         "@id":"6bd41616",
         "@name":"Allianz Parque",
         "city":{
            "@id":"6324358",
            "@name":"São Paulo",
            "@state":"São Paulo",
            "@stateCode":"27",
            "coords":{
               "@lat":"-23.6270250218409",
               "@long":"-46.6350328065523"
            },
            "country":{
               "@code":"BR",
               "@name":"Brazil"
            }
         },
         "url":"https://www.setlist.fm/venue/allianz-parque-sao-paulo-brazil-6bd41616.html"
      },
      "sets":{
         "set":[
            {
               "song":[
                  {
                     "@name":"This House Is Not for Sale"
                  },
                  {
                     "@name":"Raise Your Hands"
                  },
                  {
                     "@name":"Knockout"
                  },
                  {
                     "@name":"You Give Love a Bad Name"
                  },
                  {
                     "@name":"Born to Be My Baby"
                  },
                  {
                     "@name":"Lost Highway"
                  },
                  {
                     "@name":"We Weren't Born to Follow"
                  },
                  {
                     "@name":"Lay Your Hands On Me"
                  },
                  {
                     "@name":"In These Arms"
                  },
                  {
                     "@name":"New Year's Day"
                  },
                  {
                     "@name":"(You Want to) Make a Memory"
                  },
                  {
                     "@name":"Bed of Roses"
                  },
                  {
                     "@name":"It's My Life"
                  },
                  {
                     "@name":"Someday I'll Be Saturday Night"
                  },
                  {
                     "@name":"Wanted Dead or Alive"
                  },
                  {
                     "@name":"I'll Sleep When I'm Dead"
                  },
                  {
                     "@name":"Have a Nice Day"
                  },
                  {
                     "@name":"Keep the Faith"
                  },
                  {
                     "@name":"Bad Medicine"
                  }
               ]
            },
            {
               "@encore":"1",
               "song":[
                  {
                     "@name":"Always"
                  },
                  {
                     "@name":"Livin' on a Prayer"
                  }
               ]
            },
            {
               "@encore":"2",
               "song":{
                  "@name":"These Days"
               }
            }
         ]
      },
      "url":"https://www.setlist.fm/setlist/bon-jovi/2017/allianz-parque-sao-paulo-brazil-23e278a7.html"
   }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You should handle for object or string. For last iteration you are getting string, so try like this

<?php
    $setlista="23e278a7";
    $url = "http://api.setlist.fm/rest/0.1/setlist/".$setlista.".json";
    $json = file_get_contents($url);
    $obj = json_decode($json);
    $count = 1;
    foreach ($obj->setlist->sets->set as $key => $value) {
        foreach ($value->song as $key => $song) {
            echo ($count).". ";
            echo is_object($song) ? $song->{'@name'} : $song;
            echo "<br>\n";
            $count++;
        }
    }
?>

Live demo with your sample data : https://eval.in/875794

Comments

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.