12


KB MB GB TB&coを変換する方法を尋ねています。バイトに。
例えば:

byteconvert("10KB") // => 10240
byteconvert("10.5KB") // => 10752
byteconvert("1GB") // => 1073741824
byteconvert("1TB") // => 1099511627776

等々...

編集:すごい。私は4年以上前にこの質問をしました。このようなことは、あなたが時間の経過とともにどれだけ改善したかを本当に示しています!

4

11 に答える 11

41

これを実現する関数は次のとおりです。

function convertToBytes(string $from): ?int {
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    $number = substr($from, 0, -2);
    $suffix = strtoupper(substr($from,-2));

    //B or no suffix
    if(is_numeric(substr($suffix, 0, 1))) {
        return preg_replace('/[^\d]/', '', $from);
    }

    $exponent = array_flip($units)[$suffix] ?? null;
    if($exponent === null) {
        return null;
    }

    return $number * (1024 ** $exponent);
}

$testCases = ["13", "13B", "13KB", "10.5KB", "123Mi"];
var_dump(array_map('convertToBytes', $testCases));

出力:

array(5){[0] => int(13)[1] => int(13)[2] => int(13312)[3] => int(10752)[4] => NULL} int( 1)

于 2012-08-04T08:41:24.293 に答える
10
function toByteSize($p_sFormatted) {
    $aUnits = array('B'=>0, 'KB'=>1, 'MB'=>2, 'GB'=>3, 'TB'=>4, 'PB'=>5, 'EB'=>6, 'ZB'=>7, 'YB'=>8);
    $sUnit = strtoupper(trim(substr($p_sFormatted, -2)));
    if (intval($sUnit) !== 0) {
        $sUnit = 'B';
    }
    if (!in_array($sUnit, array_keys($aUnits))) {
        return false;
    }
    $iUnits = trim(substr($p_sFormatted, 0, strlen($p_sFormatted) - 2));
    if (!intval($iUnits) == $iUnits) {
        return false;
    }
    return $iUnits * pow(1024, $aUnits[$sUnit]);
}
于 2013-06-28T12:03:27.867 に答える
7

これが私がこれまでに思いついたものであり、はるかにエレガントな解決策だと思います。

/**
 * Converts a human readable file size value to a number of bytes that it
 * represents. Supports the following modifiers: K, M, G and T.
 * Invalid input is returned unchanged.
 *
 * Example:
 * <code>
 * $config->human2byte(10);          // 10
 * $config->human2byte('10b');       // 10
 * $config->human2byte('10k');       // 10240
 * $config->human2byte('10K');       // 10240
 * $config->human2byte('10kb');      // 10240
 * $config->human2byte('10Kb');      // 10240
 * // and even
 * $config->human2byte('   10 KB '); // 10240
 * </code>
 *
 * @param number|string $value
 * @return number
 */
public function human2byte($value) {
  return preg_replace_callback('/^\s*(\d+)\s*(?:([kmgt]?)b?)?\s*$/i', function ($m) {
    switch (strtolower($m[2])) {
      case 't': $m[1] *= 1024;
      case 'g': $m[1] *= 1024;
      case 'm': $m[1] *= 1024;
      case 'k': $m[1] *= 1024;
    }
    return $m[1];
  }, $value);
}
于 2014-07-10T12:26:16.527 に答える
4

関数を使用して、次のような一部のcronスクリプトでPHPに設定されているメモリ制限を決定します。

$memoryInBytes = function ($value) {
    $unit = strtolower(substr($value, -1, 1));
    return (int) $value * pow(1024, array_search($unit, array(1 =>'k','m','g')));
}

フロートでより適切に機能し、2文字の省略形を受け入れる同様のアプローチは、次のようになります。

function byteconvert($value) {
    preg_match('/(.+)(.{2})$/', $value, $matches);
    list($_,$value,$unit) = $matches;
    return (int) ($value * pow(1024, array_search(strtolower($unit), array(1 => 'kb','mb','gb','tb'))));
}
于 2015-01-15T02:59:13.993 に答える
3
<?php
function byteconvert($input)
{
    preg_match('/(\d+)(\w+)/', $input, $matches);
    $type = strtolower($matches[2]);
    switch ($type) {
    case "b":
        $output = $matches[1];
        break;
    case "kb":
        $output = $matches[1]*1024;
        break;
    case "mb":
        $output = $matches[1]*1024*1024;
        break;
    case "gb":
        $output = $matches[1]*1024*1024*1024;
        break;
    case "tb":
        $output = $matches[1]*1024*1024*1024;
        break;
    }
    return $output;
}
$foo = "10mb";
echo "$foo = ".byteconvert($foo)." byte";
?>
于 2012-08-05T01:59:35.150 に答える
3

これに似たものが欲しくて、さまざまな理由でここに投稿された他のソリューションがあまり好きではないので、私は自分の関数を書くことにしました。

function ConvertUserStrToBytes($str)
{
    $str = trim($str);
    $num = (double)$str;
    if (strtoupper(substr($str, -1)) == "B")  $str = substr($str, 0, -1);
    switch (strtoupper(substr($str, -1)))
    {
        case "P":  $num *= 1024;
        case "T":  $num *= 1024;
        case "G":  $num *= 1024;
        case "M":  $num *= 1024;
        case "K":  $num *= 1024;
    }

    return $num;
}

これは、Al Jey(空白の処理)とJohn V(switch-case)によってここに提示されたアイデアのいくつかを適応させますが、正規表現なしで、pow()を呼び出さず、breakがないときにswitch-caseに処理を実行させます、およびいくつかの奇妙なユーザー入力を処理できます(たとえば、「123素晴らしいKB」の結果は125952になります)。より少ない命令を含むより最適なソリューションがあると確信していますが、コードはよりクリーンで読みにくくなります。

于 2016-05-28T13:44:34.660 に答える
1

https://stackoverflow.com/a/17364338/1041470に基づく

改善点:

  • バイトサフィックスの長さのバグを修正しました。
  • double(float)値を使用できますが、整数のみを使用できます。
  • ユニットを保持する逆配列、
  • 変数の名前を変更し、
  • コメントを追加しました。
/**
 * Converts human readable file size into bytes.
 *
 * Note: This is 1024 based version which assumes that a 1 KB has 1024 bytes.
 * Based on https://stackoverflow.com/a/17364338/1041470
 *
 * @param string $from
 *   Required. Human readable size (file, memory or traffic).
 *   For example: '5Gb', '533Mb' and etc.
 *   Allowed integer and float values. Eg., 10.64GB.
 *
 * @return int
 *   Returns given size in bytes.
 */
function cm_common_convert_to_bytes(string $from): ?int {
  static $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
  $from = trim(check_plain($from));
  // Get suffix.
  $suffix = strtoupper(trim(substr($from, -2)));
  // Check one char suffix 'B'.
  if (intval($suffix) !== 0) {
    $suffix = 'B';
  }
  if (!in_array($suffix, $units)) {
    return FALSE;
  }
  $number = trim(substr($from, 0, strlen($from) - strlen($suffix)));
  if (!is_numeric($number)) {
    // Allow only float and integer. Strings produces '0' which is not corect.
    return FALSE;
  }
  return (int) ($number * pow(1024, array_flip($units)[$suffix]));
}
于 2021-01-14T20:39:19.737 に答える
1

私はちょうどこの関数を探していて、それを改善しようと挑戦し、それを2行にしました:)値を検証/抽出するためにEugeneと同様の正規表現を使用しますが、switchステートメントを避けます。長い「10MB」、「10mb」および短い「10M」、「10m」の値、10進値を受け入れることができ、常に整数を返します。無効な文字列は0を返します

function to_bytes( $str )
{
    if( ! preg_match('/^([\d.]+)([BKMGTPE]?)(B)?$/i', trim($str), $m) ) return 0;
    return (int) floor($m[1] * ( $m[2] ? (1024**strpos('BKMGTPE', strtoupper($m[2]))) : 1 ));
}
于 2021-10-25T01:56:10.687 に答える
0

これは比較的古いトピックであることは知っていますが、この種のものが必要なときに時々使用しなければならない関数があります。機能が機能しない場合は言い訳になりますが、私はこれを携帯電話で手作業で作成しました。

function intobytes($bytes, $stamp = 'b') {
    $indx = array_search($stamp, array('b', 'kb', 'mb', 'gb', 'tb', 'pb', 'yb'));
    if ($indx > 0) {
        return $bytes * pow(1024, $indx);
    }
    return $bytes;
}

コンパクトに

function intobytes($bytes, $stamp='b') {$indx=array_search($stamp,array('b','kb','mb','gb','tb','pb','yb'));if($indx > 0){return $bytes * pow(1024,$indx);} return $bytes;}

気をつけて!

Brodde85;)

于 2014-12-12T19:34:54.900 に答える
0

もう1つのソリューション(IEC):

<?php

class Filesize
{
    const UNIT_PREFIXES_POWERS = [
        'B' => 0,
        ''  => 0,
        'K' => 1,
        'k' => 1,
        'M' => 2,
        'G' => 3,
        'T' => 4,
        'P' => 5,
        'E' => 6,
        'Z' => 7,
        'Y' => 8,
    ];

    public static function humanize($size, int $precision = 2, bool $useBinaryPrefix = false)
    {
        $base = $useBinaryPrefix ? 1024 : 1000;
        $limit = array_values(self::UNIT_PREFIXES_POWERS)[count(self::UNIT_PREFIXES_POWERS) - 1];
        $power = ($_ = floor(log($size, $base))) > $limit ? $limit : $_;
        $prefix = array_flip(self::UNIT_PREFIXES_POWERS)[$power];
        $multiple = ($useBinaryPrefix ? strtoupper($prefix) . 'iB' : $prefix . 'B');
        return round($size / pow($base, $power), $precision) . $multiple;
    }

    // ...
}

ソース:

https://github.com/mingalevme/utils/blob/master/src/Filesize.php https://github.com/mingalevme/utils/blob/master/tests/FilesizeTest.php

于 2017-01-20T08:35:31.103 に答える
0

これは、標準に従ってもう少しクリーンなバージョンです(上記の回答を使用):

/**
 * Format kb, mb, gb, tb to bytes
 *
 * @param integer $size
 * @return integer
 */
function formatToBytes ($size)
{
    $aUnits = array('bytes' => 0, 'KB' => 1, 'MB' => 2, 'GB' => 3, 'TB' => 4);
    $sUnit = strtoupper(trim(substr($size, -2)));
    if (intval($sUnit) !== 0) {
        $sUnit = 'bytes';
    }
    if (!in_array($sUnit, array_keys($aUnits))) {
        return false;
    }
    $iUnits = trim(substr($size, 0, strlen($size) - 2));
    if (!intval($iUnits) == $iUnits) {
        return false;
    }
    return $iUnits * pow(1024, $aUnits[$sUnit]);
}
于 2021-02-20T14:11:20.727 に答える