0

In my form, a team's score is input, validated by the PHP script and then passed to the MySQL database. However, I want to make sure that a positive integer is being submitted, so there are no problems on the back-end when league standings are tabulated.

Research led me to the conclusion that using is_numeric would be the best way to go about this. However, it fails to recognize zero as an integer and that presents a problem for me. When I echo it in an array by itself, it shows as true, but something about the way I've written it in the script is not working.

I tried converting the $_POST with intval first and then processing the number with is_numeric, but that doesn't seem to help. Here's the code:

// Validate the away score:
if (empty($_POST['away_score'])) {
    echo "You forgot to enter the away score.<br>";
    $validate = 'false';
} elseif (!is_numeric($_POST['away_score'])) {
    echo "You entered an invalid score for the away team.<br>";
    $validate = 'false';
} else {
    $away_score_value = mysqli_real_escape_string($db, trim($_POST['away_score']));
    $validate = 'true';
}

Any thoughts?

j08691
  • 204,283
  • 31
  • 260
  • 272
712Jefferson
  • 211
  • 2
  • 7
  • 17
  • `POST[$_'$away_score']`....? Is that just a really odd copy/paste error, or is that actually what's in your PHP script? – cHao Sep 06 '13 at 01:44
  • And why the `$` in the quotes? You don't have it on any of the others... – cHao Sep 06 '13 at 01:47
  • @cHao Sorry, that was just me being an idiot with my copy/paste. Fixed, but problem remains, unfortunately. – 712Jefferson Sep 06 '13 at 01:51

8 Answers8

2

The string '0' is not truthy. That means that anything that checks it in a boolean'ish manner will treat it as false. In particular, empty($_POST['away_score']) will evaluate to true, so is_numeric would never even get a chance to fail.

Short version: empty is too wishy-washy in this case. Check for null and '' explicitly.

if (!isset($_POST['away_score']) or $_POST['away_score'] == '') {
cHao
  • 84,970
  • 20
  • 145
  • 172
  • What happens when is a float like 4.2?..the op want to check a positive integer – Emilio Gort Sep 06 '13 at 02:09
  • 1
    @EmilioGort: At this point in the validation, nothing. You'd probably want to take the `intval()` of it and see if it's loosely-equal to the input, if it has to be an integer. – cHao Sep 06 '13 at 02:11
2

You could use built-in validation. Explore few examples from Validation examples. And read about filter_input.

For example.

var_dump(filter_input(INPUT_POST, 'score', FILTER_VALIDATE_INT, array(
    'options' => array(
        'min_range' => 1,
        'max_range' => 5,
    )
)));

P.S. use prepared statements.

sectus
  • 15,605
  • 5
  • 55
  • 97
1
<?php

try {

    // Check if user submitted "away_score" with valid form.
    // "away_score" can be UNDEFINED or STRING or ARRAY.
    if (!isset($_POST['away_score']) || !is_string($away_score = $_POST['away_score'])) {
        throw new RuntimeException('You cannot access without valid form submitting.');
    }
    // If "away_score" is not filled in, this will be EMPTY STRING.
    if ($away_score === '') {
        throw new RuntimeException('You forgot to enter the away score.');
    }
    // Check if trimmed "away_score" has only digits.
    if (!ctype_digit($away_score = trim($away_score))) {
        throw new RuntimeException('You entered an invalid score for the away team.');
    }

    // do something

} catch (Exception $e) {

    printf("<p>%s</p>\n", $e->getMessage());

}
mpyw
  • 5,526
  • 4
  • 30
  • 36
1
ctype_digit( (string) $score);

preg_match('#^\d+$#', $score);

In b4 @EmilioGort

boolean false

int 0
Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
1

Using regex

if (preg_match('/\A\d++\z/', $variable)){//including 0
 //do somthing
}else{
 echo "This is not a Positive Integer"
}

is_numeric(4.2) return true with float

is_int(2) return false if the data are obtained using supergloblals like $_POST or $_GET

Emilio Gort
  • 3,475
  • 3
  • 29
  • 44
  • `/\A\d++\z/` is a perfect regex for it. `$` may contains CRLF or LF. – mpyw Sep 06 '13 at 02:16
  • @CertaiN give me an example please? – Emilio Gort Sep 06 '13 at 02:20
  • 1
    http://ideone.com/fEwG6A But later `trim` he called, so this is not absolutely necessary, sorry.. – mpyw Sep 06 '13 at 02:25
  • 1
    And `\d++` is more efficient than `\d+`, because of no backtrack. `\d+` do backtrack on matching failure. Example: `1abcdef`; PCRE tries to check the follwing all cases. `1abcdef`->`1abcde`->`1abc`->`1ab`->`1a`->`1` – mpyw Sep 06 '13 at 02:32
1
} elseif (!preg_match('/^([0-9]+)$/', $_POST['away_score'], $m)) {
  $AwayScore = $m[1];  # $AwayScore to go to mysql
  echo 'not numeric!';
  $valid = false;
}

This just works!
preg_match() works for any type, including integer/long/float, anything!

1111161171159459134
  • 1,216
  • 2
  • 18
  • 28
0

But using is_numeric is the proper way of checking whether a given input is or not a number in PHP, and

var_dump(is_numeric(0));

should return bool(true). Have you tried is_int instead?

federico-t
  • 12,014
  • 19
  • 67
  • 111
0
elseif (!is_numeric(POST[$_'$away_score']) && !is_null(POST[$_'$away_score']))

Because 0 (or null) is not a numeric value, you have to check if the score isn't null.