如何在PHP中获取目录大小

时间:2022-10-27 11:04:34
function foldersize($path) {
  $total_size = 0;
  $files = scandir($path);

  foreach($files as $t) {
    if (is_dir(rtrim($path, '/') . '/' . $t)) {
      if ($t<>"." && $t<>"..") {
          $size = foldersize(rtrim($path, '/') . '/' . $t);

          $total_size += $size;
      }
    } else {
      $size = filesize(rtrim($path, '/') . '/' . $t);
      $total_size += $size;
    }
  }
  return $total_size;
}

function format_size($size) {
  $mod = 1024;
  $units = explode(' ','B KB MB GB TB PB');
  for ($i = 0; $size > $mod; $i++) {
    $size /= $mod;
  }

  return round($size, 2) . ' ' . $units[$i];
}

$SIZE_LIMIT = 5368709120; // 5 GB

$sql="select * from users order by id";
$result=mysql_query($sql);

while($row=mysql_fetch_array($result)) {
  $disk_used = foldersize("C:/xampp/htdocs/freehosting/".$row['name']);

  $disk_remaining = $SIZE_LIMIT - $disk_used;
  print 'Name: ' . $row['name'] . '<br>';

  print 'diskspace used: ' . format_size($disk_used) . '<br>';
  print 'diskspace left: ' . format_size($disk_remaining) . '<br><hr>';
}

php disk_total_space

php作用

Any idea why the processor usage shoot up too high or 100% till the script execution is finish ? Can anything be done to optimize it? or is there any other alternative way to check folder and folders inside it size?

您知道为什么处理器的使用率会猛增到100%,直到脚本执行完成吗?能做些什么来优化它吗?或者有没有其他方法可以检查文件夹和文件夹的大小?

16 个解决方案

#1


34  

The following are other solutions offered elsewhere:

以下是其他地方提供的解决办法:

If on a Windows Host:

如果在Windows主机上:

<?
    $f = 'f:/www/docs';
    $obj = new COM ( 'scripting.filesystemobject' );
    if ( is_object ( $obj ) )
    {
        $ref = $obj->getfolder ( $f );
        echo 'Directory: ' . $f . ' => Size: ' . $ref->size;
        $obj = null;
    }
    else
    {
        echo 'can not create object';
    }
?>

Else, if on a Linux Host:

否则,如果在Linux主机上:

<?
    $f = './path/directory';
    $io = popen ( '/usr/bin/du -sk ' . $f, 'r' );
    $size = fgets ( $io, 4096);
    $size = substr ( $size, 0, strpos ( $size, "\t" ) );
    pclose ( $io );
    echo 'Directory: ' . $f . ' => Size: ' . $size;
?>

#2


47  

function GetDirectorySize($path){
    $bytestotal = 0;
    $path = realpath($path);
    if($path!==false && $path!='' && file_exists($path)){
        foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object){
            $bytestotal += $object->getSize();
        }
    }
    return $bytestotal;
}

The same idea as Janith Chinthana suggested. With a few fixes:

这和詹妮斯·钦萨纳的想法是一样的。有几个补丁:

  • Converts $path to realpath
  • 转换成美元realpath之路
  • Performs iteration only if path is valid and folder exists
  • 只有路径有效且文件夹存在时才执行迭代。
  • Skips . and .. files
  • 跳过。和. .文件
  • Optimized for performance
  • 优化了性能

#3


27  

A pure php example.

一个纯php示例。

<?php
    $units = explode(' ', 'B KB MB GB TB PB');
    $SIZE_LIMIT = 5368709120; // 5 GB
    $disk_used = foldersize("/webData/users/vdbuilder@yahoo.com");

    $disk_remaining = $SIZE_LIMIT - $disk_used;

    echo("<html><body>");
    echo('diskspace used: ' . format_size($disk_used) . '<br>');
    echo( 'diskspace left: ' . format_size($disk_remaining) . '<br><hr>');
    echo("</body></html>");


function foldersize($path) {
    $total_size = 0;
    $files = scandir($path);
    $cleanPath = rtrim($path, '/'). '/';

    foreach($files as $t) {
        if ($t<>"." && $t<>"..") {
            $currentFile = $cleanPath . $t;
            if (is_dir($currentFile)) {
                $size = foldersize($currentFile);
                $total_size += $size;
            }
            else {
                $size = filesize($currentFile);
                $total_size += $size;
            }
        }   
    }

    return $total_size;
}


function format_size($size) {
    global $units;

    $mod = 1024;

    for ($i = 0; $size > $mod; $i++) {
        $size /= $mod;
    }

    $endIndex = strpos($size, ".")+3;

    return substr( $size, 0, $endIndex).' '.$units[$i];
}

?>

#4


24  

directory size using php filesize and RecursiveIteratorIterator.

目录大小使用php filesize和recursiveiterator。

This works with any platform which is having php 5 or higher version.

这适用于任何拥有php 5或更高版本的平台。

**
 * Get the directory size
 * @param directory $directory
 * @return integer
 */
function dirSize($directory) {
    $size = 0;
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file){
        $size+=$file->getSize();
    }
    return $size;
} 

#5


12  

function get_dir_size($directory){
    $size = 0;
    $files= glob($directory.'/*');
    foreach($files as $path){
        is_file($path) && $size += filesize($path);
        is_dir($path) && get_dir_size($path);
    }
    return $size;
} 

#6


8  

Thanks to Jonathan Sampson, Adam Pierce and Janith Chinthana I did this one checking for most performant way to get the directory size. Should work on Windows and Linux Hosts.

感谢乔纳森·桑普森、亚当·皮尔斯和詹妮斯·钦萨纳,我做了这个检查,以获得最高效的目录大小。应该在Windows和Linux主机上工作。

static function getTotalSize($dir)
{
    $dir = rtrim(str_replace('\\', '/', $dir), '/');

    if (is_dir($dir) === true) {
        $totalSize = 0;
        $os        = strtoupper(substr(PHP_OS, 0, 3));
        // If on a Unix Host (Linux, Mac OS)
        if ($os !== 'WIN') {
            $io = popen('/usr/bin/du -sb ' . $dir, 'r');
            if ($io !== false) {
                $totalSize = intval(fgets($io, 80));
                pclose($io);
                return $totalSize;
            }
        }
        // If on a Windows Host (WIN32, WINNT, Windows)
        if ($os === 'WIN' && extension_loaded('com_dotnet')) {
            $obj = new \COM('scripting.filesystemobject');
            if (is_object($obj)) {
                $ref       = $obj->getfolder($dir);
                $totalSize = $ref->size;
                $obj       = null;
                return $totalSize;
            }
        }
        // If System calls did't work, use slower PHP 5
        $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
        foreach ($files as $file) {
            $totalSize += $file->getSize();
        }
        return $totalSize;
    } else if (is_file($dir) === true) {
        return filesize($dir);
    }
}

#7


6  

Johnathan Sampson's Linux example didn't work so good for me. Here's an improved version:

乔纳森·桑普森(Johnathan Sampson)的Linux示例对我不太适用。这是一个改进的版本:

function getDirSize($path)
{
    $io = popen('/usr/bin/du -sb '.$path, 'r');
    $size = intval(fgets($io,80));
    pclose($io);
    return $size;
}

#8


6  

I found this approach to be shorter and more compatible. The Mac OS X version of "du" doesn't support the -b (or --bytes) option for some reason, so this sticks to the more-compatible -k option.

我发现这种方法更短、更兼容。由于某些原因,Mac OS X版本的“du”不支持-b(或-bytes)选项,因此它坚持使用更加兼容的-k选项。

$file_directory = './directory/path';
$output = exec('du -sk ' . $file_directory);
$filesize = trim(str_replace($file_directory, '', $output)) * 1024;

Returns the $filesize in bytes.

返回以字节为单位的$filesize。

#9


5  

Even though there are already many many answers to this post, I feel I have to add another option for unix hosts that only returns the sum of all file sizes in the directory (recursively).

尽管这篇文章已经有很多答案,但我觉得我必须为unix主机添加另一个选项,它只返回目录中所有文件大小的总和(递归地)。

If you look at Jonathan's answer he uses the du command. This command will return the total directory size but the pure PHP solutions posted by others here will return the sum of all file sizes. Big difference!

如果你看看乔纳森的回答,他会使用du命令。这个命令将返回总目录大小,但是这里的其他人发布的纯PHP解决方案将返回所有文件大小的总和。大的区别!

What to look out for

When running du on a newly created directory, it may return 4K instead of 0. This may even get more confusing after having deleted files from the directory in question, having du reporting a total directory size that does not correspond to the sum of the sizes of the files within it. Why? The command du returns a report based on some file settings, as Hermann Ingjaldsson commented on this post.

在新创建的目录上运行du时,它可能返回4K而不是0。在从相关目录中删除文件之后,这可能会更令人困惑,因为du报告的目录总大小与其中文件大小的总和不一致。为什么?命令du返回一个基于一些文件设置的报告,正如Hermann Ingjaldsson在这篇文章中评论的那样。

The solution

To form a solution that behaves like some of the PHP-only scripts posted here, you can use ls command and pipe it to awk like this:

要形成一种解决方案,该解决方案的行为类似于本文中发布的一些php脚本,您可以使用ls命令并将其传输到awk,如下所示:

ls -ltrR /path/to/dir |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'

As a PHP function you could use something like this:

作为一个PHP函数,您可以使用如下内容:

function getDirectorySize( $path )
{
    if( !is_dir( $path ) ) {
        return 0;
    }

    $path   = strval( $path );
    $io     = popen( "ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r' );
    $size   = intval( fgets( $io, 80 ) );
    pclose( $io );

    return $size;
}

#10


2  

There are several things you could do to optimise the script - but maximum success would make it IO-bound rather than CPU-bound:

您可以做一些事情来优化脚本—但是最大的成功将使它与io绑定,而不是与cpu绑定:

  1. Calculate rtrim($path, '/') outside the loop.
  2. 计算循环外的rtrim($path, '/')。
  3. make if ($t<>"." && $t<>"..") the outer test - it doesn't need to stat the path
  4. 如果($ t < >”。”&& $t<>"..)外部测试-它不需要统计路径
  5. Calculate rtrim($path, '/') . '/' . $t once per loop - inside 2) and taking 1) into account.
  6. 计算空白($路径“/”)。“/”。每循环t元一次,在2内,并考虑1)。
  7. Calculate explode(' ','B KB MB GB TB PB'); once rather than each call?
  8. 计算爆炸(' ','B KB MB GB TB ');一次而不是每次通话?

#11


2  

PHP get directory size (with FTP access)

After hard work, this code works great!!!! and I want to share with the community (by MundialSYS)

经过艰苦的工作,这个代码工作得很好!!!我想和大家分享

function dirFTPSize($ftpStream, $dir) {
    $size = 0;
    $files = ftp_nlist($ftpStream, $dir);

    foreach ($files as $remoteFile) {
        if(preg_match('/.*\/\.\.$/', $remoteFile) || preg_match('/.*\/\.$/', $remoteFile)){
            continue;
        }
        $sizeTemp = ftp_size($ftpStream, $remoteFile);
        if ($sizeTemp > 0) {
            $size += $sizeTemp;
        }elseif($sizeTemp == -1){//directorio
            $size += dirFTPSize($ftpStream, $remoteFile);
        }
    }

    return $size;
}

$hostname = '127.0.0.1'; // or 'ftp.domain.com'
$username = 'username';
$password = 'password';
$startdir = '/public_html'; // absolute path
$files = array();
$ftpStream = ftp_connect($hostname);
$login = ftp_login($ftpStream, $username, $password);
if (!$ftpStream) {
    echo 'Wrong server!';
    exit;
} else if (!$login) {
    echo 'Wrong username/password!';
    exit;
} else {
    $size = dirFTPSize($ftpStream, $startdir);
}

echo number_format(($size / 1024 / 1024), 2, '.', '') . ' MB';

ftp_close($ftpStream);

Good code! Fernando

好的代码!费尔南多

#12


1  

Regarding Johnathan Sampson's Linux example, watch out when you are doing an intval on the outcome of the "du" function, if the size is >2GB, it will keep showing 2GB.

对于Johnathan Sampson的Linux示例,当您对“du”函数的结果进行intval时,请注意,如果大小是>2GB,它将继续显示2GB。

Replace:

替换:

$totalSize = intval(fgets($io, 80));

by:

由:

strtok(fgets($io, 80), " ");

supposed your "du" function returns the size separated with space followed by the directory/file name.

假定您的“du”函数返回与空间分隔的大小,后跟目录/文件名。

#13


1  

Object Oriented Approach :

面向对象的方法:

/**
 * Returns a directory size
 *
 * @param string $directory
 *
 * @return int $size directory size in bytes
 *
 */
function dir_size($directory)
{
    $size = 0;
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file)
    {
        $size += $file->getSize();
    }
    return $size;
}

Fast and Furious Approach :

《速度与激情》:

function dir_size2($dir)
{
    $line = exec('du -sh ' . $dir);
    $line = trim(str_replace($dir, '', $line));
    return $line;
}

#14


1  

Just another function using native php functions.

使用本机php函数的另一个函数。

function dirSize($dir)
    {
        $dirSize = 0;
        if(!is_dir($dir)){return false;};
        $files = scandir($dir);if(!$files){return false;}
        $files = array_diff($files, array('.','..'));

        foreach ($files as $file) {
            if(is_dir("$dir/$file")){
                 $dirSize += dirSize("$dir/$file");
            }else{
                $dirSize += filesize("$dir/$file");
            }
        }
        return $dirSize;
    }

NOTE: this function returns the files sizes, NOT the size on disk

注意:这个函数返回文件大小,而不是磁盘上的大小。

#15


0  

Evolved from Nate Haugs answer I created a short function for my project:

从Nate Haugs answer衍生而来,我为我的项目创建了一个简短的功能:

function uf_getDirSize($dir, $unit = 'm')
{
    $dir = trim($dir, '/');
    if (!is_dir($dir)) {
        trigger_error("{$dir} not a folder/dir/path.", E_USER_WARNING);
        return false;
    }
    if (!function_exists('exec')) {
        trigger_error('The function exec() is not available.', E_USER_WARNING);
        return false;
    }
    $output = exec('du -sb ' . $dir);
    $filesize = (int) trim(str_replace($dir, '', $output));
    switch ($unit) {
        case 'g': $filesize = number_format($filesize / 1073741824, 3); break;  // giga
        case 'm': $filesize = number_format($filesize / 1048576, 1);    break;  // mega
        case 'k': $filesize = number_format($filesize / 1024, 0);       break;  // kilo
        case 'b': $filesize = number_format($filesize, 0);              break;  // byte
    }
    return ($filesize + 0);
}

#16


0  

A one-liner solution. Result in bytes.

一行程序的解决方案。导致字节。

$size=array_sum(array_map('filesize', glob("{$dir}/*.*")));

Added bonus: you can simply change the file mask to whatever you like, and count only certain files (eg by extension).

附加好处:您可以简单地将文件掩码更改为您喜欢的任何文件,并且只计算某些文件(如扩展名)。

#1


34  

The following are other solutions offered elsewhere:

以下是其他地方提供的解决办法:

If on a Windows Host:

如果在Windows主机上:

<?
    $f = 'f:/www/docs';
    $obj = new COM ( 'scripting.filesystemobject' );
    if ( is_object ( $obj ) )
    {
        $ref = $obj->getfolder ( $f );
        echo 'Directory: ' . $f . ' => Size: ' . $ref->size;
        $obj = null;
    }
    else
    {
        echo 'can not create object';
    }
?>

Else, if on a Linux Host:

否则,如果在Linux主机上:

<?
    $f = './path/directory';
    $io = popen ( '/usr/bin/du -sk ' . $f, 'r' );
    $size = fgets ( $io, 4096);
    $size = substr ( $size, 0, strpos ( $size, "\t" ) );
    pclose ( $io );
    echo 'Directory: ' . $f . ' => Size: ' . $size;
?>

#2


47  

function GetDirectorySize($path){
    $bytestotal = 0;
    $path = realpath($path);
    if($path!==false && $path!='' && file_exists($path)){
        foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object){
            $bytestotal += $object->getSize();
        }
    }
    return $bytestotal;
}

The same idea as Janith Chinthana suggested. With a few fixes:

这和詹妮斯·钦萨纳的想法是一样的。有几个补丁:

  • Converts $path to realpath
  • 转换成美元realpath之路
  • Performs iteration only if path is valid and folder exists
  • 只有路径有效且文件夹存在时才执行迭代。
  • Skips . and .. files
  • 跳过。和. .文件
  • Optimized for performance
  • 优化了性能

#3


27  

A pure php example.

一个纯php示例。

<?php
    $units = explode(' ', 'B KB MB GB TB PB');
    $SIZE_LIMIT = 5368709120; // 5 GB
    $disk_used = foldersize("/webData/users/vdbuilder@yahoo.com");

    $disk_remaining = $SIZE_LIMIT - $disk_used;

    echo("<html><body>");
    echo('diskspace used: ' . format_size($disk_used) . '<br>');
    echo( 'diskspace left: ' . format_size($disk_remaining) . '<br><hr>');
    echo("</body></html>");


function foldersize($path) {
    $total_size = 0;
    $files = scandir($path);
    $cleanPath = rtrim($path, '/'). '/';

    foreach($files as $t) {
        if ($t<>"." && $t<>"..") {
            $currentFile = $cleanPath . $t;
            if (is_dir($currentFile)) {
                $size = foldersize($currentFile);
                $total_size += $size;
            }
            else {
                $size = filesize($currentFile);
                $total_size += $size;
            }
        }   
    }

    return $total_size;
}


function format_size($size) {
    global $units;

    $mod = 1024;

    for ($i = 0; $size > $mod; $i++) {
        $size /= $mod;
    }

    $endIndex = strpos($size, ".")+3;

    return substr( $size, 0, $endIndex).' '.$units[$i];
}

?>

#4


24  

directory size using php filesize and RecursiveIteratorIterator.

目录大小使用php filesize和recursiveiterator。

This works with any platform which is having php 5 or higher version.

这适用于任何拥有php 5或更高版本的平台。

**
 * Get the directory size
 * @param directory $directory
 * @return integer
 */
function dirSize($directory) {
    $size = 0;
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file){
        $size+=$file->getSize();
    }
    return $size;
} 

#5


12  

function get_dir_size($directory){
    $size = 0;
    $files= glob($directory.'/*');
    foreach($files as $path){
        is_file($path) && $size += filesize($path);
        is_dir($path) && get_dir_size($path);
    }
    return $size;
} 

#6


8  

Thanks to Jonathan Sampson, Adam Pierce and Janith Chinthana I did this one checking for most performant way to get the directory size. Should work on Windows and Linux Hosts.

感谢乔纳森·桑普森、亚当·皮尔斯和詹妮斯·钦萨纳,我做了这个检查,以获得最高效的目录大小。应该在Windows和Linux主机上工作。

static function getTotalSize($dir)
{
    $dir = rtrim(str_replace('\\', '/', $dir), '/');

    if (is_dir($dir) === true) {
        $totalSize = 0;
        $os        = strtoupper(substr(PHP_OS, 0, 3));
        // If on a Unix Host (Linux, Mac OS)
        if ($os !== 'WIN') {
            $io = popen('/usr/bin/du -sb ' . $dir, 'r');
            if ($io !== false) {
                $totalSize = intval(fgets($io, 80));
                pclose($io);
                return $totalSize;
            }
        }
        // If on a Windows Host (WIN32, WINNT, Windows)
        if ($os === 'WIN' && extension_loaded('com_dotnet')) {
            $obj = new \COM('scripting.filesystemobject');
            if (is_object($obj)) {
                $ref       = $obj->getfolder($dir);
                $totalSize = $ref->size;
                $obj       = null;
                return $totalSize;
            }
        }
        // If System calls did't work, use slower PHP 5
        $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
        foreach ($files as $file) {
            $totalSize += $file->getSize();
        }
        return $totalSize;
    } else if (is_file($dir) === true) {
        return filesize($dir);
    }
}

#7


6  

Johnathan Sampson's Linux example didn't work so good for me. Here's an improved version:

乔纳森·桑普森(Johnathan Sampson)的Linux示例对我不太适用。这是一个改进的版本:

function getDirSize($path)
{
    $io = popen('/usr/bin/du -sb '.$path, 'r');
    $size = intval(fgets($io,80));
    pclose($io);
    return $size;
}

#8


6  

I found this approach to be shorter and more compatible. The Mac OS X version of "du" doesn't support the -b (or --bytes) option for some reason, so this sticks to the more-compatible -k option.

我发现这种方法更短、更兼容。由于某些原因,Mac OS X版本的“du”不支持-b(或-bytes)选项,因此它坚持使用更加兼容的-k选项。

$file_directory = './directory/path';
$output = exec('du -sk ' . $file_directory);
$filesize = trim(str_replace($file_directory, '', $output)) * 1024;

Returns the $filesize in bytes.

返回以字节为单位的$filesize。

#9


5  

Even though there are already many many answers to this post, I feel I have to add another option for unix hosts that only returns the sum of all file sizes in the directory (recursively).

尽管这篇文章已经有很多答案,但我觉得我必须为unix主机添加另一个选项,它只返回目录中所有文件大小的总和(递归地)。

If you look at Jonathan's answer he uses the du command. This command will return the total directory size but the pure PHP solutions posted by others here will return the sum of all file sizes. Big difference!

如果你看看乔纳森的回答,他会使用du命令。这个命令将返回总目录大小,但是这里的其他人发布的纯PHP解决方案将返回所有文件大小的总和。大的区别!

What to look out for

When running du on a newly created directory, it may return 4K instead of 0. This may even get more confusing after having deleted files from the directory in question, having du reporting a total directory size that does not correspond to the sum of the sizes of the files within it. Why? The command du returns a report based on some file settings, as Hermann Ingjaldsson commented on this post.

在新创建的目录上运行du时,它可能返回4K而不是0。在从相关目录中删除文件之后,这可能会更令人困惑,因为du报告的目录总大小与其中文件大小的总和不一致。为什么?命令du返回一个基于一些文件设置的报告,正如Hermann Ingjaldsson在这篇文章中评论的那样。

The solution

To form a solution that behaves like some of the PHP-only scripts posted here, you can use ls command and pipe it to awk like this:

要形成一种解决方案,该解决方案的行为类似于本文中发布的一些php脚本,您可以使用ls命令并将其传输到awk,如下所示:

ls -ltrR /path/to/dir |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'

As a PHP function you could use something like this:

作为一个PHP函数,您可以使用如下内容:

function getDirectorySize( $path )
{
    if( !is_dir( $path ) ) {
        return 0;
    }

    $path   = strval( $path );
    $io     = popen( "ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r' );
    $size   = intval( fgets( $io, 80 ) );
    pclose( $io );

    return $size;
}

#10


2  

There are several things you could do to optimise the script - but maximum success would make it IO-bound rather than CPU-bound:

您可以做一些事情来优化脚本—但是最大的成功将使它与io绑定,而不是与cpu绑定:

  1. Calculate rtrim($path, '/') outside the loop.
  2. 计算循环外的rtrim($path, '/')。
  3. make if ($t<>"." && $t<>"..") the outer test - it doesn't need to stat the path
  4. 如果($ t < >”。”&& $t<>"..)外部测试-它不需要统计路径
  5. Calculate rtrim($path, '/') . '/' . $t once per loop - inside 2) and taking 1) into account.
  6. 计算空白($路径“/”)。“/”。每循环t元一次,在2内,并考虑1)。
  7. Calculate explode(' ','B KB MB GB TB PB'); once rather than each call?
  8. 计算爆炸(' ','B KB MB GB TB ');一次而不是每次通话?

#11


2  

PHP get directory size (with FTP access)

After hard work, this code works great!!!! and I want to share with the community (by MundialSYS)

经过艰苦的工作,这个代码工作得很好!!!我想和大家分享

function dirFTPSize($ftpStream, $dir) {
    $size = 0;
    $files = ftp_nlist($ftpStream, $dir);

    foreach ($files as $remoteFile) {
        if(preg_match('/.*\/\.\.$/', $remoteFile) || preg_match('/.*\/\.$/', $remoteFile)){
            continue;
        }
        $sizeTemp = ftp_size($ftpStream, $remoteFile);
        if ($sizeTemp > 0) {
            $size += $sizeTemp;
        }elseif($sizeTemp == -1){//directorio
            $size += dirFTPSize($ftpStream, $remoteFile);
        }
    }

    return $size;
}

$hostname = '127.0.0.1'; // or 'ftp.domain.com'
$username = 'username';
$password = 'password';
$startdir = '/public_html'; // absolute path
$files = array();
$ftpStream = ftp_connect($hostname);
$login = ftp_login($ftpStream, $username, $password);
if (!$ftpStream) {
    echo 'Wrong server!';
    exit;
} else if (!$login) {
    echo 'Wrong username/password!';
    exit;
} else {
    $size = dirFTPSize($ftpStream, $startdir);
}

echo number_format(($size / 1024 / 1024), 2, '.', '') . ' MB';

ftp_close($ftpStream);

Good code! Fernando

好的代码!费尔南多

#12


1  

Regarding Johnathan Sampson's Linux example, watch out when you are doing an intval on the outcome of the "du" function, if the size is >2GB, it will keep showing 2GB.

对于Johnathan Sampson的Linux示例,当您对“du”函数的结果进行intval时,请注意,如果大小是>2GB,它将继续显示2GB。

Replace:

替换:

$totalSize = intval(fgets($io, 80));

by:

由:

strtok(fgets($io, 80), " ");

supposed your "du" function returns the size separated with space followed by the directory/file name.

假定您的“du”函数返回与空间分隔的大小,后跟目录/文件名。

#13


1  

Object Oriented Approach :

面向对象的方法:

/**
 * Returns a directory size
 *
 * @param string $directory
 *
 * @return int $size directory size in bytes
 *
 */
function dir_size($directory)
{
    $size = 0;
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file)
    {
        $size += $file->getSize();
    }
    return $size;
}

Fast and Furious Approach :

《速度与激情》:

function dir_size2($dir)
{
    $line = exec('du -sh ' . $dir);
    $line = trim(str_replace($dir, '', $line));
    return $line;
}

#14


1  

Just another function using native php functions.

使用本机php函数的另一个函数。

function dirSize($dir)
    {
        $dirSize = 0;
        if(!is_dir($dir)){return false;};
        $files = scandir($dir);if(!$files){return false;}
        $files = array_diff($files, array('.','..'));

        foreach ($files as $file) {
            if(is_dir("$dir/$file")){
                 $dirSize += dirSize("$dir/$file");
            }else{
                $dirSize += filesize("$dir/$file");
            }
        }
        return $dirSize;
    }

NOTE: this function returns the files sizes, NOT the size on disk

注意:这个函数返回文件大小,而不是磁盘上的大小。

#15


0  

Evolved from Nate Haugs answer I created a short function for my project:

从Nate Haugs answer衍生而来,我为我的项目创建了一个简短的功能:

function uf_getDirSize($dir, $unit = 'm')
{
    $dir = trim($dir, '/');
    if (!is_dir($dir)) {
        trigger_error("{$dir} not a folder/dir/path.", E_USER_WARNING);
        return false;
    }
    if (!function_exists('exec')) {
        trigger_error('The function exec() is not available.', E_USER_WARNING);
        return false;
    }
    $output = exec('du -sb ' . $dir);
    $filesize = (int) trim(str_replace($dir, '', $output));
    switch ($unit) {
        case 'g': $filesize = number_format($filesize / 1073741824, 3); break;  // giga
        case 'm': $filesize = number_format($filesize / 1048576, 1);    break;  // mega
        case 'k': $filesize = number_format($filesize / 1024, 0);       break;  // kilo
        case 'b': $filesize = number_format($filesize, 0);              break;  // byte
    }
    return ($filesize + 0);
}

#16


0  

A one-liner solution. Result in bytes.

一行程序的解决方案。导致字节。

$size=array_sum(array_map('filesize', glob("{$dir}/*.*")));

Added bonus: you can simply change the file mask to whatever you like, and count only certain files (eg by extension).

附加好处:您可以简单地将文件掩码更改为您喜欢的任何文件,并且只计算某些文件(如扩展名)。