2010-03-03 38 views
2

我试图从表中检索分层数据,但是我没有这样做。该表(现在)具有以下列:ifc_key,ifc_name,ifc_parent。不使用ifc_key。 (主键,但不用于此功能)从递归函数中检索分层数据(Zend Framework)

目的是获取一个数组,每个元素都是一个“父”接口(因此所有这些根元素都是没有ifc_parent集的ifc_name值等于ifc_name如果设置)

考虑以下布局(演示):

ifc_key | ifc_name | ifc_parent
0 | parent_ifc |
1 | A0A | parent_ifc
2 | A0B | parent_ifc
3 | b0a | vif1
4 | b0b | vif1
5 | vif1 | A0A

所以我在寻找的阵列,从查询生成的是:

Array 
(
[parent_ifc] => Array 
    (
     [a0a] => Array 
      (
       [vif1] => Array 
        (
         [0] => b0a 
         [1] => b0b 
        ) 

      ) 

     [a0b] => 
    ) 
) 

我想出了这个功能是本段的下面。我想创建一个递归函数,该函数在查找孩子时调用它自己,但问题是在首次调用此方法时没有选择任何孩子。 (那些有空父母的人本身就是父母)。所以我只能让父母回来,但没有一个孩子(也可能是他们的孩子等 - 这在理论上可能是无限的)。

public static function getByFilerOrganisedChildren($filer_id, $parent = '') 
{ 
    $table = new Filer_Interface_Table(); 
    $where[] = $table->getAdapter()->quoteInto('ifc_system_id = ?', $filer_id); 
    $where[] = $table->getAdapter()->quoteInto('ifc_parent = ?', $parent); 
    $rows = $table->fetchAll($where, 'ifc_parent ASC'); 

    foreach ($rows as $row) { 
     if ($row->ifc_parent == '') $data[] = $row->ifc_name; 
     else { 
      $data[$row->ifc_parent][] = $row->ifc_name; 
      self::getByFilerOrganisedChildren($filer_id, $row->ifc_parent); 
     } 
    } 

    return (isset($data) ? $data : false); 
} 

回答

2

在你的方法之前,你没有提及ifc_system_id列,所以我认为这不是立即与问题相关的。你指定的输出也是不符合要求的。

您错过的关键似乎是使用与子记录相关的数据调用递归函数 - 在这种情况下为ifc_name而不是ifc_parent

public function getByFilerOrganisedChildren($filer_id, $parent = '') 
{ 
    $table = new Filer_Interface_Table(); 
    $where[] = $table->getAdapter()->quoteInto('ifc_system_id = ?', $filer_id); 
    $where[] = $table->getAdapter()->quoteInto('ifc_parent = ?', $parent); 
    $rows = $table->fetchAll($where, 'ifc_parent ASC'); 

    $data = array(); 
    foreach ($rows as $row) { 
     $data[$row->ifc_name] = $this->getByFilerOrganisedChildren($row->ifc_name); 
    } 

    return (! empty($data) ? $data : false); 
} 
0

你能写出如何调用这个函数吗?什么是参数? 而且我认为你必须让你的类的数据私有静态字段为空

+0

$接口= Filer_Interface :: getByFilerOrganisedChildren($ filer-> SYSTEM_ID); – Tom 2010-03-04 07:58:28

0

我不是在这里回答你的问题,而是:这不是存储在数据库中分层数据非常有效的方法。

我宁愿推荐嵌套集(例如在Doctrine ORM和Zend Framework [提案]中有简单的实现)。

您也可以尝试其他方法,如this article(波兰文,但提供的SQL和PHP示例是通用的)中所述。

+0

嗨,我知道这不是存储这种数据的最希望的方式。然而,对于一个读取自动支持邮件(Perl)的现有应用程序来说,它将这些数据存储在应用程序的数据库中。 现在只需要构建一个接口来通过网络查询这些数据。所以必须与我所拥有的一起工作。 – Tom 2010-03-04 10:18:10

0
public static function getByFilerOrganisedChildren($filer_id, $parent = '') 
{ 
    $table = new Filer_Interface_Table(); 
    $where[] = $table->getAdapter()->quoteInto('ifc_system_id = ?', $filer_id); 
    $where[] = $table->getAdapter()->quoteInto('ifc_parent = ?', $parent); 
    $rows = $table->fetchAll($where, 'ifc_parent ASC'); 

    foreach ($rows as $row) { 
     $data[$row->ifc_name] = array(); 
     /* self::getByFilerOrganisedChildren($filer_id, $row->ifc_name); */ 
    } 

    Zend_Debug::dump($data); 

    return (isset($this->data) ? $this->data : false); 
} 

通过上面的注释行中,输出由Zend_Debug ::转储()为:

阵列(7){
[ “CIFS-80”] =>数组(0) {
}
[ “e0M”] =>数组(0){
}
[ “LO”] =>数组(0){
}
[ “VIF1”] =>数组(0 ) {
}
[ “vif1-81”] =>数组(0){
}
[ “vif1-82”] =>数组(0){
}
[ “vif1-83” ] =>数组(0){
}
}

这些是所有的 “父母”。但如预期的那样(因为对表格的调用是“ifc_parent =''”),没有一个孩子(以及他们可能的孩子)被返回。

然而,当我取消对该行:

self::getByFilerOrganisedChildren($filer_id, $row->ifc_name); 

输出是:

NULL 

我想这是因为:

abstract class Filer_Interface_Abstract extends Filer_Db_Class 

但我无法改变这个 - 因为这是当前应用程序的构建方式。建议?

0

我的代码

DB计划:

create table roles (
    id  int not null auto_increment, 
    name varchar(50) UNIQUE not null, 
    inherit_id int 
) 

PHP代码:

class Default_Model_Roles extends Zend_Db_Table_Abstract { 

    protected $_parents = array(); 

    public function getParents($id) { 
     $this->_getAllParents($id); 
     return (! empty($this->parents) ? $this->parents : FALSE); 
    } 

    public function _getAllParents($id) { 
     $select = $this->select(); 
     $select->where('id = ?', $id) 
      ->order('id'); 
     $row = $this->fetchRow($select); 
     $this->parents[] = $row->id; 
     if ($row->inherit_id != NULL) 
      $this->_getAllParents($row->inherit_id); 
    } 
} 

用途:

$table = new Default_Model_Roles(); 
$parents = $table->getParents($this->role_id);