1

I have the following PHP:

 <?php

 $array = array("1","2","3");
 $only_integers === array_filter($array,'is_numeric'); // true

 if($only_integers == TRUE)
 {
 echo 'right';
 }

 ?>

For some reason it always returns nothing. I don't know what I'm doing wrong.

Thanks

Michael Samuel
  • 3,820
  • 12
  • 45
  • 85
  • 8
    === should be changed to = because you wants to assign the results – Matthew Purdon Feb 15 '13 at 15:37
  • this is the link i got the function from but i don't know what i'm doing wrong :( http://stackoverflow.com/questions/3559542/more-concise-way-to-check-to-see-if-an-array-contains-only-numbers-integers – Michael Samuel Feb 15 '13 at 15:46

6 Answers6

2

is_int checks the actual type of a variable, which is string in your case. Use is_numeric for numeric values regardless of variable type.

Note that the following values are all considered "numeric":

"1"
1 
1.5
"1.5"
"0xf"
"1e4"

i.e. any floats, integers or strings that would be valid representations of floats or integers.

Edit: Also, you might have misunderstood array_filter, it does not return true or false but a new array with all values for which the callback function returned true. if($only_integers) works nonetheless (after you fixed your assignment operator) because all non-empty arrays are considered "true-ish".

Edit 2: as @SDC pointed out, you should use ctype_digit if you only want to allow integers in decimal format.

Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111
  • 1
    while you're right about `is_int`, `is_numeric` really isn't that great as an alternative, because it returns true for a lot of values that you wouldn't necessarily want (hex, exponents, etc). You might want to use `ctype_digit()` instead. – SDC Feb 15 '13 at 15:39
  • It was unclear from the question, which values should be filtered. But `ctype_digit` is a good alternative for only integers in decimal format, thanks for adding it. – Fabian Schmengler Feb 15 '13 at 15:44
2

You have to compare the length of the original array to the length of the filtered array. The array_filter function returns an array with values matching the filter set to true.

http://php.net/array_filter

 if(count($only_integers) == count($array))  {
     echo 'right';
 } else {
     echo 'wrong';
 }
Matthew Purdon
  • 754
  • 11
  • 28
  • this would be a good method but i want to know what's wrong with the code...this is the link i got the function from http://stackoverflow.com/questions/3559542/more-concise-way-to-check-to-see-if-an-array-contains-only-numbers-integers – Michael Samuel Feb 15 '13 at 15:47
  • Amongst other things, you missed the `=== $array` part of the accepted answer there. – Fabian Schmengler Feb 15 '13 at 15:50
  • Your code isn't the same as that link at all. The link is looping over each value and as soon as it finds a non-numeric value returns false. It's a lot slower than using array_filter and count since the loop is not done in userland code. – Matthew Purdon Feb 15 '13 at 15:51
  • @MatthewPurdon not you, that was my answer to "this would be a good method but i want to know what's wrong with the code [...]" – Fabian Schmengler Feb 15 '13 at 16:01
1
  1. is_int() will return false for "1" because it's a string.
    I see you've edited the question now to use is_numeric() instead; this is also probably a bad idea, as it will return true for hex and exponent values, which you probably don't want (eg is_numeric("dead") will return true).
    I suggest using ctype_digit() instead.

  2. The triple-equal is being misused here. It is used for a comparison, not an assignment, so $only_integers will never be set. Use single-equal to set $only_integers.

  3. array_filter() doesn't return a true/false value; it returns the array, with the filtered values removed. This means that the subsequent check that $only_integers is true will not work.

  4. $only_integers == TRUE. This is okay, but you probably should have used the triple-equal here. But of course, we already know that $only_integers won't be true or false, it'll be an array, so actually we need to check whether it's got any elements in it. count() would do the trick here.

Here's what your code looks like, taking all that into account...

 $array = array("1","2","3");
 $only_integers = array_filter($array,'ctype_digit'); // true

 if(count($only_integers) > 0)
 {
     echo 'right';
 }
SDC
  • 14,192
  • 2
  • 35
  • 48
  • this is the link i got the function from but i don't know what i'm doing wrong :( http://stackoverflow.com/questions/3559542/more-concise-way-to-check-to-see-if-an-array-contains-only-numbers-integers – Michael Samuel Feb 15 '13 at 15:53
  • @MichaelSamuel - I can see the code you've taken, but you've taken it out of context, and the answer is not very helpfully written. The completed functions provided in the same answer would be better for you to crib from, but more importantly, if you're going to crib code from other people, make sure you take time to understand what it's doing and why rather than just copy+pasting, otherwise you'll really struggle. – SDC Feb 15 '13 at 15:57
  • this also doesn't work because if you try to change only one value like 2 or 3 with a letter it will echo right as the other 2 values are integers – Michael Samuel Feb 15 '13 at 16:00
  • Re the other answer not using `count()`: there are many ways of doing the same thing. To explain his code: In the `any()` function, he is comparing it with an empty array; if it equals an empty array, then we know that all the items were filtered; none of them matched, so the function can therefore return false. In the `all()` function, he is comparing it with the original input; if the filtered array is different from the original, then we know that at least one element has been filtered, so the function can return false. – SDC Feb 15 '13 at 16:01
  • Re my answer not matching: it wasn't clear from the question whether you were trying to do an `all()` type check or an `any()` type check. My answer is an `any()` check -- ie it gives success if any of the values are good. If you want `all()`, change the count()` check to `if($only_integers === $array)`, as per the answer on the other page. – SDC Feb 15 '13 at 16:04
  • +1 nice answer. Only (minor) problem I have with it, is that `array_filter()` has a time complexity of `O(n)` (as it will always check each element). But that is only relevant if the input arrays are expected to be large. Using some kind of loop, which you could break out of, as soon as you find a non-integer value, would offer better average-case complexity. – Decent Dabbler Feb 15 '13 at 16:17
  • @fireeyedboy - yep, there are many better ways of doing it if all you want to do is check that all values are integers. I was assuming he was going to use the filtered result subsequently which is why I kept the `array_filter`, but from his comments, that's clearly not what he's doing; he just wants a true/false response. – SDC Feb 15 '13 at 16:20
  • yup I need only a true/false answer...tried changing the code as you suggested but the problem now is when the integers are used as following array(1,2,3) without quotes it will resturn false no matter what...also you pointed there are better and faster ways to get only true/false response, can you please point to any?? thanks :) – Michael Samuel Feb 15 '13 at 16:26
  • @SDC On second thought, there's a few other problems with your answer. `is_numeric("dead")` will **not** return `true`. Only if it is prepended with `0x`. Also `ctype_digit()` will only check for integers (not other numeric values), and return 'valid' results if the argument is passed as a string. – Decent Dabbler Feb 15 '13 at 16:29
  • @fireeyedboy - you got me on the `dead`, although my point holds that `is_numeric` isn't a great function for checking that a string contains only decimal integers. Re `ctype_digit()`... well, I was under the impression his input was strings containing decimal digits, so `ctype_digit()` would be suitable. But in any case, I don't have time to help with this any more -- it's already taken waaaay too much time, especially as the original question he cribbed from contained a whole bunch of answers and explainations, several of which would be perfect for him. – SDC Feb 15 '13 at 16:37
0

change === with = it used to compare not for initialise a variable

<?php

 $array = array(1,2,3);
 $only_integers = array_filter($array,'is_int'); // true

 if($only_integers == TRUE)
 {
 echo 'right';
 }

?>
developer
  • 4,744
  • 7
  • 40
  • 55
  • +1 for the most obvious bug in the code, but there are still problems with this code that will prevent it from working. – SDC Feb 15 '13 at 15:42
  • `array_filter($array,'is_int');` no, not really! a float is considered to be a numeric value as well as a string like `"34"` therefore the `is_numeric` the author posted was right. – Shoe Feb 15 '13 at 15:42
  • changed to is_numeric but it still validates if i use letters...thanks :) – Michael Samuel Feb 15 '13 at 15:43
  • you better user `is_int` instead of `is_numberic` like the other question has mentioned :) – Dzung Nguyen Feb 17 '13 at 09:10
0

Do you try to run your code before posting ? I have this error :

Notice: Undefined variable: only_integers in ~/php/test.php on line 4
Notice: Undefined variable: only_integers in ~/php/test.php on line 6

Change === to = fixes the problem right away. You better learn how to use phplint and other tools to avoid typo mistake like this.

Dzung Nguyen
  • 9,152
  • 14
  • 65
  • 104
  • changed it but still not working...this is the link i got the function from but i don't know what i'm doing wrong :( http://stackoverflow.com/questions/3559542/more-concise-way-to-check-to-see-if-an-array-contains-only-numbers-integers – Michael Samuel Feb 15 '13 at 15:53
  • @MichaelSamuel take this file, it works for me. http://pastebin.com/271RvL2H What is the version of your PHP – Dzung Nguyen Feb 16 '13 at 10:32
  • if you change the array to ("1","2","a") for example it will still validate as true :) thanks – Michael Samuel Feb 16 '13 at 23:22
-1
<?php
$test1 = "1";
if (is_int($test1) == TRUE) {
    echo '$test1 is an integer';
}
$test2 = 1;
if (is_int($test2) == TRUE) {
    echo '$test2 is an integer';
}
?>

try this code and you'll understand why your code doesn't work.

Can Geliş
  • 1,454
  • 2
  • 10
  • 19