【发布时间】:2009-12-16 05:56:58
【问题描述】:
intval 和 (int) 有什么特别的区别吗?
例子:
$product_id = intval($_GET['pid']);
$product_id = (int) $_GET['pid'];
以上两行代码有什么特别的区别吗?
【问题讨论】:
标签: php
intval 和 (int) 有什么特别的区别吗?
例子:
$product_id = intval($_GET['pid']);
$product_id = (int) $_GET['pid'];
以上两行代码有什么特别的区别吗?
【问题讨论】:
标签: php
intval() 可以是要转换的passed a base。 (int) 不能。
int intval( mixed $var [, int $base = 10 ] )
【讨论】:
$i++ 是红色的不正确。但它应该更慢!
$i++。你是什么意思?当你说“但它应该更慢!!”你比较什么?
(int) typecast is faster x 2 ! (int):ideone.com/QggNGc , intval():ideone.com/6Y8mPN
抱歉,我只是想看看 PHP7 是否/如何对这个问题产生影响:
$ php -v
PHP 7.0.4-5+deb.sury.org~trusty+1 (cli) ( NTS )
测试:
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = (int) '1'; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3279.1121006012 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = intval('1'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "5379.3351650238 ms"
如您所见,投射肯定更快,几乎 100%
但我必须在几秒钟之内将循环计数增加到 1 亿次,而这正是我真正开始关心性能的时候,在大多数情况下。
所以我会坚持使用intval 函数,因为强制转换是一种正在发生的语言魔法。即使intval在幕后使用强制转换,如果发现强制转换的错误,并且由于某种原因无法修复(向后兼容性?),那么他们至少可以修复intval以履行其职责.
更新(PHP 7.1 + 额外案例):
$ php -v
PHP 7.1.0RC6 (cli) (built: Nov 9 2016 04:45:59) ( NTS )
$ php -a
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = (int) '1'; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3583.9052200317 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = intval('1'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3569.0960884094 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = '1' + 0; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "1641.7920589447 ms"
看起来像 7.1 优化了 intval,而 '1' + 0 现在是这场速度竞赛的获胜者 :) 无论如何我还是会继续使用 intval
【讨论】:
+0 var...不确定这里的隐式转换是否比显式转换更快。
+0 获胜...这是一个非常肮脏的黑客行为
v5.5.34,我的结果分别为9191.0059452057 ms、23307.397127151 ms 和11483.719110489 ms。所以在 PHP 7 之前,强制转换是最快的。
+0 和 |0 在投射非数字或空字符串时都会发出 警告,+0 也会发出 投射空数组时出现致命错误
intval 的一个有用属性是 - 因为它是一个函数而不是语言结构 - 它可以作为参数传递给需要函数的函数。 (int) 无法做到这一点。
例如,我通过将整数传递给array_map 来清理整数以包含在SQL IN() 子句中。这是一个例子:
$ids = implode(",", array_map('intval', $_POST['array_of_integers']));
$sql = "SELECT * FROM table WHERE ids IN ($ids)";
【讨论】:
array_map(function($n){return (int)$n;}, $_POST['array_of_integers'])
关于 (int) 和 intval() 之间的区别需要注意的一点:intval() 将已经是 ints 和 floats 的变量视为不需要转换,无论基本参数如何(从 PHP 开始) 5.3.5 至少)。这种行为并不是最明显的,正如comments on the PHP doc page 中所指出的,并且在这里无耻地重申:
$test_int = 12;
$test_string = "12";
$test_float = 12.8;
echo (int) $test_int; // 12
echo (int) $test_string; // 12
echo (int) $test_float; // 12
echo intval($test_int, 8); // 12 <-- WOAH!
echo intval($test_string, 8); // 10
echo intval($test_float, 8) // 12 <-- HUH?
【讨论】:
The base parameter has no effect unless the var parameter is a string. 然后页面显然是四天前更新的,所以也许这就是添加的内容。
intval(12,8) 会给出一个答案,当转换为没有格式的字符串时看起来像一个以 8 为基数的数字是错误的。您对intval(12,16) 有什么期望,因为它不能将c 设为int?
我认为至少有一个区别:使用intval,您可以指定应使用哪个基数作为第二个参数(默认为基数10):
var_dump((int)"0123", intval("0123"), intval("0123", 8));
会得到你:
int 123
int 123
int 83
【讨论】:
intval("2g", 17) = 50 = 2*17 + 16
36,例如intval("g", 36) //16。任何大于 36 的值都返回 0。这表明我们可以将所有 0-9 加上 a-z 字符用于我们的自定义基数,例如 intval("z",36) //35。另外需要注意的是,第一个参数是不区分大小写的。
Amber 是对的,如果我可以添加有用的信息
类型转换(在你的表达式之前添加一个“(int)”)比 intval 快 300% 到 600%。
因此,如果您的目的不是处理十进制以外的其他基数,我建议使用:
(int) $something
【讨论】:
intval 做而简单的转换没有做的事情是基本转换:
int intval ( mixed $var [, int $base = 10 ] )
如果基数是 10,intval 应该与强制转换相同(除非你会挑剔并提到一个调用函数而另一个不调用)。如man page 所述:
适用整数转换的通用规则。
【讨论】: