Как я могу использовать PHP, чтобы проверить, пуст ли каталог?
Я использую следующий script для чтения каталога. Если в каталоге нет файла, он должен быть пустым. Проблема в том, что он просто говорит, что каталог пуст, хотя там есть файлы внутри и наоборот.
<?php
$pid = $_GET["prodref"];
$dir = '/assets/'.$pid.'/v';
$q = (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
if ($q=="Empty")
echo "the folder is empty";
else
echo "the folder is NOT empty";
?>
Ответы
Ответ 1
Похоже, вам нужен scandir
вместо glob, поскольку glob не может видеть скрытые Unix файлы.
<?php
$pid = basename($_GET["prodref"]); //let sanitize it a bit
$dir = "/assets/$pid/v";
if (is_dir_empty($dir)) {
echo "the folder is empty";
}else{
echo "the folder is NOT empty";
}
function is_dir_empty($dir) {
if (!is_readable($dir)) return NULL;
return (count(scandir($dir)) == 2);
}
?>
Обратите внимание, что этот код не является вершиной эффективности, так как нет необходимости читать все файлы только для того, чтобы узнать, является ли каталог пустым. Итак, лучшая версия будет
function dir_is_empty($dir) {
$handle = opendir($dir);
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
closedir($handle);
return FALSE;
}
}
closedir($handle);
return TRUE;
}
Кстати, не используйте слова для подстановки логических значений. Сама цель последнего - сказать вам, что-то пустое или нет.
a === b
выражение уже возвращает Empty
или Non Empty
в терминах языка программирования, FALSE
или TRUE
соответственно - поэтому вы можете использовать сам результат в управляющих структурах, таких как IF()
без каких-либо промежуточных значений
Ответ 2
Я думаю, что использование FilesystemIterator должно быть самым быстрым и простым способом:
// PHP 5 >= 5.3.0
$iterator = new \FilesystemIterator($dir);
$isDirEmpty = !$iterator->valid();
Или используя доступ к члену класса при создании экземпляра:
// PHP 5 >= 5.4.0
$isDirEmpty = !(new \FilesystemIterator($dir))->valid();
Это работает, потому что новый FilesystemIterator
первоначально будет указывать на первый файл в папке - если нет файлов в папке, valid()
вернет false
. (см. документацию здесь.)
Как указано abdulmanov.ilmir, дополнительно проверьте, существует ли каталог перед использованием FileSystemIterator
потому что иначе он выкинет исключение UnexpectedValueException
.
Ответ 3
Я нашел быстрое решение
<?php
$dir = 'directory'; // dir path assign here
echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
Ответ 4
использовать
if ($q == "Empty")
вместо
if ($q="Empty")
Ответ 5
Вероятно, из-за оператора присваивания в инструкции if
.
Изменить:
if ($q="Empty")
To:
if ($q=="Empty")
Ответ 6
Попробуйте следующее:
<?php
$dirPath = "Add your path here";
$destdir = $dirPath;
$handle = opendir($destdir);
$c = 0;
while ($file = readdir($handle)&& $c<3) {
$c++;
}
if ($c>2) {
print "Not empty";
} else {
print "Empty";
}
?>
Ответ 7
Это очень старая нить, но я думал, что дам десять центов. Другие решения не помогли мне.
Вот мое решение:
function is_dir_empty($dir) {
foreach (new DirectoryIterator($dir) as $fileInfo) {
if($fileInfo->isDot()) continue;
return false;
}
return true;
}
Короткий и сладкий. Работает как шарм.
Ответ 8
Для объектно-ориентированного подхода с помощью RecursiveDirectoryIterator
из Standard Библиотека PHP (SPL).
<?php
namespace My\Folder;
use RecursiveDirectoryIterator;
class FileHelper
{
/**
* @param string $dir
* @return bool
*/
public static function isEmpty($dir)
{
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
return iterator_count($di) === 0;
}
}
Не нужно делать экземпляр вашего FileHelper
всякий раз, когда вам это нужно, вы можете получить доступ к этому статическому методу везде, где вам это нужно:
FileHelper::isEmpty($dir);
Класс FileHelper
может быть расширен другими полезными методами для копирования, удаления, переименования и т.д.
Нет необходимости проверять правильность каталога внутри метода, потому что, если он недопустим, конструктор RecursiveDirectoryIterator
будет вызывать UnexpectedValueException
, который достаточно покрывает эту часть.
Ответ 9
@Ваше общее чувство
Я думаю, что ваш пример исполнителей мог бы быть более эффективным с использованием строгого сравнения:
function is_dir_empty($dir) {
if (!is_readable($dir)) return null;
$handle = opendir($dir);
while (false !== ($entry = readdir($handle))) {
if ($entry !== '.' && $entry !== '..') { // <-- better use strict comparison here
closedir($handle); // <-- always clean up! Close the directory stream
return false;
}
}
closedir($handle); // <-- always clean up! Close the directory stream
return true;
}
Ответ 10
Просто исправьте свой код следующим образом:
<?php
$pid = $_GET["prodref"];
$dir = '/assets/'.$pid.'/v';
$q = count(glob("$dir/*")) == 0;
if ($q) {
echo "the folder is empty";
} else {
echo "the folder is NOT empty";
}
?>
Ответ 11
Я использую этот метод в моем плагине Wordpress CSV 2 POST.
public function does_folder_contain_file_type( $path, $extension ){
$all_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
$html_files = new RegexIterator( $all_files, '/\.'.$extension.'/' );
foreach( $html_files as $file) {
return true;// a file with $extension was found
}
return false;// no files with our extension found
}
Он работает с определенным расширением, но легко изменяется в соответствии с вашими потребностями, удаляя "новое значение RegexIterator (" строка ". Count $all_files.
public function does_folder_contain_file_type( $path, $extension ){
$all_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
return count( $all_files );
}
Ответ 12
У меня была аналогичная проблема в последнее время, хотя самый высокий ответ на голосование действительно не работал у меня, поэтому мне пришлось придумать аналогичное решение. и снова это также не может быть самым эффективным способом решения проблемы,
Я создал такую функцию
function is_empty_dir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($dir."/".$object) == "dir")
{
return false;
} else {
return false;
}
}
}
reset($objects);
return true;
}
и использовал его для проверки пустого dricetory, подобного этому
if(is_empty_dir($path)){
rmdir($path);
}
Ответ 13
Вы можете использовать это:
function isEmptyDir($dir)
{
return (($files = @scandir($dir)) && count($files) <= 2);
}
Ответ 14
Первый вопрос: когда каталог пуст? В директории есть 2 файла. а также '..'.
Рядом с ним на Mac может быть файл ".DS_Store". Этот файл создается, когда какой-либо контент добавляется в каталог. Если эти 3 файла находятся в каталоге, вы можете сказать, что каталог пуст. Поэтому, чтобы проверить, является ли каталог пустой (без тестирования, если $ dir является каталогом):
function isDirEmpty( $dir ) {
$count = 0;
foreach (new DirectoryIterator( $dir ) as $fileInfo) {
if ( $fileInfo->isDot() || $fileInfo->getBasename() == '.DS_Store' ) {
continue;
}
$count++;
}
return ($count === 0);
}
Ответ 15
@Твой здравый смысл, @Enyby
Некоторое улучшение вашего кода:
function dir_is_empty($dir) {
$handle = opendir($dir);
$result = true;
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$result = false;
break 2;
}
}
closedir($handle);
return $result;
}
Я использую переменную для хранения результата и устанавливаю значение true.
Если каталог пуст, возвращаются только файлы. и.. (на сервере Linux вы можете расширить условие для Mac, если вам нужно), и, следовательно, условие истинно.
Затем значение result устанавливается в false, а break 2 завершает цикл if и while, поэтому следующий выполняемый оператор - closedir.
Поэтому цикл while будет иметь только 3 круга, прежде чем он закончится, независимо от того, пустой каталог или нет.