Вывод сложного JSON из результата MySQL с помощью PHP - PullRequest
2 голосов
/ 28 ноября 2011

Я только что закончил учебник Sencha Touch, который работает нормально.В настоящее время я нахожусь в процессе преобразования файла статических данных JSON (который используется в учебнике) в файл динамически генерируемых данных (JSON) из базы данных MySQL с помощью PHP.Файл JSON (ссылка на файл примера находится ниже), используемый в учебнике, имеет сложную структуру, и у меня возникают проблемы с преобразованием моих результатов SQL в точный формат JSON, используемый в учебнике.Ссылки на исходный код приведены ниже.Фокус на файле JSON (третья ссылка).Если я смогу просто скопировать этот файл, остальная часть проекта будет работать для меня.

Учебное пособие Sencha Touch находится по адресу: http://www.sencha.com/learn/intro-to-the-nested-list-component/

Весь код для проекта может быть расположенat (мне разрешено публиковать только две ссылки, надеюсь, вы можете интерпретировать ссылку ниже): 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 имеет среднее значение:)

$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));}

Вот пример JSON, выведенного из кода PHP выше:

{
    "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 ]

1 голос
/ 28 ноября 2011

Первое, что я хотел бы сделать, это попытаться воссоздать форматированные данные 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.

0 голосов
/ 28 ноября 2011

Вы можете сделать это за один раз, используя код ниже. просто убедитесь, что ваши данные возвращены Сортировка по жанру, исполнителю, альбому, дорожке.

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;
0 голосов
/ 28 ноября 2011

Это сложно.Это довольно ужасная модель данных.

Вам нужно добавить несколько полей и, возможно, немного поработать, но попробуйте это.

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