其他地方未提及:intval(NULL) 也返回 0。
(PHP 4, PHP 5, PHP 7, PHP 8)
intval — 获取变量的整数值
value
转换为整数的标量值
base
转换的基数
注意:
如果
base
为 0,则使用的基数由value
的格式确定。
- 如果字符串包含 "0x"(或 "0X")前缀,则基数取为 16(十六进制);否则,
- 如果字符串以 "0b"(或 "0B")开头,则基数取为 2(二进制);否则,
- 如果字符串以 "0" 开头,则基数取为 8(八进制);否则,
- 基数取为 10(十进制)。
成功时返回value
的整数值,失败时返回 0。空数组返回 0,非空数组返回 1。
最大值取决于系统。32 位系统的最大带符号整数范围为 -2147483648 到 2147483647。例如,在这样的系统上,intval('1000000000000')
将返回 2147483647。64 位系统的最大带符号整数值为 9223372036854775807。
字符串很可能会返回 0,但这取决于字符串的最左字符。适用的整数转换的常用规则。
示例 #1 intval() 示例
以下示例基于 64 位系统。
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 10000000000
echo intval('1e10'); // 10000000000
echo intval(0x1A); // 26
echo intval('0x1A'); // 0
echo intval('0x1A', 0); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // -4275113695319687168
echo intval('420000000000000000000'); // 9223372036854775807
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
echo intval(false); // 0
echo intval(true); // 1
?>
注意:
除非
value
参数是字符串,否则base
参数无效。
小心
<?php
$n="19.99";
print intval($n*100); // 输出 1998
print intval(strval($n*100)); // 输出 1999
?>
看起来`intval`在PHP 5.6和7.0与PHP 7.1之间对有效数字字符串的解释有所不同。
<?php
echo intval('1e5');
?>
在PHP 5.6和PHP 7.0中将返回1,
但在PHP 7.1中将返回100000。
`intval`通过截断数字的小数部分将双精度数转换为整数。
处理某些值时,这可能会产生奇怪的结果。考虑以下情况:
print intval ((0.1 + 0.7) * 10);
这很可能会输出7,而不是预期的8。
更多信息,请参见PHP手册中关于浮点数的部分(https://php.net/manual/language.types.double.php)
另请注意,如果尝试将字符串转换为整数,结果通常为0。
但是,如果字符串的最左字符看起来像一个有效的数值,则PHP将继续读取字符串,直到遇到在数字中无效的字符。
例如
"101 Dalmations" 将转换为 101
"$1,000,000" 将转换为 0(第一个字符不是数字的有效起始字符)
"80,000 leagues ..." 将转换为 80
"1.4e98 microLenats were generated when..." 将转换为 1.4e98
另请注意,字符串中只识别十进制数。
"099" 将转换为 99,而 "0x99" 将转换为 0。
关于`intval`行为的另一个说明:如果指定了基数参数,则`var`参数应为字符串——否则基数将不会应用。
例如
print intval (77, 8); // 输出 77
print intval ('77', 8); // 输出 63
你们会喜欢这个的。我发现了一些让我相当不安的东西。
$test1 = intVal(1999);
$amount = 19.99 * 100;
$test2 = intVal($amount);
$test3 = intVal("$amount");
echo $test1 . "<br />\n";
echo $test2 . "<br />\n";
echo $test3 . "<br />\n";
预期输出
1999
1999
1999
实际输出
1999
1998
1999
看起来像是浮点数问题,但数字1999是我唯一能够做到这一点的数字。19.99是许多东西的价格,出于我们的目的,我们必须将其作为1999而不是19.99传递。
这是一个非常有用的未公开特性
你可以使用与PHP中整数字面量相同的语法("0x"表示十六进制,"0"表示八进制,非"0"表示十进制),通过向`intval()`传递基数0来自动推断数字的基数。
<?php
echo intval("0x1a", 0), "\n"; // 十六进制;输出 "26"
echo intval("057", 0), "\n"; // 八进制;输出 "47"
echo intval("42", 0), "\n"; // 十进制;输出 "42"
?>
如果要从字符串中提取数字,无论其中可能包含什么,这是一个很好的解决方案
<?php
function int($s){return(int)preg_replace('/[^\-\d]*(\-?\d*).*/','$1',$s);}
echo int('j18ugj9hu0gj5hg');
//输出:18
?>
此示例返回一个整数,因此它将遵循整数规则,并支持负值。
<?php
function int($s){return($a=preg_replace('/[^\-\d]*(\-?\d*).*/','$1',$s))?$a:'0';}
echo int('j-1809809808908099878758765ugj9hu0gj5hg');
//输出:-1809809808908099878758765
?>
此示例返回仅包含数值的字符串。
它也支持负值。
当使用32位系统并且想要一个大于PHP_MAX_INT的巨大整数时,后者更好。
二进制表示法直到php7.2才受支持
<?php
// PHP <7.2 | PHP >=7.2
echo intval(0b11); // 3 | 3
echo intval(-0b11); // -3 | -3
echo intval('0b11'); // 0 | 0
echo intval('-0b11'); // 0 | 0
echo intval('0b11', 0); // 0 | 3
echo intval('-0b11', 0); // 0 | -3
?>
有时`intval`无法满足要求。例如,如果要使用无符号32位整数并需要所有32位。最近,我编写了一个小程序,它获取一个整数并将其转换为IP地址。在意识到我不能只对整个数字取模,因为符号位会将其弄乱(并为此进行补偿)之后,我们遇到了一个问题,如果将其输入表单,该值不知何故没有正确转换为整数,至少没有隐式转换。针对此问题的解决方案,以及我推荐的将字符串转换为整数的方法是
$num = $num + 0;
PHP将保留您的数字;它只会知道它是一个数字。这就是弱类型语言的乐趣。:)
警告:不要单独使用此函数进行输入验证。
存在漏洞的示例
<?php
if(isset($_GET['id']) && intval($_GET['id']) > 0){
echo $id;
}
?>
以下请求将通过此过滤器
/page.php?id=10
/page.php?id=10oops
/page.php?id=10<script>alert(1)</script>
/page.php?id=1' OR '1'='1
/page.php?id[]=<script>alert(1)</script>
改为使用`is_numeric()`函数进行整数验证
<?php
echo intval("10oops"); // 10
echo is_numeric("10oops"); // false
?>
安全的示例
<?php
if(isset($_GET['id']) && is_numeric($_GET['id']) && intval($_GET['id']) > 0){
echo $id;
}
?>
PHP 7.2
$test = intval(150.20*100); //15019
$test2 = intval(15020); //15020
$test3 = intval(15020.0); //15020
$test4 = 150.20*100; //15020.0
当您真正需要`round()`时,不要使用`intval()`。这是由于PHP处理精度的方式。
echo number_format(8.20*100, 20), "<br />";
echo intval(8.20*100), "<br />";
echo floor(8.20*100), "<br />";
echo round(8.20*100), "<br />";
819.99999999999988631316
819
819
820
当提供基数时,`intval()`的行为很有趣,您最好检查一下基于基数的`intval`表达式,因为它违反直觉。
如示例所示
<?php
intval('42', 8); // => 34
intval(42, 8); // => 42 !
?>
PHP认为42已经是整数,并且不应用任何转换。并且提供
<?php
intval(49, 8); // => 49 !
?>
不会产生错误或警告。
小心
<?php
// 注意以下情况
echo intval( strval( -0.0001 ) ); // 0
echo intval( strval( -0.00001 ) ); // -1
// 这是因为
echo strval( -0.0001 ); // -.0001
echo strval( -0.00001 ); // -1.0E-5
// 因此在使用时要注意
function trunc2_bad( $n ) {
return intval( strval( $n * 100 ) / 100 );
}
// 请改用这个
function trunc2_good( $n ) {
return intval( floatval( strval( $n * 100 ) ) / 100 );
}
?>
作为补充,encode 函数中的 "if ($int > 0)" 检查是冗余的。保留它不会造成任何坏处,因为它到达该点时总是为真,但这是一种毫无意义的条件判断。这是我尝试使用位移来编写函数时的残留物,如果设置了第 32 位,则位移时可能会导致负整数(使用 >> 时总是用 0 填充,而不是用 1 填充,从而导致负整数)。
警告:intval() 解析科学计数法,例如 "12.3e7"。
当您使用 intval() 从字符串中截取第一个整数值时,这会出乎意料地出现;乍一看没什么问题,如果您有 "123.jeff",它会返回 123,但在很少情况下解析具有十六进制数的第二段时,很容易遇到这种情况。(让我们不要开始讨论“你为什么要解析这样的字符串”这个论点。)
因此,如果您没有做好准备,这些结果可能会让您感到意外。
intval("123.ee-2") - 返回 123
intval("123.e2-e") - 返回 12300
intval("123.a2-e") - 返回 123
intval("123.e-22") - 返回 0
intval("123.e-a2") - 返回 123
intval("123.e-2a") - 返回 1
intval("123.2e2a") - 返回 12320
intval("123.22e2") - 返回 12322
intval("123.22ea") - 返回 123
再说一次,一旦您知道它会解释科学计数法,这在某种程度上是预期的行为。但这似乎是一个鲜为人知的事实,在使用 PHP 20 多年后我才遇到这个问题。