2009-08-26 28 views
12

我需要測試ini_get('memory_limit')返回的值,並在內存限制低於某個閾值時增加內存限制,但是此調用返回字符串值(如'128M')而不是整數。PHP中是否有一種簡單的方法將字符串從'256M','180K','4G'轉換爲它們的整數對應值?

我知道我可以編寫一個函數來解析這些字符串(以案例和尾隨「B的考慮),我已經寫了他們無數次:

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

我覺得你的運氣了。 ini_get()的PHP手冊實際上解決了這個特定的問題,其中有關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源代碼一樣。「

+0

與John的答案相同的問題:不處理可選的尾部B. – cletus 2009-08-26 19:03:40

+1

是的,的確如此。我主要是提供它來說明PHP手冊如何聲明它已完成。如果你只想分析'ini_get()'的結果,那麼這將起作用,否則你必須自己修改它。海報問題的簡短答案實際上是「不,沒有內置方法」。 – zombat 2009-08-26 19:30:31

+0

我在ini值的描述中尋找這個信息,除了'ini_get()'函數本身的文檔以外的其他地方。感謝您的發現。 – 2009-08-27 13:55:40

2

從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; 
} 
+0

實際上不處理可選B關於結束。 – cletus 2009-08-26 18:34:20

+0

它什麼時候有B?該平臺是特定的嗎? – 2009-08-26 18:59:06

+0

看看OP的正則表達式。最後有一個可選的B. – cletus 2009-08-26 19:02:33

2

我只能想到上略有變化的你在做什麼:

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); 
} 
+1

我其實更喜歡原始版本:沒有循環。至少沒有明確的循環:) – elcuco 2009-08-26 19:18:04

4

或者一些較短的版本,如果你願意

function toInteger ($string) 
{ 
    sscanf ($string, '%u%c', $number, $suffix); 
    if (isset ($suffix)) 
    { 
     $number = $number * pow (1024, strpos (' KMG', strtoupper($suffix))); 
    } 
    return $number; 
} 
相關問題