从安全角度来看,将字符串转换为 int 的首选方法是什么


What is the prefered way to converting a string to an int, security-wise?

有多种

方法可以将字符串转换为整数。

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

$someString来自使用输入,因此可能必须考虑这一点。哪个选项"更好"或具有最负面的副作用?(即性能方面,安全方面)

$input可以看起来像 1_abcd_11_abcd_2 .这是非常固定的 - 除了本例中组成的abcd。此输入来自单选按钮,但用户始终可以根据需要更改其数据。因此,我必须考虑恶意数据。

我更喜欢类型转换,$i = (int) $someString;很清楚。

由于输入被转换为数字,因此不存在安全问题。性能差异可以忽略不计。但是,在某些情况下,第一个可能不会生成整数。

例如,让 $input = '19.99'; .

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

其他两种情况是等效的,但$i = (int) $someString;平均比$i = intval($someString);快约 56%。由于两者都在几毫秒内执行,因此性能差异通常可以忽略不计,除非它们发生在相当大的循环中。

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

关于安全问题:如果您希望$input始终采用特定形式(例如#_xxxx_#),那么您应该验证它是否采用该格式。扩展 Jack 的评论 — 如果您使用的是 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

当然,您可以根据需要调整正则表达式。

另请参阅:

  • Dev Shed 教程:使用过滤器扩展检查正则表达式 - PHP
  • PHP 手册: filter_var

如果您不使用 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';
}
?>

验证输入的格式可以让您立即知道数据是否被篡改。然后你可以采取相应的行动。

如果你想确定$someString只有数字,你可以使用

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