├── LICENSE.md ├── README.md ├── composer.json └── src ├── ByteSize.php └── Formatter ├── AbstractFormatter.php ├── Binary.php ├── FormatterInterface.php └── Metric.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ryan Chouinard 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ByteSize: File Size Formatter for PHP 2 | 3 | [![Latest Version on Packagist][ico-version]][link-packagist] 4 | [![Software License][ico-license]](LICENSE.md) 5 | [![Build Status][ico-travis]][link-travis] 6 | [![Quality Score][ico-code-quality]][link-code-quality] 7 | [![Total Downloads][ico-downloads]][link-downloads] 8 | 9 | ByteSize is a utility component for formatting file sizes in various formats. 10 | 11 | 12 | ## Requirements 13 | 14 | - PHP 5.3+ 15 | - BCMath extension 16 | 17 | 18 | ## Install 19 | 20 | Via Composer 21 | 22 | ``` bash 23 | $ composer require rych/bytesize 24 | ``` 25 | 26 | 27 | ## Usage 28 | 29 | Basic usage is very simple. Create an instance of `Rych\ByteSize\ByteSize` and 30 | call its `format()` method. 31 | 32 | ```php 33 | format(1440000); 40 | ``` 41 | 42 | The default formatter may be customized as well, using either the 43 | `\Rych\ByteSize\Formatter\Metric` or `\Rych\ByteSize\Formatter\Binary` classes. 44 | The metric formatter is based on a 1000-byte kilobyte and uses standard SI 45 | suffixes (kB, MB, GB, TB, etc). The binary formatter is based on a 1024-byte 46 | kilobyte and uses the standard binary suffixes (KiB, MiB, GiB, TiB, etc). Both 47 | formatters use a default precision of 2 significant digits in the formatted 48 | output, but that can be changed to any number in the range 0-10 inclusive. 49 | 50 | ```php 51 | setPrecision(1); 56 | $bytesize = new \Rych\ByteSize\ByteSize($formatter); 57 | 58 | // Outputs 1.4MiB 59 | echo $bytesize->format(1509949); 60 | ``` 61 | 62 | Precision can also be set at call time via the second argument to the 63 | `format()` methods. 64 | 65 | If you don't care for all this OO stuff, the core `\Rych\ByteSize` class also 66 | provides two static methods: `formatMetric()` and `formatBinary()`. The method 67 | signatures are the same as the standard `format()` methods. 68 | 69 | ```php 70 | =5.3.0", 17 | "ext-bcmath": "*" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "~4.7" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Rych\\ByteSize\\": "src/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ByteSize.php: -------------------------------------------------------------------------------- 1 | 10 | * @license MIT 11 | */ 12 | 13 | namespace Rych\ByteSize; 14 | 15 | /** 16 | * ByteSize class 17 | * 18 | * Provides convenience access to the byte size formatters. 19 | */ 20 | class ByteSize 21 | { 22 | 23 | /** 24 | * Default FormatterInterface instance 25 | * 26 | * @var Formatter\FormatterInterface 27 | */ 28 | protected $formatter; 29 | 30 | /** 31 | * ByteSize constructor 32 | * 33 | * @param Formatter\FormatterInterface $formatter Instance of 34 | * FormatterInterface to use by default. If not passed, an instance of 35 | * Formatter\Metric will be used. 36 | * @return void 37 | */ 38 | public function __construct(Formatter\FormatterInterface $formatter = null) 39 | { 40 | if (!$formatter) { 41 | $formatter = new Formatter\Metric(); 42 | } 43 | 44 | $this->formatter = $formatter; 45 | } 46 | 47 | /** 48 | * Formatter proxy 49 | * 50 | * @param integer|string $bytes Integer or string representing the number 51 | * of bytes. 52 | * @param integer $precision Number of significant digits to include in the 53 | * formatted output. 54 | * @return string Returns a human-friendly formatted string. 55 | */ 56 | public function format($bytes, $precision = null) 57 | { 58 | return $this->formatter->format($bytes, $precision); 59 | } 60 | 61 | /** 62 | * Binary formatter static proxy 63 | * 64 | * @staticvar Formatter\Binary $formatter 65 | * @uses Formatter\Binary::format() 66 | * 67 | * @param integer|string $bytes Integer or string representing the number 68 | * of bytes. 69 | * @param integer $precision Number of significant digits to include in the 70 | * formatted output. 71 | * @return string Returns a human-friendly formatted string. 72 | */ 73 | public static function formatBinary($bytes, $precision = null) 74 | { 75 | static $formatter = null; 76 | if (!$formatter) { 77 | $formatter = new Formatter\Binary(); 78 | } 79 | 80 | return $formatter->format($bytes, $precision); 81 | } 82 | 83 | /** 84 | * Metric formatter static proxy 85 | * 86 | * @staticvar Formatter\Metric $formatter 87 | * @uses Formatter\Metric::format() 88 | * 89 | * @param integer|string $bytes Integer or string representing the number 90 | * of bytes. 91 | * @param integer $precision Number of significant digits to include in the 92 | * formatted output. 93 | * @return string Returns a human-friendly formatted string. 94 | */ 95 | public static function formatMetric($bytes, $precision = null) 96 | { 97 | static $formatter = null; 98 | if (!$formatter) { 99 | $formatter = new Formatter\Metric(); 100 | } 101 | 102 | return $formatter->format($bytes, $precision); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/Formatter/AbstractFormatter.php: -------------------------------------------------------------------------------- 1 | 10 | * @license MIT 11 | */ 12 | 13 | namespace Rych\ByteSize\Formatter; 14 | 15 | /** 16 | * Abstract formatter 17 | * 18 | * Provides base functionality for ByteSize formatters. 19 | */ 20 | abstract class AbstractFormatter implements FormatterInterface 21 | { 22 | 23 | /** 24 | * Base value used by this formatter 25 | * 26 | * @var integer 27 | */ 28 | protected $base; 29 | 30 | /** 31 | * Default precision value 32 | * 33 | * Affects the number of significant digits to include in the formatted 34 | * value. 35 | * 36 | * @var integer 37 | */ 38 | protected $precision = 2; 39 | 40 | /** 41 | * Suffixes used by this formatter 42 | * 43 | * @var array 44 | */ 45 | protected $suffixes = array (); 46 | 47 | /** 48 | * Format input into a human-friendly string for display 49 | * 50 | * @uses \bccomp() 51 | * @uses AbstractFormatter::divPow() 52 | * @uses AbstractFormatter::formatNumber() 53 | * @uses AbstractFormatter::normalizeBytes() 54 | * 55 | * @param integer|string $bytes Integer or string representing the number 56 | * of bytes. 57 | * @param integer $precision Number of significant digits to include in the 58 | * formatted output. Defaults to 2. 59 | * @return string Returns a human-friendly formatted string. 60 | */ 61 | public function format($bytes, $precision = null) 62 | { 63 | $bytes = $this->normalizeBytes($bytes); 64 | $out = $bytes . 'B'; 65 | 66 | foreach ($this->suffixes as $power => $suffix) { 67 | if (bccomp($calc = $this->divPow($bytes, $this->base, $power), 1) >= 0) { 68 | $out = $this->formatNumber($calc, $suffix, $precision); 69 | break; 70 | } 71 | } 72 | 73 | return $out; 74 | } 75 | 76 | /** 77 | * Get the default precision value 78 | * 79 | * @return integer Returns the currently configured precision. 80 | */ 81 | public function getPrecision() 82 | { 83 | return $this->precision; 84 | } 85 | 86 | /** 87 | * Set the default precision value 88 | * 89 | * @uses AbstractFormatter::normalizePrecision() 90 | * 91 | * @param integer $precision An integer between 0 and 10. 92 | * @return AbstractFormatter Returns an instance of self for method 93 | * chaining. 94 | */ 95 | public function setPrecision($precision) 96 | { 97 | $this->precision = $this->normalizePrecision($precision); 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * Divide a dividend by result of power operation 104 | * 105 | * The return value will be a string representation of the result. This is 106 | * due to the BCMath library and so we can work with very large integers. 107 | * 108 | * @uses \bcdiv() 109 | * @uses \bcpow() 110 | * 111 | * @param integer|string $dividend The dividend to use in the division 112 | * operation. 113 | * @param integer $base The base for the power operation. 114 | * @param integer $power The power $base should be raised by. 115 | * @return string Returns the result of the operations. 116 | */ 117 | protected function divPow($dividend, $base, $power) 118 | { 119 | return bcdiv($dividend, bcpow($base, $power, 10), 10); 120 | } 121 | 122 | /** 123 | * Format a float value with given suffix 124 | * 125 | * @uses AbstractFormatter::normalizePrecision() 126 | * 127 | * @param integer|float $float The number to format. 128 | * @param string $suffix The suffix to attach. 129 | * @param integer $precision The number of significant digits to include. 130 | * @return string Returns the formatted string. 131 | */ 132 | protected function formatNumber($float, $suffix, $precision = null) 133 | { 134 | if ($precision === null) { 135 | $precision = $this->precision; 136 | } 137 | $precision = $this->normalizePrecision($precision); 138 | 139 | return sprintf("%.{$precision}f%s", $float, $suffix); 140 | } 141 | 142 | /** 143 | * Normalize bytes value 144 | * 145 | * The resulting value is a string representation of the bytes value. This 146 | * is done by the BCMath library so we can work with very large integer 147 | * values. 148 | * 149 | * @uses \bcadd() 150 | * @uses \bccomp() 151 | * @uses \filter_var() 152 | * 153 | * @param integer|float|string $bytes The bytes value. 154 | * @return string Returns the normalized value. 155 | */ 156 | protected function normalizeBytes($bytes) 157 | { 158 | $filteredBytes = filter_var($bytes, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); 159 | list ($bytes, $part) = explode('.', $filteredBytes . '.0'); 160 | if (bccomp($part, 0) == 1) { 161 | $bytes = bcadd($bytes, 1); 162 | } 163 | 164 | return $bytes; 165 | } 166 | 167 | /** 168 | * Normalize precision value 169 | * 170 | * The resulting value is an integer value between 0 and 10. 171 | * 172 | * @uses \filter_var() 173 | * 174 | * @param integer $precision The precision value. 175 | * @return integer Returns the normalized value. 176 | */ 177 | protected function normalizePrecision($precision) 178 | { 179 | $precisionFiltered = filter_var($precision, FILTER_SANITIZE_NUMBER_INT); 180 | 181 | return (int) min(10, max(0, $precisionFiltered)); 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /src/Formatter/Binary.php: -------------------------------------------------------------------------------- 1 | 10 | * @license MIT 11 | */ 12 | 13 | namespace Rych\ByteSize\Formatter; 14 | 15 | /** 16 | * Binary formatter 17 | * 18 | * Formats byte values using the binary standard values. This formatter 19 | * assumes 1 kilobyte = 1024 bytes. 20 | * 21 | * @link http://en.wikipedia.org/wiki/Binary_prefix Binary prefix at Wikipedia 22 | */ 23 | final class Binary extends AbstractFormatter 24 | { 25 | 26 | /** 27 | * Base value used by this formatter 28 | * 29 | * @var integer 30 | */ 31 | protected $base = 1024; 32 | 33 | /** 34 | * Suffixes used by this formatter 35 | * 36 | * @var array 37 | */ 38 | protected $suffixes = array ( 39 | 8 => 'YiB', 40 | 7 => 'ZiB', 41 | 6 => 'EiB', 42 | 5 => 'PiB', 43 | 4 => 'TiB', 44 | 3 => 'GiB', 45 | 2 => 'MiB', 46 | 1 => 'KiB', 47 | ); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/Formatter/FormatterInterface.php: -------------------------------------------------------------------------------- 1 | 10 | * @license MIT 11 | */ 12 | 13 | namespace Rych\ByteSize\Formatter; 14 | 15 | /** 16 | * Formatter interface 17 | * 18 | * Provides a standard interface for ByteSize formatters. 19 | */ 20 | interface FormatterInterface 21 | { 22 | 23 | /** 24 | * Format input into a human-friendly string for display 25 | * 26 | * @param integer|string $bytes Integer or string representing the number 27 | * of bytes. 28 | * @param integer $precision Number of significant digits to include in the 29 | * formatted output. 30 | * @return string Returns a human-friendly formatted string. 31 | */ 32 | public function format($bytes, $precision); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/Formatter/Metric.php: -------------------------------------------------------------------------------- 1 | 10 | * @license MIT 11 | */ 12 | 13 | namespace Rych\ByteSize\Formatter; 14 | 15 | /** 16 | * Metric formatter 17 | * 18 | * Formats byte values using the metric standard values. This formatter 19 | * assumes 1 kilobyte = 1000 bytes. 20 | * 21 | * @link http://en.wikipedia.org/wiki/Metric_prefix Metric prefix at Wikipedia 22 | */ 23 | final class Metric extends AbstractFormatter 24 | { 25 | 26 | /** 27 | * Base value used by this formatter 28 | * 29 | * @var integer 30 | */ 31 | protected $base = 1000; 32 | 33 | /** 34 | * Suffixes used by this formatter 35 | * 36 | * @var array 37 | */ 38 | protected $suffixes = array ( 39 | 8 => 'YB', 40 | 7 => 'ZB', 41 | 6 => 'EB', 42 | 5 => 'PB', 43 | 4 => 'TB', 44 | 3 => 'GB', 45 | 2 => 'MB', 46 | 1 => 'kB', 47 | ); 48 | 49 | } 50 | --------------------------------------------------------------------------------