Closedir: примеры (PHP)

Функция closedir в PHP: закрытие дескриптора директории
Раздел: Работа с файловой системой
closedir(?resource $dir_handle = null): void

Описание функции closedir

Функция closedir закрывает дескриптор каталога, который был ранее открыт с помощью opendir. Освобождение ресурсов происходит после завершения работы с содержимым директории.

Аргументы функции

Функция принимает один необязательный аргумент:

  • $dir_handle (ресурс) – Дескриптор директории, возвращенный opendir. Если аргумент не указан, функция закроет последний открытый дескриптор.
Возвращаемое значение

Функция не возвращает значения. В PHP 8.0 и выше при передаче нересурсного аргумента генерируется TypeError.

Примеры использования

Базовый пример с указанием дескриптора
<?php
$dir = opendir('.');
if ($dir) {
    while (($file = readdir($dir)) !== false) {
        echo $file . "\n";
    }
    closedir($dir); // Явное закрытие
}
?>
index.php
style.css
vendor
Использование без аргумента
<?php
$dir1 = opendir('.');
$dir2 = opendir('./vendor');
closedir(); // Закрывается $dir2
?>
// Ресурс $dir2 освобожден

Альтернативные функции в PHP

Конструкция dir()

Класс Directory автоматически закрывает дескриптор при уничтожении объекта или вызове метода close().

$d = dir('.');
while (false !== ($entry = $d->read())) {
    echo $entry;
}
$d->close(); // Аналогично closedir
Итераторы директорий

Классы DirectoryIterator и FilesystemIterator управляют ресурсами автоматически, не требуя ручного закрытия.

foreach (new DirectoryIterator('.') as $file) {
    echo $file->getFilename();
} // Закрытие происходит автоматически

Типичные ошибки

Передача нересурсного аргумента
<?php
closedir('string'); // TypeError в PHP 8.0+
?>
TypeError: closedir(): Argument #1 must be a valid directory resource
Попытка повторного закрытия
<?php
$dir = opendir('.');
closedir($dir);
closedir($dir); // Дескриптор уже недействителен
?>
Warning: closedir(): supplied resource is not a valid Directory resource
Использование после закрытия
<?php
$dir = opendir('.');
closedir($dir);
readdir($dir); // Ошибка чтения
?>
Warning: readdir(): supplied resource is not a valid Directory resource

Изменения в версиях PHP

PHP 8.0.0

Функция теперь генерирует исключение TypeError при передаче аргумента, который не является ресурсом. Ранее выдавалось предупреждение.

Историческое изменение (PHP 5.0)

Аргумент $dir_handle стал необязательным. В ранних версиях требовалось всегда передавать дескриптор.

Расширенные примеры

Закрытие в блоке try-finally
Пример php
<?php
$dir = opendir('/tmp');
try {
    while (($file = readdir($dir)) !== false) {
        if ($file === 'important.lock') {
            throw new Exception('Lock file found');
        }
    }
} finally {
    closedir($dir); // Гарантированное закрытие
}
?>
Работа с несколькими дескрипторами
Пример php
<?php
$handles = [];
$paths = ['.', './vendor', '/tmp'];
foreach ($paths as $path) {
    if ($h = opendir($path)) {
        $handles[] = $h;
    }
}
// Обработка...
foreach ($handles as $handle) {
    closedir($handle); // Закрытие всех
}
?>
Автоматическое закрытие в пользовательской функции
Пример php
<?php
function scanDirectory($path, callable $processor) {
    if (!$dir = @opendir($path)) {
        return false;
    }
    
    while (($item = readdir($dir)) !== false) {
        $processor($item);
    }
    
    closedir($dir);
    return true;
}
scanDirectory('.', function($file) {
    echo $file . PHP_EOL;
});
?>
Имитация деструктора
Пример php
<?php
class DirectoryScanner {
    private $handle;
    public function __construct($path) {
        $this->handle = opendir($path);
    }
    public function __destruct() {
        if (is_resource($this->handle)) {
            closedir($this->handle);
        }
    }
    public function read() {
        return readdir($this->handle);
    }
}
$scanner = new DirectoryScanner('.');
// При уничтожении объекта дескриптор закроется
unset($scanner);
?>

Аналоги в других языках

Python

Метод close() объекта, возвращенного os.scandir(). Контекстный менеджер гарантирует закрытие.

import os
dir_iter = os.scandir('.')
for entry in dir_iter:
    print(entry.name)
dir_iter.close()
JavaScript (Node.js)

Метод dir.close() для ресурса из fs.opendirSync(). Асинхронные методы часто не требуют явного закрытия.

const fs = require('fs');
const dir = fs.opendirSync('.');
let entry;
while ((entry = dir.readSync()) !== null) {
    console.log(entry.name);
}
dir.closeSync();
MySQL

Используется инструкция SELECT ... INTO OUTFILE для вывода списка файлов через системные команды, управление ресурсами не требуется.

PHP closedir function comments

En
Closedir Close directory handle