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>';
}
Avez-vous une idée de la raison pour laquelle l'utilisation du processeur augmente trop ou 100% jusqu'à la fin de l'exécution du script? Peut-on faire quelque chose pour l'optimiser? ou existe-t-il un autre moyen de vérifier le dossier et les dossiers qu'il contient?
Voici d'autres solutions offertes ailleurs :
Si sur un hôte 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';
}
?>
Sinon, si sur un hôte 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;
?>
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;
}
La même idée que Janith Chinthana a suggéré. Avec quelques corrections:
$path
en realpath.
et ..
Un exemple pur en php.
<?php
$units = explode(' ', 'B KB MB GB TB PB');
$SIZE_LIMIT = 5368709120; // 5 GB
$disk_used = foldersize("/webData/users/[email protected]");
$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];
}
?>
taille du répertoire en utilisant php taille du fichier et RecursiveIteratorIterator .
Cela fonctionne avec n'importe quelle plate-forme ayant une version de PHP 5 ou supérieure.
**
* 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;
}
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;
}
Grâce à Jonathan Sampson, Adam Pierce et Janith Chinthana, je l’ai vérifiée pour trouver la manière la plus performante d’obtenir la taille du répertoire. Devrait fonctionner sur les hôtes Windows et 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);
}
}
J'ai trouvé cette approche plus courte et plus compatible. La version "du" pour Mac OS X ne prend pas en charge l’option -b (ou --bytes) pour une raison quelconque; elle est donc liée à l’option plus compatible -k.
$file_directory = './directory/path';
$output = exec('du -sk ' . $file_directory);
$filesize = trim(str_replace($file_directory, '', $output)) * 1024;
Renvoie la taille de fichier $ en octets.
L'exemple Linux de Johnathan Sampson n'a pas fonctionné aussi bien pour moi. Voici une version améliorée:
function getDirSize($path)
{
$io = popen('/usr/bin/du -sb '.$path, 'r');
$size = intval(fgets($io,80));
pclose($io);
return $size;
}
Même s'il y a déjà beaucoup de réponses à ce message, j'estime devoir ajouter une autre option pour les hôtes Unix qui ne renvoie que la somme de toutes les tailles de fichiers du répertoire (récursivement).
Si vous regardez la réponse de Jonathan, il utilise la commande du
. Cette commande renverra la taille totale du répertoire, mais les solutions pures PHP publiées par d’autres ici renverront la somme de toutes les tailles de fichiers. Grande différence!
Lors de l'exécution de du
sur un répertoire nouvellement créé, il peut renvoyer 4K
au lieu de 0
. Cela peut même devenir plus déroutant après avoir supprimé des fichiers du répertoire en question et avoir du
rapportant une taille de répertoire totale qui ne correspond pas à la somme des tailles des fichiers qu'il contient. Pourquoi? La commande du
renvoie un rapport basé sur certains paramètres de fichier, comme l'a commenté Hermann Ingjaldsson sur this post .
Pour former une solution qui se comporte comme certains des scripts PHP uniquement publiés ici, vous pouvez utiliser la commande ls
et la transmettre à awk
comme ceci:
ls -ltrR /path/to/dir |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'
En tant que fonction PHP, vous pouvez utiliser quelque chose comme ceci:
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;
}
Vous pouvez optimiser le script de différentes manières, mais le maximum de succès le rendrait lié à l'IO plutôt qu'à l'unité centrale:
rtrim($path, '/')
en dehors de la boucle.if ($t<>"." && $t<>"..")
le test externe - il n'a pas besoin de stat sur le cheminrtrim($path, '/') . '/' . $t
une fois par boucle - à l'intérieur de 2) et en prenant 1) en compte.explode(' ','B KB MB GB TB PB');
une fois plutôt que chaque appel?Après un travail acharné, ce code fonctionne très bien !!!! et je veux partager avec la communauté (par 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);
Bon code! Fernando
Juste une autre fonction utilisant les fonctions PHP natives.
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;
}
REMARQUE: cette fonction renvoie la taille des fichiers, PAS la taille sur le disque
Approche Orientée Objet:
/**
* 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;
}
Approche rapide et furieuse:
function dir_size2($dir)
{
$line = exec('du -sh ' . $dir);
$line = trim(str_replace($dir, '', $line));
return $line;
}
En ce qui concerne l'exemple Linux de Johnathan Sampson, faites attention lorsque vous effectuez un intval sur le résultat de la fonction "du", si la taille est> 2 Go, il continue d'afficher 2 Go.
Remplacer:
$totalSize = intval(fgets($io, 80));
par:
strtok(fgets($io, 80), " ");
supposé que votre fonction "du" retourne la taille séparée par un espace suivi du nom du répertoire/fichier.
Evolue à partir de la réponse de Nate Haugs, j’ai créé une fonction courte pour mon projet:
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);
}
Cela fonctionne parfaitement bien.
public static function folderSize($dir)
{
$size = 0;
foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
$func_name = __FUNCTION__;
$size += is_file($each) ? filesize($each) : static::$func_name($each);
}
return $size;
}
Une solution one-liner. Résultat en octets.
$size=array_sum(array_map('filesize', glob("{$dir}/*.*")));
Bonus supplémentaire: vous pouvez simplement changer le masque de fichier comme bon vous semble, et ne compter que certains fichiers (par exemple, par extension).
Code ajusté pour accéder au répertoire principal et à tous les sous-dossiers qu'il contient. Cela renverrait la taille complète du répertoire.
function get_dir_size($directory){
$size = 0;
$files= glob($directory.'/*');
foreach($files as $path){
is_file($path) && $size += filesize($path);
if (is_dir($path))
{
$size += get_dir_size($path);
}
}
return $size;
}