intval和强制转换为int-`(int)X`之间有什么特别的区别吗?


219

intval和(int)之间有什么特别的区别吗?

例:

$product_id = intval($_GET['pid']);
$product_id = (int) $_GET['pid'];

上面两行代码之间有什么特别的区别吗?

Answers:


192

intval()可以传递转换的基础。(int)不能。

int intval( mixed $var  [, int $base = 10  ] )

73
(int)比intval()更快,根据wiki.phpbb.com/Best_Practices:PHP
Martin Thoma

正如我今天早些时候在下面指出的那样,如果参数是int或float,则基本转换将无法正常工作。
t-dub

1
@moose该页面的状态$i++不正确的红色。但是应该慢一些!
Shiplu Mokaddim

1
我从没说过$i++。你什么意思?当您说“但是应该慢一些!” 你比较什么?
马丁·托马

6
我在ideone上进行基准测试- (int)类型转换速度快了2倍! (int)ideone.com/QggNGcintval()ideone.com/6Y8mPN
jave.web 2014年

52

有一点需要注意的区别(int)intval()intval()对待变量,已经是intS和floatS作为需要任何转换,无论基本参数的(如PHP 5.3.5至少)。正如在PHP doc页面上的注释中所指出的那样,这种行为并不是最明显的,并且在这里毫不客气地重申:

$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?

13
文档确实说过。The base parameter has no effect unless the var parameter is a string.然后该页面显然是在四天前更新的,所以也许这就是添加的内容。
Lightness Races in Orbit


6
考虑到该函数在理论上可以进行基础转换,因此无论该行为是否得到了明显的证明,该行为都令人惊讶。它肯定让我绊倒了,但也许我只需要更仔细地进行RTFM :)
t-dub 2012年

7
我意识到这是一个旧线程,如果您仍在编程,那么希望您现在明白为什么这实际上是最明显的结果。int没有基数,因为基数仅用于字符串表示形式。或更简单地说,以10为底的int与以99为底的int相同。它仍然是12。期望intval(12,8)的答案是,当转换为无格式的字符串时,它看起来像以8为底数字是错误的。您会intval(12,16)因为无法进行int操作而期望得到什么c
罗伯特·麦基

1
或另一种方式...自1970年1月1日以来,已有1523994328个刻度。询问将其存储为MM / DD / YYYY还是DD / MM / YYYY没有任何意义,因为它没有以任何一种格式存储。它以数字形式存储,而不是以任何特定的日期格式存储。与询问int的基数相同。将值与它们显示的格式分开非常重要。
罗伯特·麦基

32

对不起,我只是想看看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反正


1
剩下的唯一基准是+0var ...不确定此处的隐式强制转换是否比显式的转换更快。
SparK's

2
大声笑@ +0获胜...这是一个非常肮脏的hack
SparK '16

@SparK你的想法:)我不会相信,虽然它,PHP的类型转换规则都是不完全的最好

对于v5.5.34我的研究结果9191.0059452057 ms23307.397127151 ms11483.719110489 ms分别。因此,在PHP 7之前,铸造是最快的。
GreeKatrina

虽然它像远不如理解我$a = '1' + 0;,我敢打赌大多数从来没有想过做这样的
话筒

26

我认为至少有一个区别:使用intval,您可以指定哪个基数应用作第二个参数(默认情况下,基数为10):

var_dump((int)"0123", intval("0123"), intval("0123", 8));

会给你:

int 123
int 123
int 83

11
我发现令人难以置信的是,可以将基数17的数字“ g”转换为十进制:intval("2g", 17) = 50 = 2*17 + 16
JSchaefer 2011年

1
@JSchaefer我更进一步,发现我可以通过的最大基数是36,例如in intval("g", 36) //16。任何大于36的值都将返回0。这表明我们可以将所有0-9加az字符用于自定义基数,例如intval("z",36) //35。另外,应注意的是,第一个参数不区分大小写
杰伊·达德尼亚

17

的一个有用特性intval是-因为它是一个函数而不是语言构造,所以它可以作为参数传递给需要该函数的函数。你不能这样做(int)

例如,我使用它通过将整数IN()传递给来清理整数以包含在SQL 子句中array_map。这是一个例子:

$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'])
Daniel Omine's 2016年

@DanielOmine我的意思是您可以使用它而无需定义回调函数。
科多斯·约翰逊


8

intval简单的转换不会做的事情是基本转换:

int intval ( mixed $var [, int $base = 10 ] )

如果基数是10,intval则应与强制类型转换相同(除非您会很挑剔,并提到一个调用函数而另一个不调用)。如手册页所述

适用整数转换的通用规则。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.