【问题标题】:Display and delete files from subfolders based on select value根据选择值显示和删除子文件夹中的文件
【发布时间】:2017-05-25 11:28:34
【问题描述】:

我的文件夹结构有 4 层,我的表单位于顶层,目前它仅显示顶层的文件,我希望能够选择一个子文件夹并显示其中的文件,以便在必要时将其删除.

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

我的表单使用复选框显示它所在文件夹的内容,然后我可以勾选框并删除文件,但我添加了一个选择并希望能够显示所选子文件夹的内容并删除文件。我做了两个提交按钮,都可以工作,但删除功能只有在顶部文件夹中才有效。

 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>

如何利用选定的值来完成此操作?

【问题讨论】:

    标签: php select delete-file subdirectory chdir


    【解决方案1】:

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

    我相信您的项目还有一些自然成熟的工作要做,包括安全性和用户体验。我将提供一个通用/简单的 sn-p 供您考虑/与您的项目进行比较,以希望在您的开发中为您提供更多牵引力。


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

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

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

    对于文件/目录的删除,将有三个必要的信息:

    • 动作 (action="delete")
    • 文件/目录 (files[]={variable})
    • 要访问的目录 (folder={variable}) * &lt;select&gt; 中的值不可信,因为用户可以在选择当前目录中的文件进行删除之前更改所选值.此值必须静态保留。
      *注意,您可以在复选框值中添加文件名的路径并消除隐藏输入 - 这将取决于编程偏好。

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

    $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'
    ];
    

    实际上,您可能希望生成一组有效/允许/现有文件夹。我可能会建议您查看此链接: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 @ https://stackoverflow.com/questions/43565075/new-containing-div-after-every-3-records/43566227#43566227
                    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>";
    

    表单结构可以实现&lt;input type="submit"&gt;&lt;button&gt;提交表单。我不会讨论这个问题的注意事项。

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

    action=Delete 时,则$folder$files 用于处理。
    action=Change 时,仅newfolder 用于处理。
    如果没有action,则声明默认文件夹并列出文件。

    【讨论】:

    • @Kilisi 请给我看你的代码的 pastebin 链接。
    • @Kilisi 我只是快速浏览了一下我的手机,但如果你要为复选框值添加路径,我会说你可以删除隐藏的输入和 chdir。如果这没有意义,请给我留言,我明天会好好看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多