根据 select 值显示和删除子文件夹中的文件

Display and delete files from subfolders based on select value

我的文件夹结构有 4 层,我的表格在顶层,目前它只显示顶层的文件,我希望能够 select 一个子文件夹并显示其中的文件所以如有必要,可以删除它们。

Produce
Produce/Meat
Produce/Meat/Beef
Produce/Meat/Beef/Portions
Produce/Meat/Beef/Packaged
Produce/Vegtables
Produce/Vegetables/Fresh
Produce/Vegetables/Fresh/Local etc,.

我的表单显示它所在文件夹的内容,带有复选框,然后我可以勾选框并删除文件,但我添加了一个 select 并希望能够显示 select编辑子文件夹并删除文件。我制作了两个提交按钮并且都有效,但是删除功能只有在顶级文件夹中才有效。

 if ($_POST['delete'] == 'Submit')
    {
    foreach ((array) $_POST['select'] as $file) {

    if(file_exists($file)) {
        unlink($file); 
    }
    elseif(is_dir($file)) {
        rmdir($file);
    }
}
}

$files = array();
$dir = opendir('.');
    while(false != ($file = readdir($dir))) {
        if(($file != ".") and ($file != "..")and ($file != "error_log")) {
                $files[] = $file; 
        }   
    }

if ($_POST['action'] == 'Change') {

if($_POST['folder'] == 'AAA'){
$files = array();
$dir = opendir('/home/mysite/public_html/Produce/Vegetables/');
    while(false != ($file = readdir($dir))) {
        if(($file != ".") and ($file != "..")) {
                $files[] = $file; 
        }   
    }
}
if($_POST['folder'] == 'BBB'){
$files = array();
$dir = opendir('/home/mysite/public_html/Produce/Meat');
    while(false != ($file = readdir($dir))) {
        if(($file != ".") and ($file != "..")) {
                $files[] = $file; 
        }   
    }
}
}
    natcasesort($files);
?>

<form id="delete" action="" method="POST">

<?php
echo '<table><tr>'; 
for($i=0; $i<count($files); $i++) { 
    if ($i%5 == 0) { 
        echo '</tr>';
        echo '<tr>'; 
    }       
    echo '<td style="width:180px">
            <div class="select-all-col"><input name="select[]" type="checkbox" class="select" value="'.$files[$i].'"/>
            '.$files[$i].'</div>
            <br />
        </td>';


 }
    echo '</table>';
    ?>
    </table>
    <br>
    Choose a folder:
            <select name="folder"><option value="this" selected>This folder</option><option value="BBB">Meat</option><option value="CCC">Meat/Beef</option><option value="DDD">Meat/Beef/Portions</option><option value="EEE">Meat/Beef/Packaged</option><option value="FFF">Vegetables</option><option value="GGG">Vegetables/Fresh</option><option value="HHH">Vegetables/Fresh/Local</option><option value="III">Vegetables/Fresh/Packaged</option></select>
            <br>
<input class="button" type="submit" form="delete" name="action" value="Change"><br>
    <button type="submit" form="delete" value="Submit">Delete File/s</button>
    </form><br>

如何利用 selected 值来完成此操作?

首先,我想说明为什么您无法删除顶级文件夹之外的文件。您永远不会更改 "current working directory",因此对深层文件调用删除函数将永远不会按预期工作,并且可能会删除顶级文件夹中的文件。要更正此问题,您需要包含每个要删除的 file/directory 的路径,或者调用 chdir() 一次,以便 unlink()rmdir() 在正确的位置查找。

我相信您的项目还有一些自然成熟的地方要做,包括安全性和用户体验。我会为您提供一个 generalized/simple 片段,供您 consider/compare 针对您的项目,希望能为您的开发提供更多动力。


您的用户将能够在提交时做出以下两个选择之一:更改目录和删除 Files/Directories

对于目录更改,您的程序需要提交两条必要的信息:

  • 动作(动作="change")
  • 新建文件夹(newfolder={variable})

对于file/directory删除,需要三个必要的信息:

  • 动作(动作="delete")
  • files/directory(文件[]={变量})
  • 要访问的目录 (folder={variable}) * <select> 中的值不可信任,因为用户 可以 在选择之前更改所选值删除当前目录下的文件。此值必须静态保留。
    *请注意,您可以只需将路径添加到复选框值中的文件名并消除隐藏的输入 - 这将是一个问题编程偏好。

纯粹出于演示目的,我将在我的代码中引用这个静态文件夹数组:

$valid_folders=[
    'Produce',
    'Produce/Meat',
    'Produce/Meat/Beef',
    'Produce/Meat/Beef/Portions',
    'Produce/Meat/Beef/Packaged',
    'Produce/Vegetables',
    'Produce/Vegetables/Fresh',
    'Produce/Vegetables/Fresh/Local',
    'Produce/Vegetables/Fresh/Packaged'
];

实际上,您可能希望生成一个 valid/permitted/existing 文件夹数组。我可能会建议您看看这个 link:List all the files and folders in a Directory with PHP recursive function

if(isset($_POST['action'])){                               // if there is a submission
    if($_POST['action']=="Delete"){                        // if delete clicked
        if(in_array($_POST['folder'],$valid_folders)){
            $folder=$_POST['folder'];                      // use valid directory
        }else{
            $folder=$valid_folders[0];                     // set a default directory
        }
        chdir($folder);                                    // set current working directory
        //echo "<div>",getcwd(),"</div>";                  // confirm directory is correct
        foreach($_POST['files'] as $file){                 // loop through all files submitted
            if(is_dir($file)){                             // check if a directory
                rmdir($file);                              // delete it
            }else{                                         // or a file
                unlink($file);                             // delete it
            }
        }
    }elseif($_POST['action']=="Change"){                   // if change clicked
        if(in_array($_POST['newfolder'],$valid_folders)){  // use valid new directory
            $folder=$_POST['newfolder'];
        }else{
            //echo "Sorry, invalid folder submitted";
            $folder=$valid_folders[0];                     // set a default directory
        }
    }
}else{
    $folder=$valid_folders[0];                             // no submission, set a default directory
}

$dir = opendir("/{$folder}");                              // set this to whatever you need it to be -- considering parent directories
//echo "Accessing: /$folder<br>";
while(false!=($file=readdir($dir))){
    if(!in_array($file,['.','..','error_log'])){           // deny dots and error_log; you should also consider preventing the deletion of THIS file as well!  Alternatively, you could skip this iterated condition and filter the $files array after the loop is finished.
            $files[] = $file; 
    }   
}

natcasesort($files);

echo "<form action=\"\" method=\"POST\">";
    echo "<select name=\"newfolder\">";
        //echo "<option value=\"\">Select a folder</option>";  // this isn't necessary if the neighboring button is descriptive
        foreach($valid_folders as $f){
            echo "<option",($folder==$f?" selected":""),">{$f}</option>";  // if a previously submitted directory, show it as selected
        }
    echo "</select> ";
    echo "<button name=\"action\" value=\"Change\">Change To Selected Folder</button>";
    echo "<br><br>";
    echo "Delete one or more files:";
    echo "<table><tr>"; 
        for($i=0,$count=sizeof($files); $i<$count; ++$i){ 
            if($i!=0 && $i%5==0){  // see the reason for this change @ 
                echo "</tr><tr>"; 
            }       
            echo "<td style=\"width:180px;\">";
                echo "<div><input name=\"files[]\" type=\"checkbox\" value=\"{$files[$i]}\">{$files[$i]}</div>";
            echo "</td>";
        }
    echo "</tr></table>";
    echo "<input type=\"hidden\" name=\"folder\" value=\"{$folder}\">";  // retain current directory
    echo "<button name=\"action\" value=\"Delete\">Delete Checked File(s)</button>";
echo "</form>";

关于表单结构,您可以实现<input type="submit"><button>来提交表单。我不会讨论这个问题的注意事项。

你看,在表单中,$folder 是一个随提交无形地传递的值。这会阻止用户在删除文件时移动到不想要的目录。

action=Delete时,则使用$folder$files进行处理。
action=Change时,仅使用newfolder进行处理。
当没有 action 时,会声明默认文件夹并列出文件。