Variable handling 函数
在线手册:中文 英文
PHP手册

intval

(PHP 4, PHP 5)

intval获取变量的整数值

描述

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

通过使用特定的进制转换(默认是十进制),返回变量 varinteger 数值。

var 可以是任何标量类型。intval() 不能用于 arrayobject

Note:

除非 var 参数是字符串,否则 intval()base 参数不会有效果。

参见 floatval()strval()settype()类型戏法


Variable handling 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 获取变量的整数值

用户评论:

Ken (12-Nov-2011 07:50)

Not mentioned elsewhere: intval(NULL) also returns 0.

christianblumer (09-Nov-2011 03:48)

inval work well with numbers except the kind:
intval("10.2e+2")
which gives 10
the trick around is to use the following function:

<?php
function smart_val($string) {
  eval(
"\$number=$string;");
  return
$number;
}
?>

Doing <?php echo smart_val("10.2e+2"); ?>
gives: 1020

yves (28-Dec-2010 04:53)

The behaviour of intval() is interesting when supplying a base, and you better check your intval base-based expressions, as it is counter-intuitive.
As the example shows
<?php
  intval
('42', 8); // => 34
 
intval(42, 8);   // => 42 !
?>
PHP considers the 42 as being already an integer, and doesn't apply any conversion. And supplying
<?php
  intval
(49, 8);  // => 49 !
?>
produces no error and no warning.

winbill at hotmail dot com (16-Dec-2010 04:31)

Be careful :

<?php
$n
="19.99";
print
intval($n*100); // prints 1998
print intval(strval($n*100)); // prints 1999
?>

tr at comcar dot co dot uk (16-Sep-2010 02:35)

Be careful when passing this function a string value with a leading "0". If you give it "09" for example, it will treat it as BASE 8 - 9. I was going crazy as my code was telling me that 09 > 9.

gom3r (18-Aug-2010 02:19)

Here is one example how to use this function to

<?php
echo $_GET['userId']; // 1 or 1=1
$id=intval($_GET['userId']); 
echo
$id; // 1

mysql_query('SELECT * FROM users WHERE id='.$id); // a (very) safe query

?>

jeremy at cfegames dot com (12-Aug-2010 03:41)

When retrieving numbers or integers from a MySQL DB, it's best to use intval(), or it will continue to be a string.

<?php
while($row = mysql_fetch_array($check)
{
 
$_SESSION['id'] = inval($row['id']);
 
$user_id = intval($_SESSION['id']); // Not sure if you need to do it again, but doesn't hurt.
}

is_int($_SESSION['id'])
is_int($user_id)
is_string($_SESSION['id'])
is_string($user_id)

// Output
true
true
false
false
?>

spoon_reloaded at gmail dot com (21-Jun-2009 06:35)

Here is a really useful undocumented feature:

You can have it automatically deduce the base of the number from the prefix of the string using the same syntax as integer literals in PHP ("0x" for hexadecimal, "0" for octal, non-"0" for decimal) by passing a base of 0 to intval():

<?php
echo intval("0x1a", 0), "\n"; // hex; prints "26"
echo intval("057", 0), "\n"; // octal; prints "47"
echo intval("42", 0), "\n"; // decimal; prints "42"
?>

bert at nospam dot thinc dot nl (07-Jun-2009 12:16)

If you need the reverse function of intval(), the code hereunder might be helpfull.

<?php
function itoa( $ii, $radix=10, $stritoa="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabc" ) {
    if (
$radix > strlen( $stritoa ) )    //    does request makes sense?
       
return "";    //    think of your own way to handle this case
   
$sign = $ii<0 ? "-": "";
   
$ii = abs( $ii );
   
$rc = "";
    do {
       
$rc .= $stritoa[ $ii % $radix ];
       
$ii = floor( $ii / $radix );
        } while (
$ii >0 );
    return
$sign . strrev( $rc );
    }
?>

ittasks at gmail dot com (24-Mar-2009 09:47)

when converting some optional form values to positive integers and to be on the safe side, you can use this:

<?php $q=intval("0".$_REQUEST['q']); ?>

jeromakay at yahoo dot com (02-Mar-2009 10:40)

To convert a string to a number, and avoid the 32 bit issues of intval you can use:

<?php

$no
= "214742780440" + 0;

var_dump($no); // float(214742780440) 

?>

I used to intval() everything before entering it into the DB, but it seems impractical with values over 2147483647.

To get even better idea of how it validates, try this:

<?php

$no
= "qwerty1234" + 0;

var_dump($no); // int(0) 

?>

Ben L (25-Oct-2008 01:37)

I was browsing around the site, and I seen some people commented on my comment down the way a while back...

re: Disturbing issue with intval()

I was of the opinion then as I'm of the opinion now that if you are going to have a function like intVal in a language in conjunction with a standard type casting syntax such as (int)$var, then it should not be vulnerable to floating point issues.

It's obvious that it would be very easy to do so, as when you do: echo 19.99 * 100; or intVal((string)(19.99 * 100));

it gives you 1999.

However if you do intVal(19.99 * 100), then echo it out, it outputs 1998...

This shows that type casting the float val of 19.99 * 100 to a string gives you a happy 19.99, instead of outputting 19.989999...etc

I would expect this behavior of (int)(19.99 * 100)...

But not of the function intVal, which was my point of the comment in the first place.  Once I noticed that behavior a long time ago I started using round, on such values and only use intVal/typecasting to int from string variables such as $_REQUEST variables that I expect to be in integer format.

I still wish intVal handled all that for you though.

Seally (28-Aug-2008 10:47)

Re: nobodyisperfect88 at hotmail dot de
jay at w3prodigy dot com had it right. I believe it is an issue with the floating point registers on computers, which have a precision of about 17 digits. When you get more precise than that, it rounds.

Since the second example can fit in the register, no rounding occurs, and PHP can truncate the portion after the decimal. However, the system automatically rounds the first example to 1, which is what PHP returns.

(Tested on Windows XP 32bit)

yhoko at yhoko dot com (17-Aug-2008 03:29)

Note that this function behaves different in PHP4/5 when parsing NAN-values. Try the following example:

<?php die( "Result = " . intval( NAN ) ); ?>

- In PHP 4 the result is 0
- In PHP 5 the result is 2^31 (running on 32bit)

Yhoko

phpben hood id au (11-Jun-2008 01:17)

kris at mha dot ca:

Implicit typing. This is a feature, not a bug.

The == operator will convert your string to an int automatically (in this case) so that it is really comparing 123 and 123, which is of course the same.

If you use the === operator then this will not occur, as it will only match on the same value and type. This works as expected:

<?php

$tmp_array
= "123,232,141";

if (
intval($tmp_array) === $tmp_array)
{
    echo
"'".intval($tmp_array)."' equals '$tmp_array'\n";
}
else
{
    echo
"'".intval($tmp_array)."' does not equal '$tmp_array'\n";
}

?>

nobodyisperfect88 at hotmail dot de (14-May-2008 07:46)

jay at w3prodigy dot com
25-Mar-2008 09:05
Note:

$int = 0.99999999999999999;
echo intval($int); // returns 1

and

$int = 0.9999999999999999;
echo intval($int); // returns 0
----------------------------------------------------------

^^the first is wrong ... i think it should be called

$int = 1.99999999999999999;
echo intval($int); // returns 1
and not

$int = 0.99999999999999999;
echo intval($int); // returns 1

jay at w3prodigy dot com (25-Mar-2008 08:05)

Note:

$int = 0.99999999999999999;
echo intval($int); // returns 1

and

$int = 0.9999999999999999;
echo intval($int); // returns 0

michiel ed thalent nl (12-Dec-2007 01:44)

A function to get an integer from everywhere in a string (concatenated or not).

<?php
function str2int($string, $concat = true) {
   
$length = strlen($string);   
    for (
$i = 0, $int = '', $concat_flag = true; $i < $length; $i++) {
        if (
is_numeric($string[$i]) && $concat_flag) {
           
$int .= $string[$i];
        } elseif(!
$concat && $concat_flag && strlen($int) > 0) {
           
$concat_flag = false;
        }       
    }
   
    return (int)
$int;
}
echo
var_dump(str2int('sh12apen11')); // int(12)
echo var_dump(str2int('sh12apen11', false)); // int(1211)
echo var_dump(str2int('shap99en')); // int(99)
echo var_dump(intval('shap99en')); // int(0)
?>

lrdsatyr8 at hotmail dot com (31-Oct-2007 01:09)

If you just want to get the integer value of a number without all the hassle, just use intval()... like so:

$a1 = 10.4;
$a2 = -12.5;
$a3 = 44.1238503;

print intval($a1);   // returns 10
print intval($a2);   // returns -12
print intval($a3);   // returns 44

it's that easy!

shermy at shermys dot com (17-Oct-2007 01:35)

<?php

$tmp_array
= "123,232,141";

if (
strval(intval($tmp_array)) == $tmp_array)
{
    echo
"'".intval($tmp_array)."' equals '$tmp_array'\n";
}
else
{
    echo
"'".intval($tmp_array)."' does not equal '$tmp_array'\n";

}

?>

Output:

'123' does not equal '123,232,141'

jazeik at gmail dot com (31-Jul-2007 02:15)

@kris:
If you had followed the following links:
"The common rules of integer casting apply." => http://us.php.net/manual/en/language.types.integer.php
"See String conversion to numbers" => http://us.php.net/manual/en/language.types.integer.php

Then you would have found the following: "The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used."

So this behaviour is a feature not a bug.

The following code will work:
<?php

$tmp_array
= str_replace(",", "", "123,232,141");

if(
intval($tmp_array) == $tmp_array){
    echo
intval($tmp_array) . " equals $tmp_array\n";
}else{
    echo
intval($tmp_array) . " does not equal $tmp_array\n";
}

?>

Output:
123232141 equals 123232141

kris at mha dot ca (17-Jul-2007 11:41)

More intval wierdness (tested with PHP 5.2.3 and 4.3.10). 

<?php

$tmp_array
= "123,232,141";

if (
intval($tmp_array) == $tmp_array)
{
    echo
"'".intval($tmp_array)."' equals '$tmp_array'\n";
}
else
{
    echo
"'".intval($tmp_array)."' does not equal '$tmp_array'\n";

}

?>

Output:

'123' equals '123,232,141'

Odd.  Not what was expected.  Maybe if I put it into a temporary variable it will normalize itself.

<?php

$tmp_array
= "123,232,141";
$tmp = intval($tmp_array);

if (
$tmp == $tmp_array)
{
    echo
"'$tmp' equals '$tmp_array'\n";
}
else
{
    echo
"'$tmp' does not equal '$tmp_array'\n";

}

?>

Output:

'123' equals '123,232,141'

I don't know if this is a feature, or a bug in PHP (I would certainly classify this as a bug, but since it is in both PHP 4 and PHP 5 maybe not).  If it is a feature, could someone explain it to me?

vizigr0u at gmail dot com (24-Jun-2007 12:50)

intval used on bools returns either 1 or 0
I usually use this to properly set bools in my tables
(assuming you use some kind of int like tinyints as booleans) :
<?php
$myvar
= 'right value';
mysql_query('INSERT INTO mytable (activated)
VALUES('
. intval($myvar === 'right value') . ')');
?>

aryel at redtwilightNO dot comSPAM dot brNOT (26-Apr-2007 06:42)

Since integers are stored on multiple bytes in the memory in binary format, once an signed long integer reaches the maximum value of 2147483646 (which is the maximum value that 8 bits of memory, size of a long int, can store, binary-wise), atleast on C/C++ the number starts to roll back, going gradually to ...45, ...45 and eventually reaching a negative value. Some REALLY large values will return -1, probably because PHP simply rejects the number, though I'm not sure why.

For further info:
http://www.rwc.uc.edu/koehler/comath/13.html

maciek dot iwanowskis at glasspartnership dot co dot uk (04-Apr-2007 06:36)

It seems that if you're trying to cast to integer (or use intval()) on integer of value bigger then 2147483646 it's hard to predict returned value.

(27-Apr-2006 06:36)

Operating on integers gives puzzling results--which don't seem to have to do with the number of bits...

<?php
echo intval(1e10);  // -1 on my system; 1410065408 in the example
echo intval(1e5); // 100000 (my own example: lower number--works all right)
echo intval(4e9);  // -294967296 ! (my own example: somewhere in the middle)

echo intval(42000000);  // 42000000 (as in the manual; reasonable)
echo intval(420000000000000000000);  // -1 on my system at least. 0 in the example
// ...and yet still odder...
echo intval(4200000000);  // -94967296! (my own example: somewhere in between)
?>

mkamerma at science dot uva dot nl (07-Mar-2006 07:48)

As addendum, the "if ($int > 0)" check in the encode function is redundant. It doesn't do anything bad to keep it in since it will always be true when reaching that point, but it's a meaningless conditional this way. It's a remnant from when I tried to write the function in terms of bitshifts, which could lead to negative ints when shifting if the 32nd bit was set (instead of always padding with 0's when using >> it pads with 1's leading to negative ints).

mkamerma at science dot uva dot nl (05-Mar-2006 10:04)

When you need to work with integer values that exceed maxint, the following functions may be of use to you - they form a codec pair for integers of variable length rather than fixed length, encoded in a byte as a 7 bit numberal with a 1 bit has-more flag, indicating that the next byte encodes a higher order part of the same number still.

<?php
/* encode integer as 7bit with has-more bit numeral,
    ordered lowest byte first. */
function encode_7bhm($int) {
  if (
$int==0) return chr(0); // shortcut
 
$ret = "";
  while(
$int != 0) {
   
$high = floor($int / 128);     // overflow for this round
   
$low = $int - ($high * 128); // 7 bit numeral
   
if ($int > 0) {
      if (
$high > 0) { $low = $low + 128; } // has-more flag
     
$ret .= chr($low); } //encode
   
$int = $high// set overflow as next round's number
 
}
  return
$ret;
}

/* decode a 7bit with has-more bit numeral,
    ordered lowest byte first. */
function decode_7bhm($hmb) {
 
$ret = 0;
 
$pos = 0;
 
$high = 1;
  while(
$high == 1) {
   
$byte = ord(substr($hmb, $pos, 1));
   
$high = floor($byte/128); // gets has-more flag
   
$low = $byte - ($high*128);
   
$ret += $low * pow(128, $pos++); // decode
 
}
  return
$ret;
}
?>

This codec pair is also quite useful when needing to write ints to files, as this is a low-numeral biased encoding: most of the time this will only require 8 or 16 bit rather than the 32 bits an int will use in fixed-length encoding.

The encoding range:

  1 byte  - 0 through 128 (2^7)
  2 bytes - 129 through 16,384 (2^14)
  3 bytes - 16,385 through 2,097,152 (2^21)
  4 bytes - 2,097,153 through 268,435,456 (2^28)

while indeed a 32 bit encoded variable length integer will be lower than maxint, rather than needing a new 32 bit block to represent higher range only 8 more bits are required to represent this higher number (for completeness the range of representation by bytes 5-8 are listed):

  5 bytes - 268,435,457 through 34,359,738,368 (2^35)
  6 bytes - 343,59,738,369 through 4,398,046,511,104 (2^42)
  7 bytes - 4,398,046,511,105 through 562,949,953,421,312 (2^49)
  8 bytes - 562,949,953,421,313 through 720,57,594,037,927,936 (2^56)

Also for completeness, the function to read a 7 bit with has-more bit from a filepointer:

<?php
// read a 7bhm numeral from file
function read_7bhm($fp) {
 
$bytestring = "";
 
$high = 1;
  while(
$high==1) {
   
$byte = fread($fp, 1);
   
$high = floor(ord($byte)/128); // check for has-more bit
   
$bytestring .= $byte;
  }
  return
decode_7bhm($bytestring); }
?>

simon at npkk dot cz (30-Jan-2006 04:03)

Still have on mind, that if you convert big numbers by adding zero, PHP makes automatic "to a float" conversion, so it is same as floatVal(). So if the number is realy big (over 13 digits), you can lose preciosity. Do not use it for such long numbers, if all bits do matter (IPv6 addresses and similar).

simon at npkk dot cz (30-Jan-2006 02:48)

intval() returns maxint on number_in_string, if the result would be bigger than it. But for float returns the signed 32 bit integer with the "same" value:
<?php
$num
=-1000;
print(
$num."\n");
$i_str=sprintf("%u",$num);
print(
$i_str."\n");
$i1=intval($i_str);
print(
$i1."\n");
$i2=intval(floatval($i_str));
print(
$i2."\n");
?>

prints:

-1000
4294966296
2147483647
-1000

anonymous at place dot com (17-Jan-2006 05:37)

re: Disturbing issue with intval()

It's probably just good practice to round decimals anyways.  i.e...

$amount = round(19.99 * 100);
$test2 = intVal($amount);
$test3 = intVal("$amount");

echo $test2 . "<br />\n";
echo $test3 . "<br />\n";

Ben Laurienti (16-Jan-2006 09:21)

You guys are going to love this.  I found something that I found quite disturbing.

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

expected output:
1999
1999
1999

actual output
1999
1998
1999

Appears to be a floating point issue, but the number 1999 is the only number that I was able to get to do this.  19.99 is the price of many things, and for our purpose we must pass it as 1999 instead of 19.99.

adspeed.com (29-Jul-2005 04:32)

Say you have a string $s="3763328634" to be used as a key into the database, intval() this string will result in a different,smaller number (depends on the machine/OS). To keep the number intact but as an int/long type, do $s +=0; instead.

(24-May-2004 04:38)

When trying to read 32bit values (32 bit limitation depends on the word size of your machine)  from a string that is represented in hex with the high bit set,
eg. F9833234

intval returns -1. The reason is the sign bit being set. This number is larger than can be saved in a signed int.

The way around this is to read the value in using two calls to intval.

eg.

$val = intval(substr($str,0,4), 16); // read high 16 bit word
$val <<= 16; // shift hi word correct position
$val |= intval(substr($str, 4, 4), 16); //  read low 16 bit word

tuxedobob at mac dot com (07-Feb-2004 12:56)

Sometimes intval just won't cut it. For example if you want to use an unsigned 32-bit int and need all 32 bits. Recently, I wrote a little script that took and integer and converted it to an IP address. After realizing I couldn't just mod the whole thing, since the sign bit throws it off (and compensating for that), we ran into a problem where if it was entered into a form, the value somehow wasn't converted to an integer properly, at least not implicitly. The solution for this, and the way I recommend converting a string to an integer, is:

$num = $num + 0;

and PHP will leave your number alone; it'll just know it's a number. Such is the fun of a loosely-typed language. :)

Robin Y. Millette http://rym.waglo.com (15-May-2003 09:29)

Rob_Kohr at no_need_to_email dot me dot com
11-Nov-2002 12:24    

[snip]

$var=intval("122.5");
//$var==122

This is nice if you want to turn a double into an int automatically rounding down

Hum, I had a bug earlier today, involving ===. Coming from a c++ background, I can't help testing for types. I was using floor() to get an integer from a division by 2, and comparing that to a known integer from a for loop. Well, first I changed the === to == because the test would always be false otherwise. Next, I looked up this function, and converted most of my floor() calls to intval() calls, because I really meant to get an int, and not a float with no decimal part. So I have to disagree with the editor note here. Oh, and I'm comfortably back to using ===.

cleong at letstalk dot com (02-Oct-2001 01:21)

intval() handles overflow differently depending on the type of the argument.

intval('10000000000') = 2147483647
intval(1e10) = 1410065408

intval(float) yields essentially non-defined result when the argument is beyond the range of int.

zak at php dot net (12-Aug-2000 09:38)

intval converts doubles to integers by truncating the fractional component of the number.

When dealing with some values, this can give odd results.  Consider the following:

print intval ((0.1 + 0.7) * 10);

This will most likely print out 7, instead of the expected value of 8.

For more information, see the section on floating point numbers in the PHP manual (http://www.php.net/manual/language.types.double.php)

Also note that if you try to convert a string to an integer, the result is often 0.

However, if the leftmost character of a string looks like a valid numeric value, then PHP will keep reading the string until a character that is not valid in a number is encountered.

For example:

"101 Dalmations" will convert to 101

"$1,000,000" will convert to 0 (the 1st character is not a valid start for a number

"80,000 leagues ..." will convert to 80

"1.4e98 microLenats were generated when..." will convert to 1.4e98

Also note that only decimal base numbers are recognized in strings.

"099" will convert to 99, while "0x99" will convert to 0.

One additional note on the behavior of intval.  If you specify the base argument, the var argument should be a string - otherwise the base will not be applied.

For Example:

print intval (77, 8);   // Prints 77
print intval ('77', 8); // Prints 63