// EDIT: The end goal is to detect whether user-submitted value is a string, or an integer. Because the value is obtained from form input, it is cast as string even when the value provided is an integer number.
I am performing a simple comparison to detect if a string variable is equal to its integer value. The value is passed from an HTML form field.
When the string value is a single letter, it evaluates to true, when it should not.
if ( ($val == (int)$val ) && strlen( $val ) == strlen( (int)$val ) ){
}
I've also tried using intval() rather than casting int variable type.
It is always evaluating as true. But r does not == 0, so how can this be?
$val = 'r';
echo 'Does $val = (int)$val? ' . ($val == (int)$val);
echo '<br/><br/>';
echo '$val was: ' . $val . '<br/>';
echo '(int)$val was: ' . (int)$val;
Output:
Does $val = (int)$val? 1
$val was: r
(int)$val was: 0
To check if your string is actually a number (which is what you want according to your comments), you don't have to hack together some custom test. PHP provides a built-in function for this:
if(is_numeric($val)) {
//do integer stuff
} else {
//do string stuff
}
To check whether string is actually a number, I'd use something like that:
if (strval(intval($val, 10)) == $val)
Note: this will detect only strings with integer numbers, there is also is_numeric which works for decimal and exponential (like +0123.45e6).
Note 2: is_int detects actual type of variable, so for "123" it will return false because it is string.
Note 3: you could have problems when number is submitted with + prefix like +123 - it is up to you whether you want to support such case or not
I am trying to check, Input is an integer, float or string. This program gives an error on negative inputs, I don't understand why this happen. When i check inputs with "ctype_digit()", is_int section escaped.
<?php
$var=fgets(STDIN);
if(is_numeric($var))
{
//print "$var";
if(ctype_digit($var) || is_int($var)){
print "$var";
print "This type of input is Integer";
}
else{
//print "$var";
print "This type of input is Float";
}
}
else{
print "This type of input is String";
}
?>
From PHP MANUAL :
ctype_digit
Note:
This function expects a string to be useful, so for example passing in an integer may not return the expected result. However, also note that HTML forms will result in numeric strings and not integers. See also the types section of the manual.
is_int
Note:
To test if a variable is a number or a numeric string (such as form input, which is always a string), you must use is_numeric().
Use a filter like this filter_var($var, FILTER_VALIDATE_INT) for an integer evaluation.
<?php
$var = -10.12;
if(is_numeric($var))
{
//print "$var";
if(filter_var($var, FILTER_VALIDATE_INT)){
var_dump(filter_var($var, FILTER_VALIDATE_INT));
print "$var";
print "This type of input is Integer";
}
else{
//print "$var";
print "This type of input is Float";
}
}
else{
print "This type of input is String";
}
?>
ctype fails with negative numbers because minus ("-") is not considered to be part of the POSIX digit character class ([0-9.]). My PHP (5.3) fails with negative strings '-1' as well.
Despite what others have said, filter_vars() is not the appropriate solution. It may be workable, but the OP is testing primitive values, not trying to sanitize user input. He is also asking why ctype() doesn't work, and for a variable test that does. filter_vars() also does not work in other common php versions (< 5.2). Furthermore, his test can be performed without added function calls.
instead of:
if(ctype_digit($var) || is_int($var))
cast it.
foreach (array (-1, 0, 1,1.1,'1.1','1','abc','0','-1') as $test)
{
if (is_numeric($test))
{
if ((int) $test == $test) // <-- HERE
{ echo "int: $test\n"; }
else
{ echo "float: $test\n"; }
}
else
{ echo "string: $test\n"; }
}
/*
returns:
int: -1
int: 0
int: 1
float: 1.1
float: 1.1
int: 1
string: abc
int: 0
int: -1
*/
Note: The (int) will turn any non-integer string into "1", and == against the string will also cast the string to a 1, so for "abc", the (int) 'abc' == 'abc' will produce 1 == 1 . That means either the numeric string test will have to happen first or some other pure string test has to happen first.
Note2: It will fail with strings with spaces. e.g " 1 ". Perhaps add $var=is_string($var) ? trim($var) : $var;
$val represents 1,949.58 from my sql
$sold = 50;
if ($val>$sold){
echo "true";
}
else
{
echo "false";
}
I get false. somehow 50 is bigger than 1,949.58 and this because of the ',' sign. I need some advices on how to manage this right. Thx
$val is interpreted by php to be a string. When doing the comparison, it's doing a string compare so you aren't going to get the results you expect.
You need to force them to be a floating point type. Look at http://php.net/manual/en/function.floatval.php Specifically the comments on that function.
Something like this should work:
function floatvalue($value) {
return floatval(preg_replace('#^([-]*[0-9\.,\' ]+?)((\.|,){1}([0-9-]{1,2}))*$#e', "str_replace(array('.', ',', \"'\", ' '), '', '\\1') . '.\\4'", $value));
}
You need to convert these values to floats instead of strings. Right now you're doing string comparisons and not numerical comparisons. The following converts those strings to floating values.
$val = parseFloat('1,949.58'.replace(/\,/g,""))
$sold = parseFloat('50')
The .replace removes the "," from your original string before it's parsed to a Float.
I want to convert these types of values, '3', '2.34', '0.234343', etc. to a number. In JavaScript we can use Number(), but is there any similar method available in PHP?
Input Output
'2' 2
'2.34' 2.34
'0.3454545' 0.3454545
You don't typically need to do this, since PHP will coerce the type for you in most circumstances. For situations where you do want to explicitly convert the type, cast it:
$num = "3.14";
$int = (int)$num;
$float = (float)$num;
There are a few ways to do so:
Cast the strings to numeric primitive data types:
$num = (int) "10";
$num = (double) "10.12"; // same as (float) "10.12";
Perform math operations on the strings:
$num = "10" + 1;
$num = floor("10.1");
Use intval() or floatval():
$num = intval("10");
$num = floatval("10.1");
Use settype().
To avoid problems try intval($var). Some examples:
<?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 (octal as starts with zero)
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26 (hex as starts with 0x)
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
In whatever (loosely-typed) language you can always cast a string to a number by adding a zero to it.
However, there is very little sense in this as PHP will do it automatically at the time of using this variable, and it will be cast to a string anyway at the time of output.
Note that you may wish to keep dotted numbers as strings, because after casting to float it may be changed unpredictably, due to float numbers' nature.
Instead of having to choose whether to convert the string to int or float, you can simply add a 0 to it, and PHP will automatically convert the result to a numeric type.
// Being sure the string is actually a number
if (is_numeric($string))
$number = $string + 0;
else // Let the number be 0 if the string is not a number
$number = 0;
Yes, there is a similar method in PHP, but it is so little known that you will rarely hear about it. It is an arithmetic operator called "identity", as described here:
Aritmetic Operators
To convert a numeric string to a number, do as follows:
$a = +$a;
If you want get a float for $value = '0.4', but int for $value = '4', you can write:
$number = ($value == (int) $value) ? (int) $value : (float) $value;
It is little bit dirty, but it works.
You can use:
(int)(your value);
Or you can use:
intval(string)
In PHP you can use intval(string) or floatval(string) functions to convert strings to numbers.
You can always add zero to it!
Input Output
'2' + 0 2 (int)
'2.34' + 0 2.34 (float)
'0.3454545' + 0 0.3454545 (float)
Just a little note to the answers that can be useful and safer in some cases.
You may want to check if the string actually contains a valid numeric value first and only then convert it to a numeric type (for example if you have to manipulate data coming from a db that converts ints to strings). You can use is_numeric() and then floatval():
$a = "whatever"; // any variable
if (is_numeric($a))
var_dump(floatval($a)); // type is float
else
var_dump($a); // any type
Here is the function that achieves what you are looking for. First we check if the value can be understood as a number, if so we turn it into an int and a float. If the int and float are the same (e.g., 5 == 5.0) then we return the int value. If the int and float are not the same (e.g., 5 != 5.3) then we assume you need the precision of the float and return that value. If the value isn't numeric we throw a warning and return null.
function toNumber($val) {
if (is_numeric($val)) {
$int = (int)$val;
$float = (float)$val;
$val = ($int == $float) ? $int : $float;
return $val;
} else {
trigger_error("Cannot cast $val to a number", E_USER_WARNING);
return null;
}
}
If you want the numerical value of a string and you don't want to convert it to float/int because you're not sure, this trick will convert it to the proper type:
function get_numeric($val) {
if (is_numeric($val)) {
return $val + 0;
}
return 0;
}
Example:
<?php
get_numeric('3'); // int(3)
get_numeric('1.2'); // float(1.2)
get_numeric('3.0'); // float(3)
?>
Source: https://www.php.net/manual/en/function.is-numeric.php#107326
I've been reading through answers and didn't see anybody mention the biggest caveat in PHP's number conversion.
The most upvoted answer suggests doing the following:
$str = "3.14"
$intstr = (int)$str // now it's a number equal to 3
That's brilliant. PHP does direct casting. But what if we did the following?
$str = "3.14is_trash"
$intstr = (int)$str
Does PHP consider such conversions valid?
Apparently yes.
PHP reads the string until it finds first non-numerical character for the required type. Meaning that for integers, numerical characters are [0-9]. As a result, it reads 3, since it's in [0-9] character range, it continues reading. Reads . and stops there since it's not in [0-9] range.
Same would happen if you were to cast to float or double. PHP would read 3, then ., then 1, then 4, and would stop at i since it's not valid float numeric character.
As a result, "million" >= 1000000 evaluates to false, but "1000000million" >= 1000000 evaluates to true.
See also:
https://www.php.net/manual/en/language.operators.comparison.php how conversions are done while comparing
https://www.php.net/manual/en/language.types.string.php#language.types.string.conversion how strings are converted to respective numbers
In addition to Boykodev's answer I suggest this:
Input Output
'2' * 1 2 (int)
'2.34' * 1 2.34 (float)
'0.3454545' * 1 0.3454545 (float)
Only multiply the number by 1 so that the string is converted to type number.
//String value
$string = "5.1"
if(is_numeric($string)){
$numeric_string = $string*1;
}
Alright so I just ran into this issue. My problem is that the numbers/strings in question having varying numbers of digits. Some have no decimals, others have several. So for me, using int, float, double, intval, or floatval all gave me different results depending on the number.
So, simple solution... divide the string by 1 server-side. This forces it to a number and retains all digits while trimming unnecessary 0's. It's not pretty, but it works.
"your number string" / 1
Input Output
"17" 17
"84.874" 84.874
".00234" .00234
".123000" .123
"032" 32
Here is a function I wrote to simplify things for myself:
It also returns shorthand versions of boolean, integer, double and real.
function type($mixed, $parseNumeric = false)
{
if ($parseNumeric && is_numeric($mixed)) {
//Set type to relevant numeric format
$mixed += 0;
}
$t = gettype($mixed);
switch($t) {
case 'boolean': return 'bool'; //shorthand
case 'integer': return 'int'; //shorthand
case 'double': case 'real': return 'float'; //equivalent for all intents and purposes
default: return $t;
}
}
Calling type with parseNumeric set to true will convert numeric strings before checking type.
Thus:
type("5", true) will return int
type("3.7", true) will return float
type("500") will return string
Just be careful since this is a kind of false checking method and your actual variable will still be a string. You will need to convert the actual variable to the correct type if needed. I just needed it to check if the database should load an item id or alias, thus not having any unexpected effects since it will be parsed as string at run time anyway.
Edit
If you would like to detect if objects are functions add this case to the switch:
case 'object': return is_callable($mixed)?'function':'object';
$a = "10";
$b = (int)$a;
You can use this to convert a string to an int in PHP.
I've found that in JavaScript a simple way to convert a string to a number is to multiply it by 1. It resolves the concatenation problem, because the "+" symbol has multiple uses in JavaScript, while the "*" symbol is purely for mathematical multiplication.
Based on what I've seen here regarding PHP automatically being willing to interpret a digit-containing string as a number (and the comments about adding, since in PHP the "+" is purely for mathematical addition), this multiply trick works just fine for PHP, also.
I have tested it, and it does work... Although depending on how you acquired the string, you might want to apply the trim() function to it, before multiplying by 1.
Late to the party, but here is another approach:
function cast_to_number($input) {
if(is_float($input) || is_int($input)) {
return $input;
}
if(!is_string($input)) {
return false;
}
if(preg_match('/^-?\d+$/', $input)) {
return intval($input);
}
if(preg_match('/^-?\d+\.\d+$/', $input)) {
return floatval($input);
}
return false;
}
cast_to_number('123.45'); // (float) 123.45
cast_to_number('-123.45'); // (float) -123.45
cast_to_number('123'); // (int) 123
cast_to_number('-123'); // (int) -123
cast_to_number('foo 123 bar'); // false
function convert_to_number($number) {
return is_numeric($number) ? ($number + 0) : FALSE;
}
You can use:
((int) $var) ( but in big number it return 2147483647 :-) )
But the best solution is to use:
if (is_numeric($var))
$var = (isset($var)) ? $var : 0;
else
$var = 0;
Or
if (is_numeric($var))
$var = (trim($var) == '') ? 0 : $var;
else
$var = 0;
Simply you can write like this:
<?php
$data = ["1","2","3","4","5"];
echo json_encode($data, JSON_NUMERIC_CHECK);
?>
There is a way:
$value = json_decode(json_encode($value, JSON_NUMERIC_CHECK|JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_SLASHES), true);
Using is_* won't work, since the variable is a: string.
Using the combination of json_encode() and then json_decode() it's converted to it's "true" form. If it's a true string then it would output wrong.
$num = "Me";
$int = (int)$num;
$float = (float)$num;
var_dump($num, $int, $float);
Will output: string(2) "Me" int(0) float(0)
Now we are in an era where strict/strong typing has a greater sense of importance in PHP, I use json_decode:
$num = json_decode('123');
var_dump($num); // outputs int(123)
$num = json_decode('123.45');
var_dump($num); // outputs float(123.45)
You can change the data type as follows
$number = "1.234";
echo gettype ($number) . "\n"; //Returns string
settype($number , "float");
echo gettype ($number) . "\n"; //Returns float
For historical reasons "double" is returned in case of a float.
PHP Documentation
If you don't know in advance if you have a float or an integer,
and if the string may contain special characters (like space, €, etc),
and if it may contain more than 1 dot or comma,
you may use this function:
// This function strip spaces and other characters from a string and return a number.
// It works for integer and float.
// It expect decimal delimiter to be either a '.' or ','
// Note: everything after an eventual 2nd decimal delimiter will be removed.
function stringToNumber($string) {
// return 0 if the string contains no number at all or is not a string:
if (!is_string($string) || !preg_match('/\d/', $string)) {
return 0;
}
// Replace all ',' with '.':
$workingString = str_replace(',', '.', $string);
// Keep only number and '.':
$workingString = preg_replace("/[^0-9.]+/", "", $workingString);
// Split the integer part and the decimal part,
// (and eventually a third part if there are more
// than 1 decimal delimiter in the string):
$explodedString = explode('.', $workingString, 3);
if ($explodedString[0] === '') {
// No number was present before the first decimal delimiter,
// so we assume it was meant to be a 0:
$explodedString[0] = '0';
}
if (sizeof($explodedString) === 1) {
// No decimal delimiter was present in the string,
// create a string representing an integer:
$workingString = $explodedString[0];
} else {
// A decimal delimiter was present,
// create a string representing a float:
$workingString = $explodedString[0] . '.' . $explodedString[1];
}
// Create a number from this now non-ambiguous string:
$number = $workingString * 1;
return $number;
}
All suggestions lose the numeric type.
This seems to me a best practice:
function str2num($s){
// Returns a num or FALSE
$return_value = !is_numeric($s) ? false : (intval($s)==floatval($s)) ? intval($s) :floatval($s);
print "\nret=$return_value type=".gettype($return_value)."\n";
}
//Get Only number from string
$string = "123 Hello Zahid";
$res = preg_replace("/[^0-9]/", "", $string);
echo $res."<br>";
//Result 123
Why does is_int always return false in the following situation?
echo $_GET['id']; //3
if(is_int($_GET['id']))
echo 'int'; //not executed
Why does is_int always return false?
Because $_GET["id"] is a string, even if it happens to contain a number.
Your options:
Use the filter extension. filter_input(INPUT_GET, "id", FILTER_VALIDATE_INT) will return an integer typed variable if the variable exists, is not an array, represents an integer and that integer is within the valid bounds. Otherwise it will return false.
Force cast it to integer (int)$_GET["id"] - probably not what you want because you can't properly handle errors (i.e. "id" not being a number)
Use ctype_digit() to make sure the string consists only of numbers, and therefore is an integer - technically, this returns true also with very large numbers that are beyond int's scope, but I doubt this will be a problem. However, note that this method will not recognize negative numbers.
Do not use:
is_numeric() because it will also recognize float values (1.23132)
Because HTTP variables are always either strings, or arrays. And the elements of arrays are always strings or arrays.
You want the is_numeric function, which will return true for "4". Either that, or cast the variable to an int $foo = (int) $_GET['id']...
Checking for integers using is_int($value) will return false for strings.
Casting the value -- is_int((int) $value) -- won't help because strings and floats will result in false positive.
is_numeric($value) will reject non numeric strings, but floats still pass.
But the thing is, a float cast to integer won't equal itself if it's not an integer. So I came up with something like this:
$isInt = (is_numeric($value) && (int) $value == $value);
It works fine for integers and strings ... and some floating numbers.
But unfortunately, this will not work for some float integers.
$number = pow(125, 1/3); // float(5) -- cube root of 125
var_dump((int) $number == $number); // bool(false)
But that's a whole different question.
How i fixed it:
$int_id = (int) $_GET["id"];
if((string)$int_id == $_GET["id"]) {
echo $_GET["id"];
}
It's probably stored as a string in the $_GET, cast it to an int.
Because $_GET is an array of strings.
To check if the get parameter contains an integer you should use is_numeric()
Because $_GET['id'] is a string like other parts of query string. You are not converting it to integer anywhere so is_int return false.
The dirty solution I'm using is this:
$val = trim($_GET['id']);
$cnd = ($val == (int)$val);
echo $cnd ? "It's an int" : "Not an int";
Apart from the obvious (ugly code that hides its workings behind specifics of the php engine), does anybody know cases where this goes wrong?
Prabably best way to check if value from GET or POST is integer is check by preg_match
if( preg_match('/^[0-9]+$/', $_GET['id'] ){
echo "is int";
}
You can possibly try the intval() which can be used to test the value of your var. e.g
If(intval($_GET['ID']==0)
The function will check if the var is integer and return TRUE if not FALSE