Моя структура папок имеет 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,.
Моя форма отображает содержимое папки с установленными флажками, затем я могу поставить галочки и удалить файлы, но я добавил элемент 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>
Как я могу использовать выбранное значение для достижения этой цели?
Во-первых, я хотел бы рассказать, почему вы не можете удалить файлы за пределами верхней папки. Вы никогда не меняете «текущий рабочий каталог», поэтому вызов функций удаления для глубоких файлов никогда не будет работать должным образом и может удалить файлы в верхней папке. Чтобы исправить это, вам нужно будет либо указать путь к каждому файлу / каталогу, который нужно удалить, либо вызвать chdir()
однажды так, чтобы unlink()
а также rmdir()
смотрите в нужном месте.
Я считаю, что у вашего проекта все еще есть естественное развитие, включая безопасность и UX. Я предоставлю вам обобщенный / простой фрагмент, чтобы вы могли сравнить его с вашим проектом и, надеюсь, дать вам немного больше тяги в вашей разработке.
Ваши пользователи смогут сделать один из двух вариантов при отправке: Изменить каталог & Удалить файлы / каталоги
Для смены каталога вашей программе необходимо предоставить две необходимые части информации:
Для удаления файла / каталога будет три необходимых элемента информации:
<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'
];
В действительности вы, вероятно, захотите сгенерировать массив допустимых / разрешенных / существующих папок. Я мог бы рекомендовать вам взглянуть на эту ссылку: Перечислите все файлы и папки в каталоге с рекурсивной функцией PHP
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>";
Что касается структуры формы, вы можете реализовать <input type="submit">
или же <button>
отправить форму. Я не буду обсуждать предостережения по этому вопросу.
Вы видите, в форме, $folder
это значение, которое незаметно передается с представлением. Это мешает пользователю перемещаться в непредусмотренный каталог при удалении файлов.
когда action=Delete
затем $folder
а также $files
используются для обработки.
когда action=Change
только newfolder
используется для обработки.
Когда нет action
папка по умолчанию объявлена, и файлы будут перечислены.
Других решений пока нет …