1

我想我的第一个问题是,因为我是唯一的开发人员,所以我想念别人提出想法,或者当我遇到问题时得到想法。是否有专门解决该问题的网站?像一个虚拟的联合程序员网站?或者 StackOverflow 可以这样工作吗?

我的主要问题:我正在研究类似“待办事项”列表的东西,但每个项目都可能有子步骤……甚至是子子步骤……甚至可能更进一步。我有一个包含“id、item、parent_id”字段的表,所有顶级项目的 parent_id = 0。在 CodeIgniter 中使用 Datamapper ORM,我正在使用这个:

$i = new Item();
$i->where('parent_id',0)->get();
foreach($i as $item) {
   echo $item->item;
   $si = new Item();
   $si->where('parent_id',$item->id)->get();
   foreach($si as $subItem) {
      echo $subItem->item;
      // and so on
   }
}

它有效,但有没有更聪明的方法来实现这一点?也许某种递归函数?

我也在努力让其他人管理所有内容,这样他们就可以将项目拖放到他们需要去的地方......但这是另一回事了。

4

3 回答 3

3

如果我是你,我会考虑实现一个树结构。您基本上已经为此处的邻接列表设置了基础(从数据库的角度来看 - 您仍然需要编写和测试的 php 代码)。如果您添加一level列来定义任何给定任务在其层次结构中的级别,您可以通过自联接使用 1-2 个查询提取所有数据,尽管如果嵌套级别非常深,这将很慢。

另一种方法是使用嵌套集和预序树遍历,这需要更多的工作,特别是考虑到您似乎不需要每个节点的多个分支。

看看在 MySQL 中管理分层数据,它从数据库方面详细解释了这两个方面......它是特定于 MySQL 的,但您应该能够以与数据库无关的方式或其他特定数据库应用相同的原则。

当然,无论哪种方式,您都需要在 PHP 端为此实现映射,这比您现在做的工作要多……但它也允许您访问数据库的次数更少。

我还建议使用 Doctrine(Seth 也推荐)而不是 CI Datamapper...它已经实现了所有这些...您只需要学习 Doctrine 的基础知识并将其与 CI 挂钩,我确信有大量的教程。

于 2010-12-28T15:33:46.633 回答
3

如果您编写自己的 SQL,则可以在 3 个查询中完成此操作。

"SELECT * FROM items WHERE parent_id = 0;"
"SELECT * FROM items WHERE parent_id IN (SELECT id FROM items WHERE parent_id = 0;"

但是,您看起来想要一个多嵌套的树状结构

| item |
  | sub-item |
    | sub-sub-item |

如果您使用 CI,有一个(在我看来)更好的 ORM,称为Doctrine,它将处理自引用树状数据结构(按照您的建议使用递归)。值得庆幸的是,有一篇很好的文章将它整合到 CodeIgniter 中!

http://www.phpandstuff.com/articles/codeigniter-doctrine-from-scratch-day-1-install-and-setup

Doctrine 将为您构建查询 - 它还支持关系和许多其他方便的功能,例如 CodeIgniter 缺乏的缓存 :)

于 2010-12-28T15:27:45.683 回答
0

像这样的事情,未经测试:count($ss) 可能不会返回一个好的值来查看查询是否返回任何结果,所以请根据需要进行更新(在 Zend 中,我可以依靠 Zend_Db_Table_Rowset 但不知道什么对象 CI返回,如果您可以计算结果的数量)请更新 if 语句以仅在您查询返回结果时调用该函数)

    function recursive( $i )
    {
        foreach ( $i as $item )
        {
            echo $item->item;
            $si = new Item();
            $ss = $si->where('parent_id', $item->id)->get();
            if ( count($ss) > 0 ) 
                recursive($ss);
        }
    }
    $i = new Item();
    recursive($i->where('parent_id', 0)->get());
于 2010-12-28T15:26:26.560 回答