Skip to content

Instantly share code, notes, and snippets.

@loilo
Created February 13, 2021 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loilo/bff3da9f4ec7c649bf27c748133b05f6 to your computer and use it in GitHub Desktop.
Save loilo/bff3da9f4ec7c649bf27c748133b05f6 to your computer and use it in GitHub Desktop.
PHP Filesize Parser
<?php
/**
* Parse a filesize to its number of bytes
*
* @param string|int|float $input
* @param int $base
* @return int
*
* @see https://github.com/patrickkettner/filesize-parser, the original JavaScript implementation of this function
*/
function parse_filesize($input, int $base = 2): int
{
$validAmount = function ($n) {
$n = preg_replace('/[^0-9]+$/', '', $n);
return is_numeric($n) && is_finite((float) $n);
};
$parsableUnit = function ($u) {
return strcspn($u, '0123456789') === strlen($u);
};
static $incrementBases = [
2 => [
[['b', 'bit', 'bits'], 1 / 8],
[['B', 'Byte', 'Bytes', 'bytes'], 1],
[['Kb'], 128],
[['k', 'K', 'kb', 'KB', 'KiB', 'Ki', 'ki'], 1024],
[['Mb'], 131072],
[['m', 'M', 'mb', 'MB', 'MiB', 'Mi', 'mi'], 1024 ** 2],
[['Gb'], 1.342e8],
[['g', 'G', 'gb', 'GB', 'GiB', 'Gi', 'gi'], 1024 ** 3],
[['Tb'], 1.374e11],
[['t', 'T', 'tb', 'TB', 'TiB', 'Ti', 'ti'], 1024 ** 4],
[['Pb'], 1.407e14],
[['p', 'P', 'pb', 'PB', 'PiB', 'Pi', 'pi'], 1024 ** 5],
[['Eb'], 1.441e17],
[['e', 'E', 'eb', 'EB', 'EiB', 'Ei', 'ei'], 1024 ** 6],
],
10 => [
[['b', 'bit', 'bits'], 1 / 8],
[['B', 'Byte', 'Bytes', 'bytes'], 1],
[['Kb'], 125],
[['k', 'K', 'kb', 'KB', 'KiB', 'Ki', 'ki'], 1000],
[['Mb'], 125000],
[['m', 'M', 'mb', 'MB', 'MiB', 'Mi', 'mi'], 1.0e6],
[['Gb'], 1.25e8],
[['g', 'G', 'gb', 'GB', 'GiB', 'Gi', 'gi'], 1.0e9],
[['Tb'], 1.25e11],
[['t', 'T', 'tb', 'TB', 'TiB', 'Ti', 'ti'], 1.0e12],
[['Pb'], 1.25e14],
[['p', 'P', 'pb', 'PB', 'PiB', 'Pi', 'pi'], 1.0e15],
[['Eb'], 1.25e17],
[['e', 'E', 'eb', 'EB', 'EiB', 'Ei', 'ei'], 1.0e18],
],
];
if (!isset($incrementBases[$base])) {
throw new InvalidArgumentException(
sprintf(
'Invalid base: %s. Expected one of: %s.',
json_encode($base),
join(', ', array_keys($incrementBases)),
),
);
}
preg_match('/^([0-9\\.,]*)(?:\\s*)?(.*)$/', (string) $input, $parsed);
$amount = str_replace(',', '.', $parsed[1]);
$unit = $parsed[2];
if (!$validAmount($amount) || !$parsableUnit($unit)) {
throw new InvalidArgumentException("Cannot interpret \"$input\".");
}
$amount = (float) $amount;
if ($unit === '') {
return round($amount);
}
$validUnit = fn($source_unit) => $source_unit === $unit;
$increments = $incrementBases[$base];
foreach ($increments as [$units, $factor]) {
foreach ($units as $unit) {
if ($validUnit($unit)) {
return round($amount * $factor);
}
}
}
throw new InvalidArgumentException("Invalid unit: \"$unit\".");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment