PHP:Tricky Nested Loop with select

时间:2017-03-24 20:54:36

标签: php database loops for-loop foreach

我目前的项目有问题。

我的数据库中有这个:

ID ---- FOLDERID ----说明

1 ---- 0 ---- =>根文件夹(无法删除)

2 ---- 1 ---- =>第一个文件夹(对根文件夹的引用)

3 ---- 1 ---- =>第二个文件夹(也引用Root)

4 ---- 2 ---- =>第一个文件夹中的子文件夹

5 ---- 4 ---- =>子文件夹中的子文件夹

这将显示如下:

  1. 第一个文件夹
    1. 子文件夹
        1. 子文件夹中的子文件夹
  2. 第二个文件夹
  3. 好的,所以当我想删除第一个文件夹时,我也要删除所有子文件夹。

    我该如何处理?

    我知道我需要一个带计数器的循环,但我不知道该怎么做。

    这就是我所拥有的:但仅适用于3个文件夹:

         $del_id = [];
    
        do {
            $count = \DB::table('files')
                ->select('id', 'foldersID')
                ->where('userID', '=', \Auth::user()->id)
                ->where('foldersID', '=', $id)
                ->count();
    
            //count = 1
    
            if ($count == 0) {
    
                \DB::table('files')
                    ->where('userID', '=', \Auth::user()->id)
                    ->where('id', '=', $id)
                    ->delete();
    
            } else {
                //hier
                $_id = $id; //2
    
                for ($i = 0; $i <= $count; $i++) { //1 mal
    
                    $_files = \DB::table('files')
                        ->select('id')
                        ->where('userID', '=', \Auth::user()->id)
                        ->where('foldersID', '=', $_id)
                        ->get();
    
                    //3
    
                    $files = json_decode($_files, true);
    
                    //return print_r($files);
                    // return count($files);
                    for ($i = 0; $i <= count($files) - 1; $i++) {
                        array_push($del_id, $files[$i]);
                    }
                   //3 && 4
                }
    
                for ($i = 0; $i <= count($del_id) - 1; $i++) {
                    $_files = \DB::table('files')
                        ->select('id')
                        ->where('userID', '=', \Auth::user()->id)
                        ->where('foldersID', '=', $del_id[$i])
                        ->get();
    
                    $files = json_decode($_files, true);
                    return $files;
    
                    /*   \DB::table('files')
                        ->where('userID', '=', \Auth::user()->id)
                        ->where('id', '=', $del_id[$i])
                        ->delete();
                */
                 }
    
                \DB::table('files')
                    ->where('userID', '=', \Auth::user()->id)
                    ->where('id', '=', $id)
                    ->delete();
    
            }
        } while ($count >= 1);
    

    有人可以帮助我吗?

    提前致谢。

1 个答案:

答案 0 :(得分:0)

您需要使用递归来执行此操作。基本上,创建一个删除文件夹的功能。当调用该函数时,它会检查它是否有任何子文件夹,如果有,它会调用自己的子文件夹的id。

下面我已经包含了SQL来测试它以及显示递归方法的PHP脚本。

SQL创建“测试”数据库

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `testing`;

USE `testing`;

DROP TABLE IF EXISTS `files`;
CREATE TABLE `files` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `folderid` int(11) NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

LOCK TABLES `files` WRITE;
INSERT INTO `files` VALUES (1,0,'root folder'),(2,1,'first folder'),(3,1,'second folder'),(4,2,'sub of first folder'),(5,4,'sub of sub folder');
UNLOCK TABLES;

使用递归的PHP脚本

<?php

delete_folder(2);


function delete_folder($folder_id) {
    $servername = "localhost";
    $username = 'root';
    $password = 'my_password';
    $dbname = "testing";

    // Create connection
    $conn = mysqli_connect($servername, $username, $password, $dbname);
    // Check connection
    if (!$conn) {
        die("Connection failed: " . mysqli_connect_error());
    }

    $table  = "files";

    // find subfolders
    $sub_folders = "select id from $table where folderid = $folder_id";
    $result = $conn->query($sub_folders);

    if($result->num_rows > 0) {
        while($row = $result->fetch_assoc()) {
            echo "found sub folder with id: ".$row["id"]." - recursing\n";
            delete_folder($row["id"]); // calls itself to delete subfolder.
        }
    }

    // delete this folder
    $delete_sql = "delete from $table where id = $folder_id";
    echo "deleting folder with id: $folder_id";
    if($conn->query($delete_sql) === TRUE) {
        echo " - success\n";
        return;
    } else {
        echo " - failed\n";
        die("Failed to delete folder");
    }
    return;
}

?>

创建数据库并运行脚本的示例

导入我们的数据:

root@zim:~/testing# mysql -p < testing.sql
Enter password:

看到表中的内容:

root@zim:~/testing# mysql -p -e 'select * from files' testing;
Enter password:
+----+----------+---------------------+
| id | folderid | description         |
+----+----------+---------------------+
|  1 |        0 | root folder         |
|  2 |        1 | first folder        |
|  3 |        1 | second folder       |
|  4 |        2 | sub of first folder |
|  5 |        4 | sub of sub folder   |
+----+----------+---------------------+

运行我们的脚本:

root@zim:~/testing# php db_recursion.php
found sub folder with id: 4 - recursing
found sub folder with id: 5 - recursing
deleting folder with id: 5 - success
deleting folder with id: 4 - success
deleting folder with id: 2 - success

现在查看表格中的内容:

root@zim:~/testing# mysql -p -e 'select * from files' testing;
Enter password:
+----+----------+---------------+
| id | folderid | description   |
+----+----------+---------------+
|  1 |        0 | root folder   |
|  3 |        1 | second folder |
+----+----------+---------------+