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

使用PHP从MySQL结果输出复杂JSON,php,mysql,json,sencha-touch,Php,Mysql,Json,Sencha Touch,我刚刚完成了一个senchatouch教程,效果很好。我目前正在使用PHP将静态JSON数据文件(教程使用的)从MySQL数据库转换为动态生成的数据(JSON)文件。教程中使用的JSON文件(下面是示例文件的链接)结构复杂,我在将SQL结果转换为教程中使用的确切JSON格式时遇到问题。下面列出了源代码的链接。本文的重点是JSON文件(第三个链接)。如果我可以简单地复制这个文件,那么项目的其余部分将为我工作 Sencha Touch教程位于: 该项目的所有代码都可以位于(我只允许向发布两个链接,

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

Sencha Touch教程位于:

该项目的所有代码都可以位于(我只允许向发布两个链接,希望您可以解释以下链接): github.com/nelstrom/Sencha Touch嵌套列表演示

静态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
我有以下输出JSON的php,但格式不正确,不幸的是,它是我能得到的最接近的-对不起,我的php有点平均:)

下面是上面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
    }
  ]
} 
{
“项目”:[
{
“模型”:“类型”,
“项目”:[
{
“模特”:“艺术家”,
“项目”:[
{
“模型”:“相册”,
“项目”:[
{
“模型”:“轨道”,
“期限”:96,
“正文”:“导言”,
“项目”:[
],
“信息”:“,
“叶子”:真的吗
},
{
“模型”:“轨道”,
“期限”:155,
“文本”:“请接受我的爱”,
“项目”:[
],
“信息”:“,
“叶子”:真的吗
}
],
“文本”:“居住在库克县监狱”,
“信息”:“生活在库克县监狱是B.B.金1971年在伊利诺伊州芝加哥库克县监狱录制的一张现场专辑。在滚石500张有史以来最伟大的专辑中,该专辑名列第499位。”,
“叶子”:真的吗
}
],
“文本”:“B.B.King”,
“信息”:“Riley B.King又名B.B.King(1925年9月16日出生于密西西比州的Itta Bena),是美国著名的布鲁斯吉他手和歌曲作者。他是最受尊敬的电吉他手之一。

™20世纪50年代,在阿肯色州Twist的一家酒吧里,两名男子发生斗殴,不小心打翻了一桶燃烧的煤油(用于取暖)并点燃了该场所。B.B.King冒着生命危险跑回倒塌的大楼取回他的吉他。

“, “叶子”:假 }, ], “文本”:“蓝色”, “信息”:“, “叶子”:假 } ] }
提前感谢您查看此内容,如果内容冗长,请原谅,但我只是想确保我已经包含了所有内容。如果您需要更多信息,请告诉我


亲切的问候

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

您需要添加一些字段,可能需要做一些工作,但请尝试一下

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

我要做的第一件事是尝试重新创建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输出

然后需要将数据库中的数据转换成相关格式的数组。为了避免多次通过正在构建的阵列(随着阵列越来越大,这可能需要一段时间),我将此过程分为两步

首先


然后,您应该能够循环使用$tempArray并以正确的格式构建一个数组来创建JSON。

您可以使用下面的代码一次性完成这项工作。只需确保返回的数据按流派、艺术家、专辑、曲目排序即可

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;

正如您所理解的,您正在获取一个关系数据库,并将其压缩为一个对象。在实践中,很少这样做(除非是出于存档目的,我只需要自己拍摄数据库的快照…)。相反,使用各种
SELECT
查询对数据子集进行“过滤”,以选择所需的特定信息。我知道您试图模仿教程,但由于您似乎刚刚开始使用数据库等,我想在您尝试对每个数据库调用执行类似操作之前,我会让您知道。非常感谢,所有的响应都非常有用!
$tempData = array();
while($e = mysql_fetch_assoc($result)) {
    $tempData[$e['Genre']][$e['Artist']][$e['Album']][$e['Track']] = $e['Duration']
}
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;