web-dev-qa-db-fra.com

Le meilleur moyen de vérifier un entier positif (PHP)?

Je dois vérifier qu'une valeur d'entrée de formulaire est un entier positif (pas seulement un entier) et j'ai remarqué un autre extrait utilisant le code ci-dessous:

$i = $user_input_value;
if (!is_numeric($i) || $i < 1 || $i != round($i)) {
  return TRUE;
}

Je me demandais s'il y avait un avantage à utiliser les trois vérifications ci-dessus, au lieu de faire quelque chose comme ceci:

$i = $user_input_value;
if (!is_int($i) && $i < 1) {
  return TRUE;
}
36
geerlingguy

la différence entre vos deux extraits de code est que is_numeric($i) renvoie également true si $ i est une chaîne numérique, mais is_int($i) ne renvoie true que si $ i est un entier et non si $ i est une chaîne entière. C'est pourquoi vous devez utiliser le premier extrait de code si vous souhaitez également renvoyer true si $ i est une chaîne entier (par exemple, si $ i == "19" et non pas $ i == 19).

Voir ces références pour plus d'informations:

php is_numeric function

php is_int function

31
Sören

Vous ne savez pas pourquoi il n'est pas suggéré d'utiliser filter_var à ce sujet. Je sais que c'est un vieux fil, mais peut-être que ça va aider quelqu'un (après tout, je me suis retrouvé ici, non?).

$filter_options = array( 
    'options' => array( 'min_range' => 0) 
);


if( filter_var( $i, FILTER_VALIDATE_INT, $filter_options ) !== FALSE) {
   ...
}

Vous pouvez également ajouter une valeur maximale.

$filter_options = array(
    'options' => array( 'min_range' => 0,
                        'max_range' => 100 )
);

http://php.net/manual/en/function.filter-var.php

http://www.php.net/manual/en/filter.filters.validate.php

31
Jeffrey Vdovjak

Le meilleur moyen de vérifier les entiers positifs lorsque la variable peut être INTEGER ou STRING représentant l’entier:

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

is_int() retournera true si le type de valeur est integer. ctype_digit() retournera true si le type est string mais que la valeur de la chaîne est un entier.

La différence entre cette vérification et is_numeric() est que is_numeric() retournera vrai même pour les valeurs qui représentent des nombres qui ne sont pas des entiers (par exemple "+0.123").

14
Christian P

Il se dirige définitivement vers le pays de la micro-optimisation, mais bon: le code sur lequel je travaille mâche des millions d'articles chaque jour et c'est vendredi. Alors j'ai fait un peu d'expérimentation ...

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)) { ... }
}

J'ai ensuite exécuté les tests ci-dessus pour les valeurs entières et chaînes.

Option 1: coulée simple/test d'équivalence

  • Entier: 0.3s
  • String: 0.4s

Option 2: utiliser is_int () et ctype_digit ()

  • Entier: 0.9s
  • Chaîne: 1.45s

Option 3: expressions régulières

  • Entier: 1.83s
  • Chaîne: 1.60s

Peut-être sans surprise, l'option 1 est de loin la plus rapide, car il n'y a pas d'appel de fonction, il suffit de lancer. Il convient également de noter que, contrairement aux autres méthodes, l'option 1 traite la valeur "5.0" de string-float-integer comme un entier:

$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

Que ce soit ou non une bonne chose pour votre cas d'utilisation particulier reste un exercice pour le lecteur ...

11
Jamie Mann

L'autre meilleur moyen de vérifier un nombre entier est d'utiliser une expression régulière. Vous pouvez utiliser le code suivant pour vérifier la valeur Integer. Il sera faux pour les valeurs flottantes.

if(preg_match('/^\d+$/',$i)) {
  // valid input.
} else {
  // invalid input.
}

Mieux vaut vérifier si $ i> 0 aussi.

5
Harsha

Plutôt que de rechercher int OR string avec plusieurs conditions telles que:

if ( ctype_digit($i) || ( is_int($i) && $i > 0 ) )
{
    return TRUE;
}

vous pouvez simplifier ceci en saisissant simplement (string) de sorte que l'appel ctype_digit vérifie les deux entrées string et int:

if( ctype_digit( (string)$i ) )
{
    return TRUE;
}
2
WebChemist

Définition:

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

Ensuite...

! is_numeric ($ i) || $ i <1 || $ i! = rond ($ i)  est égal à ! A || B || ! C

Alors:

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

Maintenant, en utilisant le théorème deMorgan, c'est-à-dire (! A ||! C) = (A && C), alors: 

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

Notez maintenant que A && C = is_numeric ($ i) && $ i == round ($ i), mais si $ i == round ($ i) est VRAI, alors is_numeric ($ i) est VRAI également, nous pouvons simplifier A && C = C,

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

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

Donc, il vous suffit d'utiliser:

$i = $user_input_value;
if ($i == round($i) || $i < 1) {
  return TRUE;
}
2
Miguel A. Carrasco

Laravel 4.2 Règle de validation pour le nombre positif

Il ne prend que des nombres positifs, y compris des valeurs flottantes.

public static $rules = array(
    'field_name' => 'required|regex:/^\d*\.?\d*$/'
);

par exemple: 20,2.6,06

2
user1895505

En plus de toutes les autres réponses: Vous recherchez probablement ctype_digit . Il recherche une chaîne contenant uniquement des chiffres.

2
NikiC

Pour vérifier l’utilisation d’un nombre entier positif, procédez comme suit: 

$i = $user_input_value;
if (is_int($i) && $i > 0) {
  return true; //or any other instructions 
}

OR

$i = $user_input_value;
if (!is_int($i) || $i < 1) {
  return false; //or any other instructions 
}

Utilisez celui qui correspond à votre objectif car ils sont les mêmes. Les exemples suivants montrent la différence entre is_numeric() et is_int():

is_numeric(0);     // returns true
is_numeric(7);     // returns true
is_numeric(-7);    // returns true
is_numeric(7.2);   // returns true
is_numeric("7");   // returns true
is_numeric("-7");  // returns true
is_numeric("7.2"); // returns true
is_numeric("abc"); // returns false

is_int(0);     // returns true
is_int(7);     // returns true
is_int(-7);    // returns true
is_int(7.2);   // returns false
is_int("7");   // returns false
is_int("-7");  // returns false
is_int("7.2"); // returns false
is_int("abc"); // returns false
1
Amr

Ok, je sais que ce fil est vraiment vieux, mais je partage l’avis de @Jeffrey Vdovjak: puisque j’ai pu le trouver, il pourrait toujours aider quelqu'un d’autre.

la fonction gmp_sign () de PHP peut être un autre moyen facile de vérifier. Il fonctionne pour les chaînes entières et numériques et renvoie 1 si a est positif, -1 si a est négatif et 0 si a est égal à zéro.

Alors:

// positive
echo gmp_sign("500") . "\n";

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

// zero
echo gmp_sign("0") . "\n";

affichera:

1
-1
0

Voir le manuel de fonctionnement à http://php.net/manual/en/function.gmp-sign.php

P.S. Php_gmp.dll doit être activé dans votre fichier .ini.

1
Ola

Le premier exemple utilise round pour vérifier que l'entrée est un entier et non une valeur numérique différente (c'est-à-dire: une décimale). 

is_int retournera false si une chaîne est passée. Voir les exemples de manuel PHP pour is_int

1
nybbler

Vous n'avez pas vraiment besoin d'utiliser les trois vérifications et si vous voulez un entier positif, vous voudrez peut-être faire l'inverse de ce qui est dans votre code:

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

Vérifiez la réponse de Sören pour plus d’informations sur la différence entre is_int() et is_numeric()

1
JeroenEijkhof
    preg_match('{^[0-9]*$}',$string))

et si vous voulez limiter la longueur:

    preg_match('{^[0-9]{1,3}$}',$string)) //minimum of 1 max of 3

Si int intacte avec une longueur maximale de 6:

    if(preg_match('{^[0-9]{1,6}$}',$string)) && $string >= 0)
1
SuperSpy

Toutes ces réponses négligent le fait que le demandeur peut vérifier la saisie du formulaire.
La fonction is_int () échouera car l'entrée de formulaire est une chaîne.
is_numeric () sera également vrai pour les nombres flottants.
C’est pourquoi le tour $ i == ($ i) entre car il vérifie que l’entrée est un nombre entier.

1
Han Koster
if(preg_match('/^[1-9]\d*$/',$i)) {
   //Positive and > 0
}
1
Mirko Pagliai

Je ferais quelque chose comme ça:

if ((int) $i > 0) {
    // this number is positive
}

Le nombre est transtypé en nombre positif ou négatif en fonction du signe moins à l'avant. Ensuite, compare le nombre de transtypage à supérieur à 0 pour déterminer si le nombre est positif.

0
Ozzy

Ceci est ma solution, espérons utile:

if (is_numeric($i) && (intval($i) == floatval($i)) && intval($i) > 0)
   echo "positive integer";

je vérifie si la chaîne est numérique, deuxième vérification pour s'assurer qu'il est entier et troisième pour s'assurer que positif

0
Tín Tử Tế

Si vous utilisez "is_int", la variable doit être un entier, il ne peut donc s'agir d'une valeur float. (pas de tour nécessaire). 

0
ipsum
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
Matt Asbury