[英]How to generate a PHP array from MySQL database record for multi-level folder structure
我想用PHP和MySQL構建Evernote風格的筆記應用程序。
Evernote允許其中包含便箋記錄的頂級文件夾。
我想讓我的應用程序允許文件夾位於文件夾內,以便頂層文件夾可以具有子文件夾,然后在子文件夾內具有注釋記錄。
就像下面的這張圖...
我有這個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> ' . $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個數據庫表構建如下數組的函數來幫助我。
我的數據庫表將是
parent
筆記本表示父文件夾。 如果筆記本ID是父筆記本的子文件夾,則該筆記本ID將進入父字段。 0 ==父級文件夾。 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())
輕松彈出一些按鍵檢查。
潛在的“ Gotcha”
這適用於名稱。 如果您允許“筆記本”使用相同的名稱,建議您更進一步,並通過id而不是像筆記本標題那樣的基於文本的列來構建數組。 從那里,您需要在每個筆記本內部添加一個名稱本身的新密鑰。 在制作此腳本時,我復制了您在示例中提供的數組,但我確實想確保您了解此方法涉及的潛在(令人沮喪)“陷阱”。
如果您有任何疑問,請告訴我,希望能對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.