使用PHP从MySQL结果输出复杂的JSON

时间:2011-11-28 12:26:47

标签: php mysql json sencha-touch

我刚刚完成了一个工作正常的Sencha Touch教程。我目前正在使用PHP将静态JSON数据文件(本教程使用的)转换为MySQL数据库中的动态生成数据(JSON)文件。本教程中使用的JSON文件(示例文件的链接位于下面)具有复杂的结构,我在将SQL结果转换为本教程中使用的确切JSON格式时遇到问题。下面列出了源代码的链接。重点关注JSON文件(第三个链接)。如果我可以简单地复制这个文件,那么项目的其余部分将适用于我。

Sencha Touch教程位于: http://www.sencha.com/learn/intro-to-the-nested-list-component/

项目的所有代码都可以找到(我只允许发布两个链接,我希望你能解释下面的链接): github dot com / nelstrom / Sencha-Touch-nested-list-demo

可以在以下位置查看静态JSON数据文件的示例:https://github.com/senchalearn/Nested-list-demo/blob/master/data/albums.json

我有一个数据库和sql,它以下列结构输出数据:

Genre  Artist     Album           Track               Duration 
ROCK   MUSE       Absolution      Intro               0:23
ROCK   MUSE       Absolution      Apolcalypse Please  4:13
ROCK   MUSE       The Resistance  Uprising            5:03
ROCK   SEVENDUST  Next            Hero                3:48
FUNK   PRIMUS     Antipop         The Antipop         5:33
FUNK   PRIMUS     Antipop         Ballad of Bodacious 2:29

我有以下php输出JSON但格式不正确,不幸的是它尽可能接近 - 抱歉我的PHP是abit average:)

$result = mysql_query($query,$link) or die('Errant query:  '.$query);
$model = array();

if(mysql_num_rows($result)) {
    while($e = mysql_fetch_assoc($result)) {
        $model['Genre'] = $e['Genre'];
        $model['Artist'] = $e['Artist'];
        $model['Album'] = $e['Album'];
        $model['items'][] = array(
                        'text' => $e['Track'],
                        'duration' => $e['Duration']
        );
    }
}  

header('Content-type: application/json');
echo json_encode(array('items'=>$model));}

以下是从上面的PHP代码输出的JSON示例:

{
    "items": {
        "Genre": "ROCK",
        "Artist": "MUSE",
        "Album": "Absolution",
        "items": [
            {
                "text": "Intro",
                "duration": "0:23"
            },
            {
                "text": "Apolcalypse Please",
                "duration": "4:13"
            }
        ]
    }
}

不幸的是,这种JSON格式不正确。主要问题是循环并在正确的位置应用方括号'['']'。我在下面列出了一个简短的例子:

    {
    "items": [
     {
       "model": "Genre",
       "items": [
         {
           "model": "Artist",
           "items": [
             {
               "model": "Album",
               "items": [
                {
                  "model": "Track",
                  "duration": 96,
                  "text": "Introduction",
                  "items": [

                  ],
                  "info": "",
                  "leaf": true
                 },
                 {
                  "model": "Track",
                  "duration": 155,
                  "text": "Please Accept My Love",
                  "items": [

                  ],
                  "info": "",
                  "leaf": true
                }
              ],
              "text": "Live in Cook County Jail",
              "info": "<p>Live in Cook County Jail is a 1971 live album by B.B. King recorded in Cook County Jail, Chicago, Illinois. It was ranked as number 499 in the book version of Rolling Stone's 500 Greatest Albums of All Time.</p>",
              "leaf": true
            }
          ],
          "text": "B.B.King",
          "info": "<p>Riley B. King aka B. B. King (born September 16th, 1925 in Itta Bena, Mississippi) is a well known American blues guitarist and songwriter. He is among the most respected electric guitarists. </p><p>One of King’s trademarks is naming his guitar (Gibson ES335) “Lucilleâ€. In the 1950s in a bar in Twist, Arkansas two men got into a fight, accidentally knocking over a bucket of burning kerosene (used for heating) and setting the establishment on fire. Risking his life, B.B. King ran back into the collapsing building to retrieve his guitar.</p>",
          "leaf": false
        },
      ],
      "text": "Blues",
      "info": "",
      "leaf": false
    }
  ]
} 

提前感谢你看看这个,对不起,如果这是啰嗦,但我只是想确保我已经包含了所有内容。如果您需要更多信息,请与我们联系。

亲切的问候

3 个答案:

答案 0 :(得分:1)

我要做的第一件事是尝试重新创建JSON格式化数据。快速测试

$array = array(
'items' => array(
    array(
    'model' => 'Genre',
    'items' => array(
        array(
        'model' => 'Artist',
        'items' => array(
            'model' => 'Album',
            'items' => array(array())
        )
        )
    )
    )
)
);
$json = json_encode( $array );
var_dump( $json );

这提供了类似于您需要的JSON输出。

然后,您需要将数据库中的数据转换为相关格式的数组。为了避免多次通过你正在构建的数组(这可能需要一段时间,因为数组变大)我将这个过程分为两个步骤。

第一

$tempData = array();
while($e = mysql_fetch_assoc($result)) {
    $tempData[$e['Genre']][$e['Artist']][$e['Album']][$e['Track']] = $e['Duration']
}

然后你应该能够遍历$ tempArray并以正确的格式构建一个数组来创建JSON。

答案 1 :(得分:0)

这很棘手。这是一个非常糟糕的数据模型。

你需要添加一些字段并做一些工作,但试试这个。

if(mysql_num_rows($result)) {
    while($e = mysql_fetch_assoc($result)) {
        $genreExisted = 0;
        $albumExisted = 0;
        foreach ($model['items'] as $genreKey => $genre) {
            if ($e['Genre'] == $genre['text']) {
                $genreExisted = 1;
                foreach ($genre['items'] as $albumKey => $album) {
                    if ($e['Album'] == $album['text']) {
                        $albumExisted = 1;
                        //add a new track
                        $model['items'][$genreKey]['items'][$albumKey]['items']["model"] = $e['Track'];
                        $model['items'][$genreKey]['items'][$albumKey]['items']["duration"] = $e['Duration'];
                    }
                }
                if ($albumExisted != 1) {
                    //add an album inside the genre
                    $model['items'][$genreKey]['items'][]["model"] = "Album";
                    $model['items'][$genreKey]['items'][]["text"] = $e['Album'];
                }
            }    
        }
        if ($genreExisted != 1) {
            //add a new genre
            $model['items'][]["model"] = "Genre";
            $model['items'][]["text"] = "Blues";
        }
    }
}

答案 2 :(得分:0)

您可以使用下面的代码一次完成此操作。只需确保您的数据按流派,艺术家,专辑,曲目退回。

if(mysql_num_rows($result)) {
   $curr_genre = $curr_artist = $curr_album = $curr_track = '';
   $model = $track = $album = $artist = $genre = array();
   $first_row = 1;
   while ($e = mysql_fetch_assoc($result))
        // every time track changes, create new array and insert into album
        $track['model'] = 'Track';
        $track['info'] = "";
        $track['text'] = $e['Track'];
        $track['duration'] = $e['Duration'];
        $track['leaf'] = TRUE;
        $album['items'][] = $track;
        $track = array();

        // every time album changes, create new array and insert into artist
    if ($curr_album != $e['Album']) {
        $album['model'] = 'Album';
        $album['info'] = "";
        $album['text'] = $curr_album;
        $album['leaf'] = FALSE;
        if (!$first_row) 
    {
        // pop the last item as it's taken one from the next album
        $new_item = array_pop(&$album['items']);
        $artist['items'][] = $album;
        $album = array();
        $album['items'][] = $new_item;
        }
        $curr_album = $e['Album'];

        }

        // every time artist changes, create new array and insert into genre
    if ($curr_artist != $e['Artist']) {
        $artist['model'] = 'Artist';
        $artist['info'] = "";
        $artist['text'] = $curr_artist;
        $artist['leaf'] = FALSE;
        if (!$first_row) 
    {
        $genre["items"][] = $artist;
    $artist = array();
    }
    $curr_artist = $e['Artist'];
    }


        // every time genre changes, create new array and insert into model
    if ($curr_genre != $e['Genre']) {
        $genre['model'] = 'Genre';
        $genre['text'] = $curr_genre;
        $genre['left'] = FALSE;
        if (!$first_row) 
    {
        $model["items"][] = $genre;
    $genre = array();
    }

    $curr_genre = $e['Genre'];
        }

        if ($first_row) {
            $first_row = 0;
        }
    }
  }  
    // now just process the last row

        $album['model'] = 'Album';
        $album['info'] = "";
        $album['text'] = $curr_album;
        $album['leaf'] = FALSE;
        $album['items'][] = $track;

        $artist['model'] = 'Artist';
        $artist['info'] = "";
        $artist['text'] = $curr_artist;
        $artist['leaf'] = FALSE;
        $artist['items'][] = $album;

        $genre['model'] = 'Genre';
        $genre['text'] = $curr_genre;
        $genre['left'] = FALSE;
        $genre["items"][] = $artist;

        $model['items'][] = $genre;