113

Làm cách nào tôi có thể chuyển đổi đầu ra của filesize()chức năng PHP sang định dạng đẹp với MegaBytes, KiloBytes, v.v.?

như:

  • nếu kích thước nhỏ hơn 1 MB, hãy hiển thị kích thước tính bằng KB
  • nếu nó nằm trong khoảng 1 MB - 1 GB thì hiển thị bằng MB
  • nếu nó lớn hơn - tính bằng GB
|
240

Đây là một mẫu:

<?php
// Snippet from PHP Share: http://www.phpshare.org

    function formatSizeUnits($bytes)
    {
        if ($bytes >= 1073741824)
        {
            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
        }
        elseif ($bytes >= 1048576)
        {
            $bytes = number_format($bytes / 1048576, 2) . ' MB';
        }
        elseif ($bytes >= 1024)
        {
            $bytes = number_format($bytes / 1024, 2) . ' KB';
        }
        elseif ($bytes > 1)
        {
            $bytes = $bytes . ' bytes';
        }
        elseif ($bytes == 1)
        {
            $bytes = $bytes . ' byte';
        }
        else
        {
            $bytes = '0 bytes';
        }

        return $bytes;
}
?>
|
57

Phiên bản này thậm chí còn đẹp hơn mà tôi đã tạo từ một plugin tôi tìm thấy:

function filesize_formatted($path)
{
    $size = filesize($path);
    $units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
    $power = $size > 0 ? floor(log($size, 1024)) : 0;
    return number_format($size / pow(1024, $power), 2, '.', ',') . ' ' . $units[$power];
}

Lưu ý từ fileizeize ()

Vì loại số nguyên của PHP được ký và nhiều nền tảng sử dụng số nguyên 32 bit, một số hàm hệ thống tệp có thể trả về kết quả không mong muốn cho các tệp lớn hơn 2GB

|
  • 1

    tuyệt vời, chính xác những gì tôi đang tìm kiếm, cảm ơn!

    – Đặng Nghĩa Anh 16:05:58 05/09/2012
  • 1

    Tại sao nó "đẹp hơn" tho? Nó gần giống với phiên bản của tôi, ngoại trừ việc nó sẽ trả lại kích thước sai cho các tệp trên 2 GB (cộng với OP không bao giờ yêu cầu các đơn vị năng lượng còn lại).

    – Dương Vành Khuyên 13:35:58 19/11/2012
  • 1

    @AlixAxel Nó đẹp hơn, vì nó chỉ bằng một nửa và vẫn dễ đọc. Ngoài ra tôi cá là nó nhanh hơn. Nhưng này, nó không phải là cá nhân. Tôi đã không nghĩ về nó bản thân mình. Phiên bản của bạn cũng rất tuyệt! Nâng cấp nó;)

    – Nguyễn Văn Tèo 16:16:52 19/11/2012
  • 1

    Adnan đăng dài dòng nhất, nhưng cũng là câu trả lời hiệu quả nhất. Sử dụng hàm log để xác định các đơn vị chậm hơn nhiều so với sử dụng các bất đẳng thức đơn giản. Ngay cả việc sử dụng các câu lệnh chia liên tiếp trong một vòng lặp cũng nhanh hơn nhiều so với sử dụng nhật ký

    – Hoàng Nam Sơn 02:41:02 25/05/2013
  • 1

    @PiTheNumber Xem xét ghi chú tại filesize()doc : "Vì loại số nguyên của PHP đã được ký và nhiều nền tảng sử dụng số nguyên 32 bit, một số hàm hệ thống tệp có thể trả về kết quả không mong muốn cho các tệp lớn hơn 2GB". Vì lý do này và vì nhiều lý do nữa, tôi hoàn toàn không tin rằng ai đó sẽ sử dụng PHP để vận hành trên các tệp, kích thước được tính vào TB, không đề cập đến quy mô cao hơn. Ngoài ra, tôi nghi ngờ chức năng của bạn nhanh hơn Alix Axel vì bạn đang sử dụng powchức năng, tương tự như mức tiêu thụ tài nguyên logđược Alix sử dụng.

    – Đỗ Thanh Phong 09:33:28 17/09/2013
41

Một cách tiếp cận sạch hơn:

function Size($path)
{
    $bytes = sprintf('%u', filesize($path));

    if ($bytes > 0)
    {
        $unit = intval(log($bytes, 1024));
        $units = array('B', 'KB', 'MB', 'GB');

        if (array_key_exists($unit, $units) === true)
        {
            return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
        }
    }

    return $bytes;
}
|
  • 1

    Điều này có vẻ sạch hơn nhưng sử dụng nhật ký để xác định các đơn vị tốn kém hơn nhiều so với sử dụng một vài bất đẳng thức đơn giản.

    – Đặng Nghĩa Anh 02:38:08 25/05/2013
  • 1

    @AliGangji: Đúng, chính xác hơn từ 0,1% đến 42% (tùy thuộc vào ifđiều kiện nào $bytesrơi vào).

    – Dương Vành Khuyên 03:48:00 25/05/2013
  • 1

    @AliGangji: Để mở rộng nhận xét cuối cùng của tôi, có vẻ như đối với các giá trị <= 1023 byte, cách tiếp cận nhật ký trung bình chậm hơn ~ 40% nhưng đối với 1024 trở lên, tôi nhận được trung bình nhất quán ở mức 0,1%. Hấp dẫn!

    – Nguyễn Văn Tèo 03:55:31 25/05/2013
  • 1

    @AlixAxel Sẽ không như vậy, bởi vì trình phân tích cú pháp PHP phân tích ifkhối từ dưới lên, tức là bắt đầu từ đơn (cuối cùng) elsevà đi lên tất cả elseifcho đến khi cuối cùng đạt đến đầu tiên (theo thứ tự) if? Chỉ cần lang thang, tại sao bạn nhận được kết quả như vậy?

    – Hoàng Nam Sơn 09:29:42 17/09/2013
  • 1

    Tôi không thể tin được rằng các bạn đang lo lắng về 'chi phí' của một sự đánh đồng logarit trong câu trả lời gọn gàng và thanh lịch hơn nhiều này. Làm thế nào bạn thậm chí điểm chuẩn sự khác biệt đó? Và, tại sao không bắt đầu chức năng với một so sánh với> = 1024 trước khi áp dụng phụ lục đơn vị nếu nhật ký ist rất tốn kém?

    – Đỗ Thanh Phong 11:26:50 22/06/2015
12

Tôi nghĩ rằng đây là một cách tiếp cận tốt hơn. Đơn giản và thẳng tiến.

public function sizeFilter( $bytes )
{
    $label = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB' );
    for( $i = 0; $bytes >= 1024 && $i < ( count( $label ) -1 ); $bytes /= 1024, $i++ );
    return( round( $bytes, 2 ) . " " . $label[$i] );
}
|
6

Điều này dựa trên câu trả lời tuyệt vời của @ adnan.

Thay đổi:

  • thêm cuộc gọi filesize () nội bộ
  • trở lại phong cách sớm
  • lưu một kết nối trên 1 byte

Và bạn vẫn có thể kéo lệnh gọi filesize () ra khỏi hàm, để có được một hàm định dạng byte thuần túy. Nhưng điều này hoạt động trên một tập tin.


/**
 * Formats filesize in human readable way.
 *
 * @param file $file
 * @return string Formatted Filesize, e.g. "113.24 MB".
 */
function filesize_formatted($file)
{
    $bytes = filesize($file);

    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } elseif ($bytes > 1) {
        return $bytes . ' bytes';
    } elseif ($bytes == 1) {
        return '1 byte';
    } else {
        return '0 bytes';
    }
}
|
5

Đây sẽ là một thực hiện sạch hơn:

function size2Byte($size) {
    $units = array('KB', 'MB', 'GB', 'TB');
    $currUnit = '';
    while (count($units) > 0  &&  $size > 1024) {
        $currUnit = array_shift($units);
        $size /= 1024;
    }
    return ($size | 0) . $currUnit;
}
|
2
function getNiceFileSize($file, $digits = 2){
    if (is_file($file)) {
        $filePath = $file;
        if (!realpath($filePath)) {
            $filePath = $_SERVER["DOCUMENT_ROOT"] . $filePath;
        }
        $fileSize = filesize($filePath);
        $sizes = array("TB", "GB", "MB", "KB", "B");
        $total = count($sizes);
        while ($total-- && $fileSize > 1024) {
            $fileSize /= 1024;
        }
        return round($fileSize, $digits) . " " . $sizes[$total];
    }
    return false;
}
|
2

Một ví dụ hoàn chỉnh.

<?php
    $units = explode(' ','B KB MB GB TB PB');
    echo("<html><body>");
    echo('file size: ' . format_size(filesize("example.txt")));
    echo("</body></html>");


    function format_size($size) {

        $mod = 1024;

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

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

        return substr( $size, 0, $endIndex).' '.$units[$i];
    }
?>
|
1
//Get the size in bytes
function calculateFileSize($size)
{
   $sizes = ['B', 'KB', 'MB', 'GB'];
   $count=0;
   if ($size < 1024) {
    return $size . " " . $sizes[$count];
    } else{
     while ($size>1024){
        $size=round($size/1024,2);
        $count++;
    }
     return $size . " " . $sizes[$count];
   }
}
|
1
function calcSize($size,$accuracy=2) {
    $units = array('b','Kb','Mb','Gb');
    foreach($units as $n=>$u) {
        $div = pow(1024,$n);
        if($size > $div) $output = number_format($size/$div,$accuracy).$u;
    }
    return $output;
}
|
0

Tất cả các câu trả lời cho câu hỏi sử dụng 1 kilobyte = 1024 byte là sai! ( 1 kibibyte = 1024 byte )

vì câu hỏi yêu cầu chuyển đổi kích thước tệp, nên sử dụng 1 kilobyte = 1000 byte (xem https://wiki.ub Ubuntu.com/UnitsPolicy )

function format_bytes($bytes, $precision = 2) {
    $units = array('B', 'KB', 'MB', 'GB');

    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1000));
    $pow = min($pow, count($units) - 1);

    $bytes /= pow(1000, $pow);

    return round($bytes, $precision) . ' ' . $units[$pow];
}
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.