Функция recurse_dirsize() для вычисления размера директории

RECURSE_DIRSIZE() │ WP 3.0.0

Функция recurse_dirsize() вычисляет размер директории, включая все вложенные поддиректории.

Зачем нужна эта функция?

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

Как работает функция?

Возвращаемые значения

Функция может вернуть:

  • Целое число или false или null.
    • Целое число: размер директории в байта��, если директория существует и доступна.
    • false: если директория не найдена или недоступна.
    • null: если истекло время выполнения.

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

Функция вызывается следующим образом:

recurse_dirsize( $directory, $exclude, $max_execution_time, $directory_cache );

Параметры функции:

  • $directory (строка, обязательный): полный путь к директории.
  • $exclude (строка|массив): полный путь к поддиректории, которую следует исключить из подсчета, или массив путей. Должен быть без завершающих слэшей.
    • По умолчанию: null
  • $max_execution_time (целое число): максимальное время выполнения в секундах. Время считается с момента загрузки WordPress.
    • По умолчанию: значение настройки max_execution_time PHP.
  • $directory_cache (массив, передается по ссылке): массив кэшированных путей к директориям.
    • По умолчанию: значение, которое запоминается в трансайте dirsize_cache.

Пример кода для получения размера директории uploads

$upload_dir = (object) wp_upload_dir();

// подключаем файл с функциями
require_once ABSPATH . WPINC .'/ms-functions.php';

$mb = recurse_dirsize( $upload_dir->basedir );

echo number_format( $mb / (1024*1024), 1 ) .' MB'; // вывод: 74.5 MB

Изменения в функции

История изменений:

  • С 3.0.0: функция была введена.
  • С 4.3.0: добавлен параметр $exclude.
  • С 5.2.0: добавлен параметр $max_execution_time.
  • С 5.6.0: добавлен параметр $directory_cache.

Код функции recurse_dirsize

Вот как выглядит код функции:


function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) {
$directory = untrailingslashit( $directory );
$save_cache = false;

if ( ! isset( $directory_cache ) ) {
    $directory_cache = get_transient( 'dirsize_cache' );
    $save_cache      = true;
}

if ( isset( $directory_cache[ $directory ] ) && is_int( $directory_cache[ $directory ] ) ) {
    return $directory_cache[ $directory ];
}

if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) {
    return false;
}

if (
    (is_string($exclude) && $directory === $exclude) ||
    (is_array($exclude) && in_array($directory, $exclude, true))
) {
    return false;
}

if (null === $max_execution_time) {
    if (function_exists('ini_get')) {
        $max_execution_time = ini_get('max_execution_time');
    } else {
        $max_execution_time = 0;
    }

    if ($max_execution_time > 10) {
        $max_execution_time -= 1;
    }
}

$size = apply_filters('pre_recurse_dirsize', false, $directory, $exclude, $max_execution_time, $directory_cache);

if (false === $size) {
    $size = 0;

    $handle = opendir($directory);
    if ($handle) {
        while (($file = readdir($handle)) !== false) {
            $path = $directory . '/' . $file;
            if ('.' !== $file && '..' !== $file) {
                if (is_file($path)) {
                    $size += filesize($path);
                } elseif (is_dir($path)) {
                    $handlesize = recurse_dirsize($path, $exclude, $max_execution_time, $directory_cache);
                    if ($handlesize > 0) {
                        $size += $handlesize;
                    }
                }

                if ($max_execution_time > 0 && (microtime(true) - WP_START_TIMESTAMP) > $max_execution_time) {
                    $size = null;
                    break;
                }
            }
        }
        closedir($handle);
    }
}

if (!is_array($directory_cache)) {
    $directory_cache = array();
}

$directory_cache[$directory] = $size;

if ($save_cache) {
    $expiration = (wp_using_ext_object_cache()) ? 0 : 10 * YEAR_IN_SECONDS;
    set_transient('dirsize_cache', $directory_cache, $expiration);
}

return $size;

}

Заметки по коду

  • Функция начинает с получения и проверки входных данных.
  • Затем подсчитывает размер всех файлов в директории и её поддиректориях.
  • Возможные ошибки времени выполнения обрабатываются, чтобы избежать фатальных ошибок.
  • Используется кэш для ускорения повторных запросов к одной и той же директории.

Надеюсь, эта статья была полезна! Если у вас есть вопросы, не стесняйтесь спрашивать.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *