代码之家  ›  专栏  ›  技术社区  ›  Adam Franco

在PHP中,是否有一种简单的方法可以将字符串“256M”、“180K”、“4G”转换为它们的整数等价物?

php
  •  13
  • Adam Franco  · 技术社区  · 15 年前

    我需要测试返回的值 ini_get('memory_limit') 如果内存限制低于某个阈值,则增加内存限制,但是 ini-get('内存限制') call返回字符串值,如“128m”,而不是整数。

    我知道我可以编写一个函数来解析这些字符串(考虑到大小写和尾随'b's),因为我已经多次编写了这些字符串:

    function int_from_bytestring ($byteString) {
      preg_match('/^\s*([0-9.]+)\s*([KMGTPE])B?\s*$/i', $byteString, $matches);
      $num = (float)$matches[1];
      switch (strtoupper($matches[2])) {
        case 'E':
          $num = $num * 1024;
        case 'P':
          $num = $num * 1024;
        case 'T':
          $num = $num * 1024;
        case 'G':
          $num = $num * 1024;
        case 'M':
          $num = $num * 1024;
        case 'K':
          $num = $num * 1024;
      }
    
      return intval($num);
    }
    

    然而,这会变得单调乏味,这看起来像是那些在PHP中已经存在的随机事件之一,尽管我从未发现过它。有人知道解析这些字节量字符串的一些内置方法吗?

    5 回复  |  直到 7 年前
        1
  •  5
  •   zombat    15 年前

    我想你运气不好。PHP手册 ini_get() 实际上,在一个关于ini_get()如何返回ini值的警告中解决了这个特定的问题。

    它们在其中一个示例中提供了一个函数来实现这一点,因此我猜想这是一种方法:

    function return_bytes($val) {
        $val = trim($val);
        $last = strtolower($val[strlen($val)-1]);
        switch($last) {
            // The 'G' modifier is available since PHP 5.1.0
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }
    
        return $val;
    }
    

    关于上面的函数,他们这样说:“上面的例子展示了将速记符号转换成字节的一种方法,很像PHP源代码的方法。”

        2
  •  4
  •   Ramunas Dronga    9 年前

    或者更短的版本,如果你愿意的话

    function toInteger ($string)
    {
        sscanf ($string, '%u%c', $number, $suffix);
        if (isset ($suffix))
        {
            $number = $number * pow (1024, strpos (' KMG', strtoupper($suffix)));
        }
        return $number;
    }
    
        3
  •  2
  •   John Rasch    15 年前

    从php网站 ini_get() :

    function return_bytes($val) {
        $val = trim($val);
        $last = strtolower($val[strlen($val)-1]);
        switch($last) {
            // The 'G' modifier is available since PHP 5.1.0
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }
    
        return $val;
    }
    
        4
  •  2
  •   cletus    15 年前

    我想你所做的只是略有不同:

    function int_from_bytestring($byteString) {
      $ret = 0;
      if (preg_match('!^\s*(\d+(?:\.\d+))\s*([KMNGTPE])B?\s*$!', $byteString, $matches)) {
        $suffix = " KMGTPE";
        $index = strpos($suffix, $matches[2]);
        if ($index !== false) {
          $ret = $matches[1];
          while ($index--) {
            $matches *= 1024;
          }
        }
      }
      return intval($ret);
    }
    
        5
  •  0
  •   Jacques Amar    7 年前

    因为如果该值末尾有字符,则较新版本的PHP会出错,因此可能需要进行一些额外的测试:

    private function toBytes($str){
        $val = trim($str);
        $last = strtolower($str[strlen($str)-1]);
        if (!is_numeric($last)) {
            $val = substr($val,0,strlen($val)-1);
            switch($last) {
                case 'g': $val *= 1024;
                case 'm': $val *= 1024;
                case 'k': $val *= 1024;
            }
        }
        return $val;
    }
    

    这项工作没有警告