我最终通过不将菜单项放入多维数组来解决这个问题。
我所寻找的最终结果是将DB查询转换为HTML,因此有了父数组和子数组,我创建了一个递归函数,将菜单项连接到一个带有标记的无序列表中。
到目前为止,我已经用3个深度测试了它,但从我所能看到的情况来看,它不应该随着深度的加深而破裂。
// returns a string value of an HTML built multi-level list ready to display in HTML
// requires 2 arrays. $tree array contains the top parent folders
// and $children array contains all other folders which are not the top parents i.e. all the children
// and grandchildren and so on.
function findChildren($tree, $children){
$message = "";
foreach($tree as $folder){
$parent = array();
if($folder['parentId'] === null) {
$message .= "<li id='" . $folder['folderId'] . "'>" . $folder['folderName'] . " " . $folder['folderId'];
}
$i = 0;
foreach ($children as $child) {
if ($child['parentId'] === $folder['folderId']) {
if (($childKey = array_search($child, $children)) !== false) {
if($i === 0){
$message .= "<ul>";
}
$message .= "<li>" . $child['folderName'] . " " . $child['folderId'];
$parent[$i] = $children[$childKey];
unset($children[$childKey]);
$message .= "</li>";
}
$i++;
}
}
if(isset($parent[0])) {
$message .= findChildren($parent, $children);
}
if($i > 0){
$message .= "</ul>";
}
if($folder['parentId'] === null) {
$message .= "</li>";
}
}
return $message;
}
// Searches through DB for user folders and returns whatever findChildren() returns.
// requires a $userID as int
function getDirTree($userId){
global $mysqli;
$children = array();
$tree = array();
if($folders = $mysqli->prepare("SELECT folders.id, folders.name, child_of_folder.parent_id
FROM child_of_folder
RIGHT JOIN folders
ON (child_of_folder.child_id = Folders.id)
WHERE folders.user_id = ?;")) {
// Bind the parameters... s for String and the variable $name to be bound.
if ($folders->bind_param("i", $userId)) {
// execute the query
if ($folders->execute()) {
// store the results
if($folders->store_result()){
// bind the results
if($folders->bind_result($folderId, $folderName, $parentId)) {
// Fetch the results
while ($folders->fetch()) {
if ($parentId === null) {
array_push($tree, array('folderId' => $folderId, 'folderName' => $folderName, 'parentId' => $parentId));
} else {
array_push($children, array('folderId' => $folderId, 'folderName' => $folderName, 'parentId' => $parentId));
}
}
} else {
$hasFolder = null;
}
} else {
// if there were no values to store return false
$hasFolder = null;
}
} else {
// if there was a problem executing the statement return null
$hasFolder = null;
}
} else {
// if there was a problem binding the statement return null
$hasFolder = null;
}
} else {
// if there was a problem preparing the statement return null
$hasFolder = null;
}
// Call findChildren
$message = findChildren($tree, $children);
// Add the surrounding block elements which would ideally be placed in the template to separate php logic and html
if ($message != ""){
$message = "<ul>" . $message;
$message .= "</ul>";
} else {
$message .= "No Folders Created";
}
$folders->free_result();
$mysqli->close();
return $message;
}