So this function is not intimidated by super-big numbers. I hope this helps someone.

PS: Also note that if you write is_numeric (45thg), this will generate a parse error (since the parameter is not enclosed between apostrophes or double quotes). Keep this in mind when you use this function.

Hi !Many of you may have experienced that the 'is_numeric' function seems to fail always when form entries are checked against their variable type. So the function seems to return 'false' even if the form entry was aparently a number or numeric string.

The solution is pretty simple and no subroutines or fancy operations are necessary to make the 'is_numeric' function usable for form entry checks:

Simply strip off all (invisible) characters that may be sent along with the value when submitting a form entry.

The documentation does not clarify what happens if you the input is an empty string - it correctly returns false in my experience. Useful to state these odd cases, for when you see code that checks for an empty string and is_numeric, you can tell it's a waste of a comparison.

The documentation is not completely precise here. is_numeric will also return true if the number begins with a decimal point and/or a space, provided a number follows (rather than a letter or punctuation). So, it doesn't necessarily have to start with a digit.

- set_locale() does not exist, you must use setlocale() instead- you have to enclose 12,25 with quotes; otherwise PHP will think that the function gets _two_ arguments: 12 and 25 (depending on PHP version and setup you may additionally get a PHP warning)- if you don't enclose 12,25 with quotes the first argument will be the inspected value (12), the second value (25) is discarded. And is_numeric(12) and is_float(12) is always TRUE

Remarks:- is_float(12.25) is _always_ TRUE, 12.25 is a PHP language construct (a "value") and the way PHP interpretes files is definitely _not_ affected by the locale- is_float("12,25") is _always_ FALSE, since is_float (other than is_numeric): if the argument is a string then is_float() always returns FALSE since it does a strict check for floats

And the corrected example shows: you get the _same_ results for every possible locale, is_numeric() does not depend on the locale.

This will not match strings like -6,77.8,8 which are matched by the below expression, and instead requires a single decimal point, with at least one character following, and only permits comma-separation when the right hand side is a triplet.

When using the exec() function in php to execute anther php script, any command line arguments passed the script will lose their type association, regardless of whether they are numeric or not, the same seems to hold true for strings as well.

ie : two scripts test.php:

<?php$val = trim($argv[1]);echo is_string($val);?>

and testwrapper.php:

<?php$tmp = 5;exec("php ./test.php ".$tmp);?>

Executing testwrapper.php on the command line will echo nothing (ie false), and false will be returned regardless of any escaping of parameters or other such attempts to overcome this. The solution then is to explicitly cast $val in test.php to be an int and then is_numeric will work. But as stated the same test was performed using a string for $val and the is_string() function and the same thing occurs. Not the end of the world, but something to be aware of :)

Note that this function is not appropriate to check if "is_numeric" for very long strings. In fact, everything passed to this function is converted to long and then to a double. Anything greater than approximately 1.8e308 is too large for a double, so it becomes infinity, i.e. FALSE. What that means is that, for each string with more than 308 characters, is_numeric() will return FALSE, even if all chars are digits.

Maybe your function was more strickt, but profides FALSE to any numeric string that wasnt written in the English/American notition. To enable a person to use the both the English/American and the rest of the world's way:

Other than that, i'd recommend using yours, if it works (i havent tested either yours or mine)By using mine, there might be a slight chance to not being able to do calculations with the numeric string if it's not the English/American way.

(*Note: -the E/A way of writing 1 million (with decimal for 1/50): 1,000,000.02-the global way of writing 1 million (with decimal for 1/50): 1.000.000,02

// if input just so happens to be a string, we check to make sure it // still holds a numeric value and only acquire the last 2 numbers. // if it's not a string, nor an integer, we freak out and say no.if(!is_int($o)) if(ctype_digit($o))$o=(int)substr($o,-2,2); else return(false);

// basically, if $o is between 11 and 19, we use 'th' // otherwise we use the last digit and if it's over // 4 then we use 0 (for the $s array index).return($i.$s[($o%100>10&&$o%100<20)?0:($o%10<4?$o%10:0)]);}

ordinal('-1'); returns false because ctype_digit hates anything that isn't strictly 0 through 9 and '-' trips it to false.

ordinal('asdf'); returns false for the exact same reason.

ordinal(); returns false because it's blank.

signed integers on a 32-bit system (and the same issue on a 64-bit system using 0x7FFFFFFFFFFFFFFF because of two's compliment, anything higher will become a negative number): ordinal(0x7FFFFFFF ); returns 2147483647th (which is correct) ordinal(0x7FFFFFFF+1); returns false.*/

if speed is important, the liberal use of regex should be avoided, especially complex ones like those here.

For most purposes, this will be sufficient and has the advantages of both speed and clarity.

$BoolResult = empty(trim($Test, '+-.,0123456789'));

If the $Test contains any character that is not a valid part of a number the remaining string will not be empty.

if you want to be more restrictive of the '+-' then you can use a separate trim for that and nest it. Keep in mind that some notations pt the sign to the right of the number instead of to the left. Depending upon your specific application you can also choose to ignore spaces and allow for 'e' notation.

I also use this approach when testing for other character sets such as Hex.

regarding the global vs. american numeral notations, it should be noted that at least in japanese, numbers aren't grouped with an extra symbol every three digits, but rather every four digits (for example 1,0000 instead of 10.000). also nadim's regexen are slightly suboptimal at one point having an unescaped '.' operator, and the whole thing could easily be combined into a single regex (speed and all).

i'm sure this still isn't optimal, but it should also cover japanese-style numerals and it fixed a couple of other issues with the other regexen. it also allows for an exponent suffix, the pre-decimal digits are optional and it enforces using either grouped or ungrouped integer parts. should be easier to trim to your liking too.

Be careful when using is_numeric() to escape SQL strings. is_numeric('0123') returns true but 0123 without quotes cannot be inserted into SQL. PHP interprets 0123 without quotes as a literal octal number; but SQL just throws a syntax error.

Casting a value to float then string and comparing it to the original value cast as string as the same effect as is_numeric but returns false for numeric strings that begin with zero and have no decimal point. Examples:<?phpfunction isDecimalNumber($n) { return (string)(float)$n === (string)$n;}

Regarding renimar at yahoo's function to yield ordinal numbers, the function lacks one thing. It accounts for numbers in the teens only if the number is below 100. If you used this function and gave 212 as the input, it would give 212nd, and not 212th. (Also, checking for numbers between 11 and 13 is sufficient, since 14-19 yield th either way.)

Miero: Your function doesn't match some special cases: '+1', '-0', '+0', all of which are valid integers. The easiest and most reliable way to get a definite integer match is with a regular expression: