其他地方没有提到: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 行为的另一个注意事项:如果您指定了 base 参数,那么 var 参数应该是一个字符串 - 否则 base 将不会被应用。
例如
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。
这是一个非常有用的未公开功能
您可以通过将 base 传递为 0 给 intval(),让它使用与 PHP 中整数字面量相同的语法("0x" 表示十六进制,"0" 表示八进制,非 "0" 表示十进制)自动推断数字的基数。
<?php
echo intval("0x1a", 0), "\n"; // 十六进制;打印 "26"
echo intval("057", 0), "\n"; // 八进制;打印 "47"
echo intval("42", 0), "\n"; // 十进制;打印 "42"
?>
二进制表示法直到 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
?>
如果您想从字符串中获取一个数字,无论它可能包含什么,这里有一个很好的解决方案
<?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 的巨大整数时,后者更好。
PHP 7.2
$test = intval(150.20*100); //15019
$test2 = intval(15020); //15020
$test3 = intval(15020.0); //15020
$test4 = 150.20*100; //15020.0
有时 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;
}
?>
当您真正想要 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
注意
<?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 );
}
?>
当提供一个 base 时,intval() 的行为很有趣,您最好检查您的基于 base 的 intval 表达式,因为它不直观。
如示例所示
<?php
intval('42', 8); // => 34
intval(42, 8); // => 42 !
?>
PHP 将 42 视为已经是一个整数,并且不执行任何转换。提供
<?php
intval(49, 8); // => 49 !
?>
不会产生错误或警告。
作为补充,encode 函数中的 "if ($int > 0)" 检查是多余的。由于当到达该点时它总是为 true,所以保留它不会造成任何负面影响,但这样它就是一个毫无意义的条件语句。它是在我尝试用位移运算来编写函数时留下的残留部分,当第 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
再次强调,一旦你了解 intval() 会解释科学计数法,这种行为就多少是可以预料的。但这似乎是一个不太为人所知的知识点,我在使用 php 20 多年后才遇到这个问题。