PHP警告:非法字符串偏移 - json数据

时间:2017-10-07 12:28:43

标签: php json

我收到错误

  

警告:非法字符串偏移' @ name'在......

但仅基于此特定示例的22行。

我找了一个解决方案,这可能是将字符串作为数组,但我不知道如何处理这个问题。这是代码:

$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>"; 

  }  

输出结果为:

  
      
  1. 此房屋不得出售
  2.   
  3. 举手
  4.   
  5. 敲除
  6.   
  7. 你给爱一个坏名字
  8.   
  9. 天生就是我的宝贝
  10.   
  11. 失落的公路
  12.   
  13. We Weren生于关注
  14.   
  15. 把手放在我身上
  16.   
  17. In These Arms
  18.   
  19. 新年
  20.   
  21. (你想)创造记忆
  22.   
  23. 玫瑰花床
  24.   
  25. 这是我的生活
  26.   
  27. 总有一天我会成为周六晚上
  28.   
  29. 想死或活着
  30.   
  31. 我死的时候会睡觉
  32.   
  33. 度过美好的一天
  34.   
  35. 保持信仰
  36.   
  37. 坏医学   Encore 1
  38.   
  39. 始终
  40.   
  41. Livin的&#39;在祷告上   Encore 2
  42.   
  43. 警告:非法字符串偏移&#39; @ name&#39;在...
  44.   

2 个答案:

答案 0 :(得分:1)

Fiddle Demo

  

我找了一个解决方案,这可能是因为把字符串作为一个字符串   数组,但我不知道如何处理这个问题。这是代码:

     

警告:......中的非法字符串偏移'@ name'

原因:

您收到错误,因为api响应不是最后一个的数组,因为剩下的只是"song":[]

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

所以对于最后一组$row = "These Days"

这是您可以轻松搞定的差异

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

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

        )

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

)

在json中相同

enter image description here

因此您可以检查其数组是否如下所示

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

      }
}

下面有一个可以帮助你,它给出了数组中的所有歌曲名称,

<?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

?>

<强>输出:

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回复,来自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"
   }
}

答案 1 :(得分:0)

您应该处理objectstring。对于最后一次迭代,你得到了字符串,所以试试这个

<?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++;
        }
    }
?>

使用您的示例数据进行实时演示:https://eval.in/875794