在PHP中使用Recursively提取数据库信息

时间:2014-05-02 00:14:29

标签: php mysql database

我在数据库中有这样的表结构:
menuId,label,parentMenuId 如类别和子类别如何在此方法中提取此数据:
将所有菜单分成一个数组:
我想在一个数组列表中提取所有相关菜单。

array(
    [0] => array(array(1,php), array(2,c#), array(3,asp), array(4,perl)),
    [0] => array(array(5,c++), array(6,android), array(7,java), array(8,tcl)),
    ...
    ...
    ...
)

此数组中的所有项都是相关的。 例如,php是c#的父级和asp的asp和asp父级的c#parent,所有这些相关的项目都想在一个数组中提取。

2 个答案:

答案 0 :(得分:0)

你想要这样的东西吗?

$result = array();
$menu_items = array(array("php", "c#", "asp", "perl"),array("vb", "java", "android", "c++"));
foreach($menu_items as $menu_item) {
  foreach($menu_item as $item) {
    array_push($result, $item);
  }
}
print_r($result);

答案 1 :(得分:0)

我使用'redbeanphp'作为数据库'orm',因为它使用PDO并自动定义所有表。使用数据库很有趣。

重要的是要注意'readbeanphp'只是处理数据库。您可以使用'mysqli'或'pdo'替换所有'stores'和'finds'。 'redbeanphp'只是一个自动将调用转换为PDO的层。如果还提取了一些关于获取相关记录的查询。只是省了我们不得不手动编码。它会生成与您手动完全相同的代码。

以下是用于保存和返回带有嵌套菜单的菜单树的经过测试的代码。

可以下载代码并包含“redbeanphp”: Q23418814.zip

1)将菜单创建为数组:

// let us create a menu as we want it to look -- with nested submenus
$menu1Submenus = array( array('PHP', 'C#',
                                array('lisp', 'logo'),
                                'asp', 'perl'),
                 array('c++', 'android', 'java', 'tcl'),
               );

2)连接数据库并为'bean'定义一个常量。

require_once __DIR__ .'/RedBeanPHP4/rb.phar';
\R::setup("mysql:host=localhost;dbname=testmysql", 'test', 'test', false);

define('BEAN_MENUITEM', 'menuitem');

// redbeanphp automatically provides an 'id' for every 'bean'
//
// It will automatically make the foreign key fields
//
// all fields must be lowercase

// clear the table
$result = \R::exec('delete from menuitem');

3)将整个菜单的“父”定义为我们可以存储在数据库中的bean。将自动创建数据库表。

//the owner of the complete menu
$menu1 = \R::dispense(BEAN_MENUITEM);
$menu1->label = 'menu1';
\R::store($menu1);

4)将完整菜单添加到数据库

// add the complete submenus and the items to the database...
foreach($menu1Submenus as $submenu) {
    addSubmenu($menu1, $submenu);
}

echo 'menu stored.';

5)通过获取'parent'bean然后'tree walk'来从数据库中检索菜单。

$parentList = \R::find(BEAN_MENUITEM, " label = ? limit 1", array('menu1'));
if (empty($parentList)) {
    die('menu parent not found!');
}
$parent = current($parentList);

$menu2 = getSubmenu($parent);

6)显示输出:

var_dump($menu1Submenus, 'original',  $menu2, 'from database');
exit;

现在,您需要添加到数据库的例程:

function addSubmenu($parent, $itemList = array())
{
    if (empty($itemList)) {
        return;
    }

    // make an owner for the submenu
    $smOwner = \R::dispense(BEAN_MENUITEM);
    $smOwner->label = 'parent:'. $parent->id;
    $parent->ownMenuitem[] = $smOwner; // sets the foreign key relationship
    \R::store($parent);

    foreach($itemList as $label) {
        if (is_array($label)) { // nested submenu, recurse...
            addSubmenu($smOwner, $label);
            continue; // process next entry...
        }
        $bean = \R::dispense(BEAN_MENUITEM);
        $bean->label = $label;
        $smOwner->ownMenuitem[] = $bean;
        \R::store($smOwner);
    }
}

从数据库中检索......

function getSubmenu($parent, $menuList = array())
{
    $ml = $menuList;

    foreach($parent->ownMenuitem as $entry) {
        if (isSubmenu($entry)) {
            $sm  = array();
            $ml[] = getSubmenu($entry, $sm);
            continue;
        }
        $ml[] = $entry->label;
    }
    return $ml;
}

任何'助手'

function isSubmenu($menuitem)
{
    return strpos($menuitem->label, 'parent:') !== false;
}

示例的数据库输出:

    id  label     menuitem_id  
------  --------  -------------
     1  menu1            (NULL)
     2  parent:1              1
     3  PHP                   2
     4  C#                    2
     5  parent:2              2
     6  lisp                  5
     7  logo                  5
     8  asp                   2
     9  perl                  2
    10  parent:1              1
    11  c++                  10
    12  android              10
    13  java                 10
    14  tcl                  10