【问题标题】:Generate a tree with recursive array combining data from two tables使用递归数组组合来自两个表的数据生成一棵树
【发布时间】:2011-01-19 14:52:28
【问题描述】:

我必须从 PHP 中的两个 MySQL 表生成一个树并用 HTML 打印它。我的主要问题是我有两个表来获取数据。一个表格是pages和其他translations,因为我在网站上有 3 种语言,所有翻译都保留在 translations 表格中。

这个表的架构是:

页面

id INT
id_user INT
id_parent INT
order INT
template INT
image VARCHAR
flag_active INT
flag_extra INT
edited INT
created INT

翻译

id INT
id_user INT
locale VARCHAR
module VARCHAR
pk INT
label VARCHAR
value TEXT
edited INT

当我添加页面时,我会将页面的值 title, slug and text(不在架构上,因为取决于语言环境)到翻译中:

INSERT INTO pages (id_user, template, image, flag_active, flag_extra, edited, created)
VALUES (1, 0, 'test.jpg', 1, 1, 12345, 12345)

<!-- the pages.id is 4, for example, for next insert: -->

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'en', 'pages', 4, 'title', 'This is the title in English', 12345)

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'en', 'pages', 4, 'slug', 'this-is-the-title-in-english', 12345)

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'en', 'pages', 4, 'text', 'This is the text in English', 12345)

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'es', 'pages', 4, 'title', 'Este es el titulo en Español', 12345)

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'es', 'pages', 4, 'slug', 'este-es-el-titulo-en-espanol', 12345)

INSERT INTO translations (id_user, locale, module, pk, label, value, edited)
VALUES (1, 'es', 'pages', 4, 'text', 'Este es el contenido en Español', 12345)

然后,当我必须访问某种语言的页面时,首先在 PHP 中,我从表 pages 中选择页面,然后在 translations 中查找:WHERE module='pages' AND pk='4' AND locale='en',我得到了所有信息我需要从页面和翻译后的文本值。

我已经解释了我的翻译系统是如何工作的。现在我在后端(和前端)遇到了问题,因为我需要用一种语言从这些页面构建一棵树。我的想法是抛出一个递归数组,但我不知道如何合并数据,因为我认为这将是 PHP 而不是 MySQL。

我还没有构建树函数,我认为我需要树函数,因为:

  1. 我需要从 MySQL 查询生成和数组,结合页面数据和翻译。
  2. 我需要用嵌套树在 HTML 中生成一个&lt;ol /&gt; 列表。

对于第一个树数组,即 MySQL 数组,我需要为每个条目创建一个 MySQL?或者这可以只用一个 MySQL 查询来完成?代码示例,未测试直接写:

function mysql_tree($parent_id = 0)
{
    $return = array();

    $query = "SELECT * FROM pages WHERE id_parent=$parent_id";

    $result = mysql_query($query);

    if(mysql_num_rows($result) != 0)
    {
        $i = 0;

        while($row = mysql_fetch_array($result))
        {
            $return[$i] = array(
                'id' => $row["id"];
                //etc
            );

            // Time to merge the data for each page from translations????

            $return[$i]["childs"] = mysql_tree($row["id"]);

            $i++;
        }
    }

    return $return;
}

对于第二个树函数我想是不是类似于 MySQL 的?

提前谢谢你!

更新:文森特请求的嵌套列表示例

Array(
    [0] => Array(
        [id] => 4
        [id_user] => 1
        [id_parent] => 0
        [order] => 0
        [template] => 1
        [image] => NULL
        [flag_active] => 1
        [flag_extra] => 0
        [edited] => 12345
        [created] => 12345
        [title] => This is the title in English
        [slug] => this-is-the-slug-in-english
        [childs] => Array(
            [0] => Array(
                [id] => 5
                [id_user] => 1
                [id_parent] => 4
                [order] => 0
                [template] => 1
                [image] => NULL
                [flag_active] => 1
                [flag_extra] => 0
                [edited] => 12345
                [created] => 12345
                [title] => This is the title in English 2
                [slug] => this-is-the-slug-in-english-2
                [childs] => NULL
            )
        )
    )
)

还有 HTML 树:

<ol>
    <li class="id_4"><a href="/pages/this-is-the-slug-in-english">This is the title in English</a>
        <ol>
            <li class="id_5"><a href="/pages/this-is-the-slug-in-english-2">This is the title in English 2</a></li>
        </ol>
    </li>
</ol>

【问题讨论】:

  • @Tomalak:哈哈,我试图解释整个事情,因为人们通常说我没有很好地描述和回答。恢复:我有两个用于嵌套树的表,不能在 MySQL 中连接,因为它使用另一个过程来存储语言,我想知道如何用更少的 MySQL 查询生成树。
  • 您能举例说明生成的嵌套列表会是什么样子吗?您是否只想显示页面标题并在每个页面标题下缩进所有子级?
  • @Vincent:已更新。该数组是手动编写的,因此可能会出现一些错误,但您明白了。谢谢!

标签: php mysql


【解决方案1】:

我终于通过使用所需的 MySQL 查询解决了这个问题。我发布代码是因为可能对其他用户有用。我正在使用 CodeIgniter,但它可以与普通的 mysql_query() 一起使用。

PS:请注意,我使用的是西班牙名字,顺便说一句,这很容易理解。

public function tree($id_padre = 0, $locale = null)
{
    $return = array();

    if(false == is_numeric($id_padre))
        return $return;

    if(null == $locale)
        return $return;

    $query = $this->db->where("id_padre", $id_padre)->get("paginas");

    if($query->num_rows() > 0)
    {
        $i = 0;

        foreach($query->result_array() as $row)
        {
            $translation = (array) $this->get($row["id"], $locale); // This returns the "title", "slug" and "text" from the translations tables

            $data["id"] = $row["id"];
            $data["id_padre"] = $row["id_padre"];
            $data["orden"] = $row["orden"];

            $data = array_merge($data, $translation);

            $data["childs"] = $this->tree($row["id"], $locale);

            $return[$i] = $data;

            unset($data);

            $i++;
        }

        return $return;

    }
    else {
        return NULL;
    }
}

还有 HTML 树:

function backend_tree($array = null, $class = null)
{
    if(null == $array)
        return false;

    $return = '<ol';

    if(null != $class)
        $return .= ' class="'.$class.'"';

    $return .= '>';

    foreach($array as $item)
    {
        $return .= '<li id="id-'.$item["id"].'"><div>'.$item["titulo"];
        $return .= '<div class="edit">'.anchor("/admin/carta/edit/".$item["id"], " ", array("class" => "sortableEdit")).' '.anchor("/admin/carta/delete/".$item["id"], " ", array("class" => "sortableDelete")).'</div>';
        $return .= '</div>';
        $return .= backend_tree($item["childs"]);
        $return .= '</li>';
    }

    $return .= '</ol>';

    return $return;
}

【讨论】:

    【解决方案2】:

    更少的查询 - 意味着加入:-)

    想法 - 用语言加入它 - 所以你每页得到 3 行,并将其处理成相关的数组:-) (例如 $result[$row["id"]]['title'] = $row[ '标题'];)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      相关资源
      最近更新 更多