PHP - 嵌套列表分成偶数列(修复和更新)

标签 php mysql css

我对之前的线程/问题进行了跟进,希望可以通过对现有代码进行相对较小的更新来解决。在另一个线程/问题中,我几乎解决了对嵌套无序列表的需求。我需要根据主题的数量将嵌套的无序列表分成几列。

例如,如果数据库查询产生 6 个主题并且用户为布局指定了 2 列,则每列将有 3 个主题(以及其下方的相关新闻项)。

例如,如果数据库查询产生 24 个主题并且用户为布局指定了 4 列,则每列将有 6 个主题(以及其下方的相关新闻项)。

  • 上一题的题目是PHP - Simple Nested Unordered List (UL) Array . 提供的解决方案效果很好,但并不总是 split 正确。例如,当 $columns = 4 时,它只划分 列分为 3 组。代码如下。

  • 我想解决的另一个问题是由 回答问题的先生。而不是把 一切都存入内存,然后第二次迭代打印它 out,我想运行两个查询:一个是查找 唯一的 TopicNames 和一个用于查找中的总元素数 列表。

  • 我想解决的最后一件事是复制一组 具有将嵌套无序列表分解为列的更新的代码 基于新闻项的数量(而不是类别)。所以这 这一秒可能只需要交换几个变量 一组代码。

所以,我希望解决三个问题:

1.) 修复依赖类别数时的划分问题(无序列表按主题数分列)

2.) reshape PHP 代码以运行两个查询:一个查找唯一主题名称的数量,一个查找列表中的总元素数

3.) 创建一组重复的 PHP 代码,其工作依赖于新闻项的数量而不是类别(无序列表根据新闻项的数量分成列)

任何人都可以提供更新或指出正确的方向吗?非常感谢!

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

2011 年 12 月 19 日更新: 将数据处理与输出逻辑分开(对于“每列 X 主题变体”):

您好 Hakre:我已经勾勒出我的输出结构,但我正在努力将两个新函数与旧数据处理结合起来。下面的代码应该有效吗?

/* Data Handling */

$columns = // user specified;

$result = mysql_query("SELECT * FROM News LEFT JOIN Topics on Topics.TopicID = New.FK_TopicID WHERE News.FK_UserID = $_SESSION[user_id] ORDER BY TopicSort, TopicName ASC, TopicSort, NewsTitle");

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

/* Output Logic */

function render_list($title, array $entries)
{
    echo '<ul><li>', $title, '<ul>';
    foreach($entries as $entry)
    {
        echo '<li>', $entry['NewsID'], '</li>';
    }
    echo '</ul></li></ul>;
}

function render_column(array $topics)
{
    echo '<div class="column">';
    foreach($topics as $topic)
    {
        render_list($topic['title'], $topic['entries']);
    }
    echo '</div>';
}

最佳答案

你的两个问题都没有说明数据库表是什么,所以我不能具体回答,但会概述我的建议。

您可以使用 mysql 中的聚合函数来获取按主题(包括主题)排序和分组的新闻条目。他们的计数。您可以先进行两次查询以获取计数,这在一定程度上取决于您希望如何处理数据。

在任何情况下,使用 mysql_... 函数,您从数据库中选择的所有数据都将在内存中(由于内部结构甚至两次)。因此,由于 PHP 中的写时复制优化,在您之前的问题中拥有另一个数组应该不会造成太大伤害。只需少量开销即可有效。

接下来,在处理实际输出之前,您应该按顺序获取数据,这样您就不需要混合数据处理和输出逻辑。混合确实会使事情变得更复杂,因此更难解决。例如,如果您将输出放入简单的函数中,这会变得更容易:

function render_list($title, array $entries)
{
    echo '<ul><li>', $title, '<ul>';
    foreach($entries as $entry)
    {
        echo '<li>', $entry['NewsID'], '</li>';
    }
    echo '</ul></li></ul>;
}

function render_column(array $topics)
{
    echo '<div class="column">';
    foreach($topics as $topic)
    {
        render_list($topic['title'], $topic['entries']);
    }
    echo '</div>';
}

这已经解决了你的输出问题,所以我们不需要再关心它了。我们只需要关心将什么作为参数输入这些函数。

每列的 X 个主题变体:

对于这个变体,数据应该是一个数组,每个值一个主题,就像您对上一个问题所做的那样。我会说它已经解决了。不知道列数有哪个具体问题,计算看起来不错,所以我跳过它,直到您提供有关它的具体信息。 “不起作用”不合格。

每列变体的 X 个新闻元素:

这更有趣。此处的一个简单步骤是通过再次添加主题标题在下一栏中继续上一个主题。像这样的东西:

Topic A    Topic A    Topic B
 - A-1      - A-5      - B-4
 - A-2     Topic B     - B-5
 - A-3      - B-1      - B-6
 - A-4      - B-2
            - B-3

要实现这一点,您需要以不同方式处理数据,即按元素(新闻)计数。

假设您设法从数据库中检索分组(并因此排序)的数据:

SELECT TopicName, NewsID FROM news GROUP BY 1;

然后您可以遍历所有返回的行并创建您的列,最后输出它们(已经解决):

$itemsPerColumn = 4;

// get columns
$topics = array();
$items = 0;
$lastTopic = NULL;

foreach ($rows as $row)
{
    if ($lastTopic != $row['TopicName'])
    {
        $topic = array('title' => $row['TopicName']);
        $topics[] = &$topic;
    }
    $topic['entries'][] = $row;

    $items++;
    if ($items === $itemsPerColumn)
    {
        $columns[] = $topics;
        $topics = array();
        $lastTopic = NULL;
    }
}

// output
foreach($columns as $column)
{
    render_column($column);
}

所以这实际上与之前的答案相当,但这次您不需要重新排列数组来获取按主题排序的新闻,因为数据库查询已经这样做了(您可以为之前的答案这样做也回答)。

然后又是一样的:迭代返回的结果集并将数据放入可以输出的结构中。输入、处理、输出。总是一样的。

希望对您有所帮助。

关于PHP - 嵌套列表分成偶数列(修复和更新),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8364358/

相关文章:

php - 制作所有 GET 变量的数组

php - Mac 雪豹 Mcrypt 扩展

php - CodeIgniter - Group by with order by 不按预期工作

mysql - 如何在一个查询中执行两次 COUNT(*) 获取?

css - 更改透明div中文本的颜色

html - 有些 Css 类有效,有些则无效

php - Laravel - 自动加载 View

php - 如何在 laravel 的自定义请求类中传递消息?

mysql group by 和 order by 不起作用

blackberry - 如何仅在带有物理键盘的小屏幕黑莓上增加字体大小?