Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any particular difference between intval and casting to int - `(int) X`?

Tags:

php

intval() can be passed a base from which to convert. (int) cannot.

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

One thing to note about the difference between (int) and intval(): intval() treats variables which are already ints and floats as needing no conversion, regardless of the base argument (as of PHP 5.3.5 at least). This behavior isn't the most obvious, as noted in the comments on the PHP doc page and shamelessly reiterated here:

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

Sorry for necroing, I just wanted to see if/how PHP7 has an effect on this question:

$ php -v
PHP 7.0.4-5+deb.sury.org~trusty+1 (cli) ( NTS )

The test:

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"

As you can see, casting is definitely faster, by almost 100%

But I had to increase the loop count to 100 million before the difference was a matter of seconds, which is about when I would actually start caring about performance, in most cases.

So I'll stick with using the intval function, because casting is a bit of language magic that's happening. Even if intval uses casting behind the scenes, if there were to be a bug found with casting, and for some reason it could not be fixed (backwards compatibility?), then they could at least fix intval to perform it's duty.

Update (PHP 7.1 + Extra case):

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

Looks like 7.1 optimized intval, and '1' + 0 is now the winner of this speed contest :) I'd still keep using intval anyway


I think there is at least one difference : with intval, you can specify which base should be used as a second parameter (base 10 by default) :

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

will get you :

int 123
int 123
int 83

One useful property of intval is that - since it is a function and not a language construct - it can be passed as an argument to a function that expects a function. You can't do this with (int).

For example, I have used it to sanitize integers for inclusion into a SQL IN() clause by passing it to array_map. Here is an example:

$ids = implode(",", array_map('intval', $_POST['array_of_integers']));
$sql = "SELECT * FROM table WHERE ids IN ($ids)";

Amber is right and if I may add a useful information type casting (adding a "(int)" before your expression ) is 300 to 600% faster than intval. So if your purpose is not to dealing with other bases than decimal, I recommend using: (int) $something


The thing that intval does that a simple cast doesn't is base conversion:

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

If the base is 10 though, intval should be the same as a cast (unless you're going to be nitpicky and mention that one makes a function call while the other doesn't). As noted on the man page:

The common rules of integer casting apply.