Laravel中如何删除同表内关联的所有层级文件夹?
解决文件夹级联删除问题的几种方案
方案1:递归获取子文件夹ID后批量删除
先写个递归函数把指定父文件夹下所有层级的子文件夹ID都捞出来,再把父ID和这些子ID放一起批量删除,代码示例:
// 递归获取所有子文件夹ID function getAllChildFolderIds($parentId) { $childIds = Folder::where('parent_id', $parentId)->pluck('id')->toArray(); foreach ($childIds as $id) { $childIds = array_merge($childIds, getAllChildFolderIds($id)); } return $childIds; } // 实际调用 $targetId = 1; $childIds = getAllChildFolderIds($targetId); // 合并父ID和子ID,一次性删除 Folder::whereIn('id', array_merge([$targetId], $childIds))->delete();
方案2:用数据库CTE递归查询(MySQL 8.0+适用)
如果你的MySQL版本是8.0及以上,用公共表表达式(CTE)可以一次性查出所有层级的关联文件夹,效率比PHP递归更高:
$targetId = 1; // 用CTE查询所有要删除的文件夹ID $folderIds = DB::select(" WITH RECURSIVE folder_tree AS ( SELECT id FROM folders WHERE id = ? UNION ALL SELECT f.id FROM folders f JOIN folder_tree ft ON f.parent_id = ft.id ) SELECT id FROM folder_tree ", [$targetId]); // 转成ID数组 $ids = array_column($folderIds, 'id'); // 批量删除 Folder::whereIn('id', $ids)->delete();
方案3:数据库外键级联删除(一劳永逸)
直接在数据库层面设置外键的级联删除规则,这样以后删父文件夹时,数据库会自动帮你删掉所有子文件夹(包括各级嵌套的)。
迁移文件修改示例:
Schema::create('folders', function (Blueprint $table) { $table->id(); $table->string('name'); $table->unsignedBigInteger('parent_id')->nullable(); $table->timestamps(); // 设置外键并开启级联删除 $table->foreign('parent_id') ->references('id') ->on('folders') ->onDelete('cascade'); });
设置好之后,原来的Folder::where('id', $id)->delete();就能自动删掉所有子文件夹了,不用改业务代码。
内容的提问来源于stack exchange,提问作者muntasir
相关产品推荐
相关产品推荐

