PHP est numérique ou preg match 0-9 validation

ce n'est pas un gros problème pour moi (pour autant que je sache), c'est plutôt quelque chose qui m'intéresse. Mais quelle est la principale différence, le cas échéant, d'utiliser is_numeric sur preg_match (ou vice versa) pour valider les valeurs d'entrée de l'utilisateur.

Exemple Un:

<?php
    $id = $_GET['id'];
    if (!preg_match('/^[0-9]*$/', $id)) {
        // Error
    } else {
        // Continue
    }
?>

Exemple Deux:

<?php
    $id = $_GET['id'];
    if (!is_numeric($id)) {
        // Error
    } else {
        // Continue
    }
?>

je suppose que les deux font exactement la même chose, mais y a-t-il des différences spécifiques qui pourraient causer des problèmes plus tard? Être il y a un "meilleur moyen" ou quelque chose que je ne vois pas qui les rend différents.

31
demandé sur Bas Slagter 2011-10-04 18:48:50

11 réponses

is_numeric() test si une valeur est un nombre. Il ne doit pas nécessairement être un entier bien qu'il pourrait un nombre décimal ou un nombre en notation scientifique.

l'exemple preg_match() que vous avez donné vérifie seulement qu'une valeur contient les chiffres zéro à neuf; n'importe quel nombre d'entre eux, et dans n'importe quelle séquence.

notez que l'expression régulière que vous avez donnée n'est pas non plus un vérificateur d'entiers parfait, comme vous l'avez écrit. Il n'a pas tenir compte des négatifs; tenir compte d'une chaîne de longueur zéro (c'est-à-dire sans aucun chiffre, ce qui ne devrait probablement pas être valide?), et il permet au nombre d'avoir n'importe quel nombre de zéros de tête, qui encore une fois peut ne pas être l'intention.

[EDIT]

selon votre commentaire, une meilleure expression régulière pourrait ressembler à ceci:

/^[1-9][0-9]*$/

cela force le premier chiffre à être seulement entre 1 et 9, donc vous ne pouvez pas avoir de zéros de tête. Il a également oblige à être au moins un chiffre longs, ce qui résout la chaîne de longueur zéro problème.

vous n'êtes pas inquiet pour les négatifs, donc ce n'est pas un problème.

vous pourriez vouloir restreindre le nombre de chiffres, parce que dans l'état des choses, il permettra aux chaînes qui sont trop grandes d'être stockées comme entiers. Pour restreindre ceci, vous changeriez l'étoile en une restriction de longueur comme ceci:

/^[1-9][0-9]{0,15}$/

cela permettrait à la chaîne d'être entre 1 et 16 caractères de long (c'est à dire le premier chiffre plus 0-15 autres chiffres). N'hésitez pas à ajuster les nombres entre accolades pour l'adapter à vos propres besoins. Si vous voulez une chaîne de longueur fixe, alors vous avez seulement besoin de spécifier un numéro dans les accolades.

Espère que ça aide.

57
répondu Spudley 2011-10-04 15:04:40

Selon http://www.php.net/manual/en/function.is-numeric.php , is_numeric s'installe quelque chose comme "+0123.45e6" ou "0xFF". Je pense que ce pas ce que vous attendez.

preg_match peut être lent, et vous pouvez avoir quelque chose comme 0000 ou 0051.

je préfère utiliser ctype_digit (fonctionne seulement avec les chaînes, c'est ok avec $_GET).

<?php
  $id = $_GET['id'];
  if (ctype_digit($id)) {
      echo 'ok';
  } else {
      echo 'nok';
  }
?>
10
répondu rap-2-h 2011-10-04 14:57:50

is_numeric () permet n'importe quelle forme de nombre. donc 1 , 3.14159265 , 2.71828e10 sont tous "numériques", alors que votre regex descend à l'équivalent de is_int()

7
répondu Marc B 2011-10-04 14:51:56

is_numeric accepterait "-0.5 e+12" comme ID valide.

5
répondu user187291 2011-10-04 14:51:07

pas exactement le même.

des Docs PHP d'is_numeric:

'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric

avec votre regex vous ne vérifiez que les valeurs numériques "de base".

aussi is_numeric() devrait être plus rapide.

5
répondu PeeHaa 2011-10-04 14:51:33

is_numeric vérifie s'il s'agit d'un nombre quelconque, tandis que votre regex vérifie s'il s'agit d'un entier, éventuellement avec des 0. Pour un id, stocké comme un entier, il est tout à fait probable que nous ne voulons pas avoir les 0 principaux. Suite à la réponse de Spudley, nous pouvons faire:

/^[1-9][0-9]*$/

cependant, comme le note Spudley, la chaîne résultante peut être trop grande pour être stockée comme une valeur entière de 32 ou 64 bits. La valeur maximale d'un entier 32 bits signé est 2,147,483,647 (10 chiffres), et la valeur maximale d'un entier 64 bits signé est de 9.223.372.036.854.775.807 (19 chiffres). Cependant, de nombreux entiers de 10 et 19 chiffres sont plus grands que les entiers 32 bits et 64 bits respectivement. Une solution simple de regex-seulement serait:

/^[1-9][0-9]{0-8}$/ 

ou

/^[1-9][0-9]{0-17}$/

respectivement, mais ces" solutions " restreignent malheureusement chacun à des entiers de 9 et 19 chiffres; à peine un résultat satisfaisant. Une meilleure solution pourrait être quelque chose comme:

$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
    echo 'ok';
} else {
    echo 'nok';
}
5
répondu Jacob Lee 2013-10-30 13:28:49

is_numeric contrôles de plus:

trouve si la variable donnée est numérique. Les chaînes numériques consistent du signe facultatif, de tout nombre de chiffres, de la partie décimale facultative et partie exponentielle optionnelle. + 0123.45e6 est une valeur numérique valide. La notation hexadécimale (0xFF) est autorisée aussi mais seulement sans signe, partie décimale et exponentielle.

3
répondu MasterCassim 2011-10-04 14:52:00

Si vous êtes seulement vérifier si c'est un nombre, is_numeric() est beaucoup plus beaucoup mieux ici. C'est plus lisible et un peu plus rapide que regex.

le problème avec votre regex ici est qu'il ne permettra pas de valeurs décimales, donc essentiellement vous avez juste écrit is_int() dans regex. Les expressions régulières ne doivent être utilisées que lorsqu'il y a un format de données non standard dans votre entrée; PHP a beaucoup de fonctions de validation intégrées, même un validateur email sans regex .

1
répondu Bojangles 2011-10-04 14:51:05
La fonction

de PHP is_numeric permet des flotteurs aussi bien que des entiers. En même temps, la fonction is_int est trop stricte si vous voulez valider les données du formulaire (chaînes uniquement). Par conséquent, vous avez généralement mieux utiliser des expressions régulières pour cela.

à proprement parler, les nombres entiers sont des nombres entiers positifs et négatifs, et aussi, y compris zéro. Voici une expression régulière:

/^0$|^[-]?[1-9][0-9]*$/

OU, si vous souhaitez autoriser les zéros non significatifs:

/ ^[ -]?[0] |[1-9][0-9] $/

notez que cela permettra des valeurs telles que -0000, ce qui ne cause pas de problèmes en PHP, cependant. (MySQL va aussi lancer des valeurs comme 0.)

vous pouvez également vouloir limiter la longueur de votre entier pour des considérations de Les caractéristiques de la plate-forme PHP 32/64-bit et/ou la compatibilité de base de données. Par exemple, pour limiter la longueur de votre entier à 9 chiffres (à l'exclusion du signe - optionnel), vous pouvez utiliser:

/^0$|^[-]?[1-9][0-9]{0,8}$/

1
répondu mixabo 2017-05-23 11:54:44

pendant ce temps, Toutes les valeurs ci-dessus ne restreindront les valeurs qu'à un nombre entier, donc j'utilise

/^[1-9][0-9\.]{0,15}$/

pour permettre des valeurs de flottaison aussi.

0
répondu tormuto 2015-03-24 08:47:44

vous pouvez utiliser ce code pour la validation du numéro:

if (!preg_match("/^[0-9]+$/i", $phone)) {
        $errorMSG = 'Invalid Number!';
        $error    = 1;
    }
0
répondu vicky mahale 2017-11-14 12:42:03