我们要开发的todo列表类似菜单项,每个菜单可以有多个菜单项,每个菜单项又可以有多个子菜单,我们的todo有一系列任务,每个任务又有多个子任务,以此类推。数据库设计:
每个task有一个parent_id,task_id与parent_id之间形成一种伪外主键关系。
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <title>View Tasks</title> </head> <body> <h3>Current To-Do List</h3> <?php # Script 1.5 - view_tasks2.php /* This page shows all existing tasks. * A recursive function is used to show the * tasks as nested lists, as applicable. * Tasks can now be marked as completed. */ // Retrieve all the uncompleted tasks: // Connect to the database: $dbc = @mysqli_connect ('localhost', 'username', 'password', 'test') OR die ('<p>Could not connect to the database!</p></body></html>'); $q = 'SELECT task_id, parent_id, task FROM tasks WHERE date_completed="0000-00-00 00:00:00" ORDER BY parent_id, date_added ASC'; $r = mysqli_query($dbc, $q); // Initialize the storage array: $tasks = array(); while (list($task_id, $parent_id, $task) = mysqli_fetch_array($r, MYSQLI_NUM)) { // Add to the array: $tasks[$parent_id][$task_id] = $task;
会形成这种形式:
Array | |
( | |
[0] => Array | |
( | |
[2] => task2 | |
[3] => task3 | |
[1] => task1 | |
) | |
[1] => Array | |
( | |
[4] => task11 | |
[5] => task12 | |
[6] => task13 | |
) | |
) |
} 可以看到所有父级都在$task[0]里面,$task[1]则存储了父级1的儿子。 // Function for displaying a list. // Receives one argument: an array. function make_list ($parent) { 调用时$parent=$task[0] // Need the main $tasks array: global $tasks; // Start an ordered list: echo '<ol>'; // Loop through each subarray: foreach ($parent as $task_id => $todo) { // Display the item: // Start with a checkbox! echo <<<EOT <li><input type="checkbox" name="$tasks[$task_id]" value="done" /> $todo EOT; // Check for subtasks: if (isset($tasks[$task_id])) { // Call this function: make_list($tasks[$task_id]); } // Complete the list item: echo '</li>'; 这才结束li } // End of FOREACH loop. // Close the ordered list: echo '</ol>'; } // End of make_list() function. // Check if the form has been submitted: if (isset($_POST['submitted']) && isset($_POST['tasks']) && is_array($_POST['tasks'])) { // Define the query: $q = 'UPDATE tasks SET date_completed=NOW() WHERE task_id IN ('; // Add each task ID: foreach ($_POST['tasks'] as $task_id => $v) { $q .= $task_id . ', '; } // Complete the query and execute: $q = substr($q, 0, -2) . ')'; $r = mysqli_query($dbc, $q); // Report on the results: if (mysqli_affected_rows($dbc) == count($_POST['tasks'])) { echo '<p>The task(s) have been marked as completed!</p>'; } else { echo '<p>Not all tasks could be marked as completed!</p>'; } } // End of submission IF. // For debugging: //echo '<pre>' . print_r($tasks,1) . '</pre>'; // Make a form: echo '<p>Check the box next to a task and click "Update" to mark a task as completed (it, and any subtasks, will no longer appear in this list).</p> <form action="view_tasks2.php" method="post"> '; // Send the first array element // to the make_list() function: make_list($tasks[0]); // Complete the form: echo '<input name="submitted" type="hidden" value="true" /> <input name="submit" type="submit" value="Update" /> </form> '; ?> </body> </html>
我们代码的关键是建立一个二维数组,第一维是表示父级,
0表示最高级。
1表示以task_id=1为父的所有子集
第二维表示某个task_id.
代码来自:php Advance visual quickPro guide 这本书