Best way to check for positive integer (PHP)?

前端 未结 20 2195
心在旅途
心在旅途 2020-12-02 18:34

I need to check for a form input value to be a positive integer (not just an integer), and I noticed another snippet using the code below:

$i = $user_input_v         


        
相关标签:
20条回答
  • 2020-12-02 18:52

    The best way for checking for positive integers when the variable can be INTEGER or STRING representing the integer:

     if ((is_int($value) || ctype_digit($value)) && (int)$value > 0 ) { // int }
    

    is_int() will return true if the value type is integer. ctype_digit() will return true if the type is string but the value of the string is an integer.

    The difference between this check and is_numeric() is that is_numeric() will return true even for the values that represent numbers that are not integers (e.g. "+0.123").

    0 讨论(0)
  • 2020-12-02 18:54

    Definition:

    !A = !is_numeric($i)
    B = $i < 1
    !C = $i != round($i)
    

    Then...

    !is_numeric($i) || $i < 1 || $i != round($i) is equal to !A || B || !C

    So:

    !A || B || !C = !A || !C || B
    

    Now, using the deMorgan theorem, i.e. (!A || !C) = (A && C), then:

    !A || !C || B = (A && C) || B
    

    Now, note that A && C = is_numeric($i) && $i == round($i), but if $i == round($i) is TRUE, then is_numeric($i) is TRUE as well, so we can simplify A && C = C so,

    (A && C) || B = C || B =

    $i == round($i) || $i < 1
    

    So you just need to use:

    $i = $user_input_value;
    if ($i == round($i) || $i < 1) {
      return TRUE;
    }
    
    0 讨论(0)
  • 2020-12-02 18:55
    if(isset($i) && is_int($i) && $i >= 0){ //0 is technically a postive integer I suppose
        return TRUE; //or FALSE I think in your case.
    }
    
    0 讨论(0)
  • 2020-12-02 18:56

    It's definitely heading towards the land of micro-optimisation, but hey: the code I'm working on chews through millions of items every day and it's Friday. So I did a little bit of experimenting...

    for ($i = 0; $i < 1000000; $i++) {
        // Option 1: simple casting/equivalence testing
        if ((int) $value == $value && $value > 0) { ... }
    
        // Option 2: using is_int() and ctype_digit().  Note that ctype_digit implicitly rejects negative values!
        if ((is_int($value) && $value > 0) || ctype_digit($value)) { ... }
    
        // Option 3: regular expressions
        if (preg_match('/^\d+$/', $value)) { ... }
    }
    

    I then ran the above tests for both integer and string values

    Option 1: simple casting/equivalence testing

    • Integer: 0.3s
    • String: 0.4s

    Option 2: using is_int() and ctype_digit()

    • Integer: 0.9s
    • String: 1.45s

    Option 3: regular expressions

    • Integer: 1.83s
    • String: 1.60s

    Perhaps unsurprisingly, option 1 is by far the quickest, since there's no function calls, just casting. It's also worth noting that unlike the other methods, option 1 treats the string-float-integer value "5.0" as an integer:

    $valList = array(5, '5', '5.0', -5, '-5', 'fred');
    foreach ($valList as $value) {
        if ((int) $value == $value && $value > 0) {
            print "Yes: " . var_export($value, true) . " is a positive integer\n";
        } else {
            print "No: " . var_export($value, true) . " is not a positive integer\n";
        }
    }
    
    Yes: 5 is a positive integer
    Yes: '5' is a positive integer
    Yes: '5.0' is a positive integer
    No: -5 is not a positive integer
    No: '-5' is not a positive integer
    No: 'fred' is not a positive integer
    

    Whether or not that's a good thing for your particular use-case is left as an exercise for the reader...

    0 讨论(0)
  • 2020-12-02 18:57

    You don't really need to use all three check and if you want a positive integer you might want to do the opposite of what is in your code:

    if(is_numeric($i) && $i >= 0) { return true; }
    

    Check Sören's answer for more information concerning the difference between is_int() and is_numeric()

    0 讨论(0)
  • 2020-12-02 18:57

    Ok, I know this thread is really old but I share @Jeffrey Vdovjak's opinion: since I was able to find it, it might still help someone else out there.

    php's gmp_sign() might be another easy way to check. It works for integer and numeric strings, and returns 1 if a is positive, -1 if a is negative, and 0 if a is zero.

    So:

    // positive
    echo gmp_sign("500") . "\n";
    
    // negative
    echo gmp_sign("-500") . "\n";
    
    // zero
    echo gmp_sign("0") . "\n";
    

    will output:

    1
    -1
    0
    

    See function manual at http://php.net/manual/en/function.gmp-sign.php

    P.S. You'll need to have php_gmp.dll enabled in your .ini file.

    0 讨论(0)
提交回复
热议问题