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

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"
}
}