Как удалить все файлы, кроме одного, из каталога с помощью PHP?

У меня есть несколько каталогов с некоторыми файлами в них:

/test1/123.jpg
/test1/124.jpg
/test1/125.jpg
/test2/123.jpg
/test2/124.jpg

Я хочу удалить все, кроме /test1/124.jpg or /test2/124.jpg?

Я знаю имя каталога и имя файла. Есть ли способ сделать это в среде Linux с помощью php и, возможно, unlink?


person Patrioticcow    schedule 10.08.2012    source источник


Ответы (5)


8 лет назад я написал этот быстрый хак, который был принят, но, пожалуйста, примите во внимание, что

  • Он зависит от платформы: он будет работать только в unix-подобных системах, так как он зависит от unix-подобных путей и rm и mv команд оболочки для удаления и перемещения.
  • Требуется конфигурация php для запуска команд системной оболочки через shell_exec. (Что-то, что я бы не рекомендовал, если вы не знаете, что делаете)
  • Это довольно специальный ответ на предложенный вопрос, даже недостаточно причудливый, чтобы использовать foreach итерация для массива имен файлов, что позволяет получить гораздо более общее решение.
  • Он не выполняет перехват ошибок любого рода, поэтому ваш скрипт будет автоматически продолжать работу в случае сбоя (также перехват ошибок на shell_exec не тривиален, поскольку вы не получаете код выхода, как вы можете сделать с альтернативами, такими как exec или система)

Однако у него есть то преимущество, что он запускает все удаления в одной команде оболочки и не требует дополнительного поиска исключений для каждого обрабатываемого файла, что позволяет ему работать довольно быстро при высоких соотношениях удаления и сохранения, если производительность - это то, что вы ищете:

    for ($i=1;$i<=2;$i++){
        shell_exec ('mv /test'.$i.'/124.jpg /test'.$i.'/keep.jpg');
        shell_exec ('rm /test'.$i.'/12*.jpg');
        shell_exec ('mv /test'.$i.'/keep.jpg /test'.$i.'/124.jpg');
    }

В любом случае, если вы посмотрите здесь несколько других ответов, которые предлагают отменить связь основанное решение было добавлено после моего, что (как обсуждалось в комментариях ниже) является гораздо лучшим подходом, к которому я также предлагаю

  • Добавлена ​​обработка ошибок, поскольку unlink может не удалить существующий файл из-за проблем с разрешениями, когда файл используется или пользователю, выполняющему сценарий, не разрешено его изменять.

  • Всегда ini_get('max_execution_time'); чтобы проверить настройки тайм-аута выполнения скрипта (и рассмотрите возможность использования set_time_limit, чтобы при необходимости расширить его для вашего скрипта) перед запуском скрипта, обрабатывающего неосознанно длинный список файлов.

person NotGaeL    schedule 10.08.2012
comment
Грязный взлом. Вам не следует использовать этот пример, если вы можете писать только PHP-код. Только если вы понимаете, что и ПОЧЕМУ вы делаете. - person maectpo; 19.09.2012
comment
@maectpo, не могли бы вы дать мне лучший ответ? Принимаю любую конструктивную критику. - person NotGaeL; 21.09.2012
comment
@elcodedocle, в ответах ниже есть два примера. От HappyTimeGopher и от Константена-Лукаса. Они используют только PHP, поэтому вам не нужно знать, на какой платформе выполняется ваш код, а также знать, разрешена ли функция shell_exec на вашем хостинге/сервере. Его можно отключить из соображений безопасности. Опять же, если вы понимаете, ПОЧЕМУ вы делаете это, вы можете. Например, проблема с производительностью. - person maectpo; 24.09.2012
comment
@maectpo Хорошо, теперь я понимаю, что ты имеешь в виду. С этого момента я буду использовать и рекомендовать вызовы unlink и языковые вызовы, если только производительность не является проблемой. Спасибо :) - person NotGaeL; 24.09.2012

Просто отредактируйте $dir и $leave_files, чтобы отредактировать местоположения и файлы.

$dir = 'test1';
$leave_files = array('124.jpg', '123.png');

foreach( glob("$dir/*") as $file ) {
    if( !in_array(basename($file), $leave_files) ){
        unlink($file);
    }
}

Вы бы запустили это один раз для каждого каталога.

Также не забудьте сделать $dir полным путем (без косой черты в конце), если целевой каталог не находится в той же папке, что и этот скрипт.

person HappyTimeGopher    schedule 10.08.2012
comment
как это сделать для корневого каталога, обслуживающего домен? как для каталога public_html на сервере и папки проекта на локальном хосте? - person coder101; 22.06.2013
comment
@coder101 просто измените переменную $dir на путь к тому, что вы хотите. - person HappyTimeGopher; 25.06.2013

Возможно, немного грубо, но если вы работаете в системе Linux, вы можете сделать это (при условии, что вы находитесь в правильном каталоге):

<?php shell_exec('rm $(ls * | grep -v '.$fileYouWantToKeep.')'); ?>

Вам, очевидно, нужно будет отфильтровать эту переменную, если она содержит какой-либо пользовательский ввод.

person Grenville    schedule 10.08.2012

Вот еще вариант:

<?php
$dirList = array('/path/to/dir1','/path/to/dir2'); //List of Dirs with files to be deleted. No trailing slash
$saved = array('path/to/file1','path/to/file2'); //List of files to be saved, no leading slash

foreach($dirList as $directory){
$list = scandir($directory);
foreach($list as $file){
if(!is_int(array_seach($directory.'/'.$file,$saved))){ //Array search returns key if needle exists, so we check if it does not return int
unlink($file);
}
}
}

?>

У меня сейчас нет доступа к моему серверу, поэтому я не проверял его, но думаю, что он должен работать. Сначала попробуйте его в нескольких тестовых каталогах и посмотрите, работает ли он.

person Constantine Loukas    schedule 10.08.2012

вы можете переместить файлы во временную папку, затем стереть папку, создать новую папку и переместить папку с именем старой и переместить фотографии обратно, стереть папку tmp. $ прибыль $

person failuuuureee    schedule 05.01.2013