php - 如何从 MySQL 数据库记录为多级文件夹结构生成 PHP 数组

标签 php mysql multidimensional-array menu

我想用 PHP 和 MySQL 构建一个 Evernote 风格的笔记应用。

Evernote 允许在其中包含笔记记录的顶级文件夹。

我想让我的应用程序允许文件夹位于文件夹内,这样顶级文件夹可以有一个子文件夹,然后在子文件夹内有笔记记录。

喜欢下面这张图片...

enter image description here


我有这个 PHP 函数,它将构建如上图所示的结构菜单...

此代码构建显示的菜单

<?php
function tree($array, $parent, $parts = array(), $step = 0) {

    if (!count($array)) {
        return '';
    }

    $tid = ($step == 0) ? 'id="tree"' : '';
    $t = '<ul class="unstyled" '.$tid.'>';

    foreach ($array as $key => $item) {
        if (is_array($item)) {
            $open = $step !== false && (isset($parts[$step]) && $key == $parts[$step]);

            $t .= '<li class="directory'. ($open ? ' open' : '') .'">';
                $t .= '<a href="#" data-role="directory"><i class="glyphicon glyphicon-folder-'. ($open ? 'open' : 'close') .'"></i>&nbsp; ' . $key . '</a>';
                $t .= tree($item, "$parent/$key", $parts, $open ? $step + 1 : false);
            $t .=  '</li>';
        } else {
            $selected = (isset($parts[$step]) && $item == $parts[$step]);
            $t .= '<li class="file'. ($selected ? ' active' : '') .'"><a href="'. $parent .'/'. $item . '">'.$item.'</a></li>';
        }
    }

    $t .= '</ul>';

    return $t;
}
?>

上面的代码通过调用_getTree()构建树形菜单

protected function _getTree($dir = LIBRARY)
{
    $return = array('directories' => array(), 'files' => array());

    $items = scandir($dir);
    foreach ($items as $item) {
        if(preg_match($this->_ignore, $item)) {
            if($this->_force_unignore === false || !preg_match($this->_force_unignore, $item)) {
                continue;
            }
        }

        $path = $dir . DIRECTORY_SEPARATOR . $item;
        if (is_dir($path)) {
            $return['directories'][$item] = $this->_getTree($path);
            continue;
        }

        $return['files'][$item] = $item;
    }

    uksort($return['directories'], "strnatcasecmp");
    uksort($return['files'], "strnatcasecmp");

    return $return['directories'] + $return['files'];
}

上面的

_getTree() 通过扫描服务器上的目录来查找文件夹和文件,以如下所示的格式构建一个数组。然后将该数组传递给 tree()。我的目标是让一个函数构建相同样式的数组,但来自 MySQL 数据库文件夹和注释记录。

任何人都可以帮助我使用一个可以从 2 个数据库表构建如下数组的函数。

我的数据库表将是

  • notebooks 列名称 parent 表示父文件夹。如果笔记本是父笔记本的子文件夹,则笔记本 ID 将进入父字段。 0 == 父级文件夹。
  • notes parent 列链接到笔记本的 ID。

非常感谢任何帮助?

Array(
    [top_level_notebook_1] => Array(
            [child_note_of_parent_notebook_1.html] => some_note.html
            [child_level_notebook_1] => Array(
                    [note_1.html] => some_note.html
            )

            [child_level_notebook_2] => Array(
                    [note_2] => cache.js
                    [note_3] => cache.js.md
                    [note_4] => Confirmation-Dialog.js
            )

            [child_level_notebook_3] => Array(
                    [crud.php] => crud.php
                    [error2mysql.php] => error2mysql.php
                    [upload_file_from_remote_url.php] => upload_file_from_remote_url.php
            )

    )

    [top_level_notebook_2] => Array(
            [note_7.html] => some_note.html
    )

    [root_level_note.html] => Dev_Bookmarks.html
)

最佳答案

除非您想使查询变得异常复杂,否则我会按照获取所有记录和使用脚本构建数组的方式做更多的事情。像这样:

现在包含数据库内容的脚本(已更新):

//Change these credentials!
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

$query = "SELECT nb.`name` AS 'notebook', no.`name` AS 'note', (SELECT `name` FROM `notebooks` WHERE `id` = nb.`parent`) AS 'nbparent', no.`parent` AS 'noparent' FROM `notebooks` nb RIGHT JOIN `notes` no ON no.`parent` = nb.`id` WHERE (nb.`active` = 1 OR nb.`active` IS NULL) AND (no.`active` = 1 OR no.`active` IS NULL)";

$result = $mysqli->query($query);

$myArray = array();

while($row = $result->fetch_assoc()){
    if($row['nbparent']){
        if($row['note']) $myArray[$row['nbparent']][$row['notebook']][] = $row['note'];
    } else {
        if($row['note']) {
            if($row['notebook']) $myArray[$row['notebook']][] = $row['note'];
                else $myArray[] = $row['note'];
        }

    }

}

var_dump($myArray);

这应该有效!我在我的本地开发环境中对其进行了测试,并通过一组测试数据得到了这个结果:

array (size=4)
  'Parent Notebook1' => 
    array (size=6)
      0 => string 'Note1' (length=5)
      1 => string 'Note2' (length=5)
      2 => string 'Note5' (length=5)
      'Child Notebook1' => 
        array (size=1)
          0 => string 'Note6' (length=5)
      'Child Notebook2' => 
        array (size=1)
          0 => string 'Note7' (length=5)
      'Child Notebook3' => 
        array (size=1)
          0 => string 'Note8' (length=5)
  'Parent Notebook2' => 
    array (size=1)
      0 => string 'Note3' (length=5)
  'Parent Notebook3' => 
    array (size=1)
      0 => string 'Note4' (length=5)
  0 => string 'Note With No Parent :(' (length=22)

它所做的是遍历每个结果。当然,您需要将列名称更改为您实际列的名称,例如 $row['notebook'] 中的名称。它会在一个层次上起作用。如果您需要更多,则必须稍微调整一下。不过,这是一般的想法,应该从您的结构中构建一个数组。

速记

上面的代码不是严格友好的。如果你关心警告,上面的代码会给你关于未定义键的警告。它会为您创建它们,因为我们都对 PHP 爱恨交加。如果您想将键警告排除在外,您可以使用 if(array_key_exists()) 轻松弹出一些键检查。

潜在的“陷阱”

这适用于名称。如果您允许“笔记本”使用相同的名称,我建议您更进一步,通过 id 而不是像笔记本标题这样的基于文本的列来构建数组。从那里开始,您需要在每个笔记本中添加一个新 key ,并使用名称本身。在制作此脚本时,我复制了您在示例中提供的数组,但我确实想绝对确保您理解此方法涉及的潜在(令人沮丧的)“陷阱”。

如果您有任何问题,请告诉我,希望对您有所帮助。

关于php - 如何从 MySQL 数据库记录为多级文件夹结构生成 PHP 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35351005/

相关文章:

mysql - SELECT with WHERE IN 和子查询非常慢

python - 动态重新定义 numpy 数组

vb.net - 强类型多维数组/集合

php - 如何从字符串创建对象?

php - mysql 中的 Rails 多数组格式

php - 如何在 PHP 中获取枚举的默认值?

javascript - 如何在 Typescript 中声明给定大小的多维数组

php - 使用 PHP 从 Wordpress 自定义表中检索数据

php - PHP中的stdClass是什么?

php - 剥离危险的 html 标签、mysql 注入(inject)并在 php 中保留 'good' 标签的最佳方法