2012-05-30 12 views
1

將字符串轉換爲整數有多種方法。什麼是最好的方式來將字符串轉換爲int,安全明智?

$someString = substr($input, strripos($input, "_") + 1); 
$i = $someString + 0; 
$i = (int) $someString; 
$i = intval($someString); 

$someString來自使用輸入,因此可能必須予以考慮。 「哪個選項更好」或有最負面的副作用? (即在性能方面,安全方面)

$input可以看起來像1_abcd_11_abcd_2。除了abcd這個例子,這是相當固定的—。這個輸入來自單選按鈕,但用戶可以隨時更改他們的數據,如果他們想。因此,我必須考慮到惡意數據。

回答

2

由於輸入被強制轉換爲一個數字,有’沒什麼安全問題。性能差異可以忽略不計。但是,在某些情況下,第一個可能不會生成整數。

例如,讓$input = '19.99';

$i = $someString + 0; // $i = 19.99 

其他兩種情況是等價的,但比$i = intval($someString);更快$i = (int) $someString;平均約56%。由於兩者都在毫秒級內執行,因此性能差異通常可忽略不計,除非它們發生在相當大的循環中。

$i = (int) $someString;  // $i = 9 
$i = intval($someString); // $i = 9 

在安全事項:如果你希望$input總是在一個特定的形式(例如#_xxxx_#),那麼你應該確認它是該格式。如果您使用PHP> = 5.2.0重新使用’,則可以使用正則表達式檢查輸入的格式。

<?php 
$input = '1_abcd_1'; 

// Set the desired format 
$filter_options = array(
    'options' => array(
     // choose a regular expression that matches your format 
     'regexp' => '/^[\d]_[a-z]{4}_[\d]$/' 
    ) 
); 

$format = filter_var($input, FILTER_VALIDATE_REGEXP, $filter_options); 
if ($format !== false) { 
    // process input 
    $someString = substr($format, strripos($format, "_") + 1); 
    $i = (int) $someString; 
    echo '$i = ', $i; 
} else { 
    // Handle invalid format 
    echo 'Malformed data. Potentially malicious'; 
} 
?> 

這將徹底拒絕了諸如:

0xfe 
bob 
j_xtyz_5 
1_wxyz_22 
21_abcd_1 
1_Abcd_2 

當然,你會調整正則表達式您的需求。

參見:

如果’再沒有使用PHP> = 5.2.0,您可以使用preg_match

<?php 
$input = '1_abcd_2'; 

$valid = preg_match('/^[\d]_[a-z]{4}_[\d]$/', $input); 
if ($valid) { 
    // process input 
    $someString = substr($input, strripos($input, "_") + 1); 
    $i = (int) $someString; 
    echo '$i = ', $i; 
} else { 
    // Handle invalid format 
    echo 'Malformed data. Potentially malicious'; 
} 
?> 

驗證輸入的格式,讓你馬上知道數據是否被篡改’秒。然後你可以採取相應的行動

+1

有趣:-)。將結合你的Rajan Rawal建議使用'is_numeric()' –

+0

@DaanTimmer no,'is_numeric('0xfe')== true'這可能不是你想要的;如果你想測試整數,你可以使用'filter_var' –

+0

我更新了我的答案以擴展安全性。感謝您提出filter_var @Jack – Herbert

3

我更喜歡類型鑄造,$i = (int) $someString;這是很清楚。如果你想確保約$ someString

+0

我最喜歡的方法。 – jancha

+0

同樣,接受赫伯特的答案會更徹底。儘管謝謝你的回答! –

1

只有數字,你可以使用

if(is_numeric($someString)){ 
    // proceed your code if $someString is numeric 
}else{ 
    // proceed your code if $someString is not numeric 
} 
+0

是的,我知道爆炸版本。可能確實是做一個is_numeric檢查的好主意。並沒有執行數據庫操作。即使我做了我會使用PDO,並且不需要mysql_real_escape。這也不會阻止SQL注入順便說一句。 –

+0

對不起,我不知道你在使用PDO。我剛剛提到,正如你在安全方面提到你的問題。謝謝。 –

+0

我只是在提取數值的兩種方式(爆炸vs substr)之間進行了性能測試,爆炸速度慢了5%。我跑了每個'功能'100000次。並在一個10倍的循環。這些值比較慢了4%到7%。仍然感謝您花時間。我確實喜歡首先使用is_numeric的建議。 –

相關問題