recurse_dirsize()
云策文档标注
概述
recurse_dirsize() 是一个 WordPress 核心函数,用于递归计算目录及其子目录的总大小(以字节为单位)。它支持缓存机制、超时控制和排除特定路径,常用于 get_dirsize() 等函数中。
关键要点
- 函数返回目录大小(字节),无效目录返回 false,超时返回 null。
- 参数包括目录路径、排除路径、最大执行时间和目录缓存数组。
- 使用 transient 'dirsize_cache' 缓存结果以提高性能。
- 包含 pre_recurse_dirsize 过滤器,允许自定义空间计算逻辑。
- 递归遍历文件系统,处理超时以避免致命错误。
代码示例
function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) {
// 函数实现代码,包括参数处理、缓存检查、递归计算和超时控制。
}注意事项
- 目录路径应完整,且不包含尾部斜杠。
- 超时时间基于 WordPress 启动时间计算,需合理设置以避免中断。
- 缓存仅在顶层调用时写入 transient,递归调用中复用。
- 使用 untrailingslashit() 等辅助函数确保路径格式正确。
原文内容
Gets the size of a directory recursively.
Description
Used by get_dirsize() to get a directory size when it contains other directories.
Parameters
$directorystringrequired-
Full path of a directory.
$excludestring|string[]optional-
Full path of a subdirectory to exclude from the total, or array of paths. Expected without trailing slash(es).
Default:
null $max_execution_timeintoptional-
Maximum time to run before giving up. In seconds.
The timeout is global and is measured from the moment WordPress started to load. Defaults to the value ofmax_execution_timePHP setting.Default:
null $directory_cachearrayoptional-
Array of cached directory paths.
Defaults to the value ofdirsize_cachetransient.Default:
null
Source
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 ) {
// Keep the previous behavior but attempt to prevent fatal errors from timeout if possible.
if ( function_exists( 'ini_get' ) ) {
$max_execution_time = ini_get( 'max_execution_time' );
} else {
// Disable...
$max_execution_time = 0;
}
// Leave 1 second "buffer" for other operations if $max_execution_time has reasonable value.
if ( $max_execution_time > 10 ) {
$max_execution_time -= 1;
}
}
/**
* Filters the amount of storage space used by one directory and all its children, in megabytes.
*
* Return the actual used space to short-circuit the recursive PHP file size calculation
* and use something else, like a CDN API or native operating system tools for better performance.
*
* @since 5.6.0
*
* @param int|false $space_used The amount of used space, in bytes. Default false.
* @param string $directory Full path of a directory.
* @param string|string[]|null $exclude Full path of a subdirectory to exclude from the total,
* or array of paths.
* @param int $max_execution_time Maximum time to run before giving up. In seconds.
* @param array $directory_cache Array of cached directory paths.
*/
$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
) {
// Time exceeded. Give up instead of risking a fatal timeout.
$size = null;
break;
}
}
}
closedir( $handle );
}
}
if ( ! is_array( $directory_cache ) ) {
$directory_cache = array();
}
$directory_cache[ $directory ] = $size;
// Only write the transient on the top level call and not on recursive calls.
if ( $save_cache ) {
$expiration = ( wp_using_ext_object_cache() ) ? 0 : 10 * YEAR_IN_SECONDS;
set_transient( 'dirsize_cache', $directory_cache, $expiration );
}
return $size;
}
Hooks
- apply_filters( ‘pre_recurse_dirsize’, int|false $space_used, string $directory, string|string[]|null $exclude, int $max_execution_time, array $directory_cache )
-
Filters the amount of storage space used by one directory and all its children, in megabytes.
Changelog
| Version | Description |
|---|---|
| MU (3.0.0) | MU (3.0.0) |
| 5.6.0 | The $directory_cache parameter was added. |
| 5.2.0 | The $max_execution_time parameter was added. |
| 4.3.0 | Introduced. |