Mysql
 sql >> Base de données >  >> RDS >> Mysql

PHP - Tableau de listes imbriquées simples non ordonnées (UL)

Cela devrait faire l'affaire :

$result = mysql_query("SELECT * FROM News");
$topicname = '';

// open list of topics
echo '<ul>';

// loop through topics
while($row = mysql_fetch_array($result)) {
    if (!$row['TopicID']) {
        // fake topic name for unsorted stuff
        $row['TopicName'] = 'Sort Me';
    }
    if ($topicname != $row['TopicName']) {
        if($topicname != ''){
            // had a topic name, means we opened a list
            // that hasn't been closed, close it.
            echo '</ul>';
        }
        // print this topic and open the list of articles
        echo '<li>' . $row['TopicName'] . '</li><ul>';
        // update the current topic to be this TopicName
        $topicname = $row['TopicName']; 
    }
    // the news item
    echo '<li>' . $row['NewsID'] . '"</li>';
}
if($topicname != ''){
    // we saw at least one TopicName, we need to close
    // the last open list.
    echo '</ul>';
}
// end topic list
echo '</ul>';

Je pense que votre vrai problème est que vous ouvriez deux listes à chaque fois, mais que vous n'en fermiez qu'une (même en déplaçant le dernier bloc à l'intérieur de la liste).

Pour la deuxième partie de votre (nouvelle) question :

Je mettrai en garde que pour les listes plus volumineuses (par exemple, plus de 300 éléments), le compromis que je fais en ce qui concerne le stockage de la liste en mémoire et l'itération deux fois plutôt que de simplement interroger les décomptes nécessaires basculerait dans l'autre sens. C'est-à-dire que la solution ci-dessous met tout en mémoire, puis itère une seconde fois pour l'imprimer ; une alternative serait d'exécuter deux requêtes, une pour trouver le nombre de TopicNames uniques et une pour trouver le nombre total d'éléments dans la liste.

De plus, pour l'affichage, vous voulez vraiment résoudre une optimisation de la mise en page, je vais le faire naïvement et créer un nombre (à peu près) égal de sujets par colonne et lorsque la division ne fonctionne pas, cela pèsera vers la gauche. Vous verrez où vous pouvez modifier ou remplacer du code pour obtenir des résultats différents (et meilleurs ?).

$columns = // user specified;

$result = mysql_query("SELECT * FROM News");
$num_articles = 0;

// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
    if (!$row['TopicID']) {
        $row['TopicName'] = 'Sort Me';
    }
    $dataset[$row['TopicName']][] = $row['NewsID'];
    $num_articles++;
}

$num_topics = count($dataset);

// naive topics to column allocation
$topics_per_column = ceil($num_topics / $columns);

$i = 0; // keeps track of number of topics printed
$c = 1; // keeps track of columns printed
foreach($dataset as $topic => $items){
    if($i % $topics_per_columnn == 0){
        if($i > 0){
            echo '</ul></div>';
        }
        echo '<div class="Columns' . $columns . 'Group' . $c . '"><ul>';
        $c++;
    }
    echo '<li>' . $topic . '</li>';
    // this lists the articles under this topic
    echo '<ul>';
    foreach($items as $article){
        echo '<li>' . $article . '</li>';
    }
    echo '</ul>';
    $i++;
}
if($i > 0){
    // saw at least one topic, need to close the list.
    echo '</ul></div>';
}