2011-01-30 15 views
34

necesito para comprobar un valor formulario de entrada para ser un número entero positivo (no sólo un número entero), y me di otro fragmento con el siguiente código:¿Cuál es la mejor forma de verificar si hay un entero positivo (PHP)?

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

Me preguntaba si hay alguna ventaja de utilizar la tres comprobaciones anteriores, en lugar de hacer algo así:

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

la última comprobación es solo para ver si el número es un número entero. El uso de este cheque realmente depende de sus requisitos – Ass3mbler

+2

... Está buscando un número negativo en el código actualmente. – JeroenEijkhof

+0

¡Reparado! Lo siento por eso. – geerlingguy

Respuesta

29

la diferencia entre los dos fragmentos de código es que is_numeric($i) también devuelve cierto si $ i es un cadena numérica, pero is_int($i) sólo se devuelve cierto si $ i es un número entero y no se si $ i es una cadena número entero. Es por eso que debe usar el primer fragmento de código si también desea devolver verdadero si $ i es una cadena de entera (por ejemplo, si $ i == "19" y no $ i == 19).

ver estas referencias para obtener más información:

php is_numeric function

php is_int function

+0

Nunca pensé en eso ... – geerlingguy

+2

Solo probando ese código, estoy descubriendo que incluso eso no es suficiente, ya que valida ''123'' como un entero. Necesitaba agregar '$ i! == trim ($ i)' para atrapar espacios principales. Parece que '123' == '123' incluso cuando está seguro de que los dos valores son cadenas, pero PHP no los trata como cadenas cuando los compara de esa manera. – Jason

+1

Observe que los valores de cadena de consulta (parámetros GET) siempre se pasan como cadena, incluso si el valor es numérico. –

1

el primer ejemplo es el uso round para verificar que la entrada es un entero, y no un valor numérico diferente (es decir: un decimal).

is_int devolverá falso si pasó una cadena. Ver el PHP manual examples for is_int

1

En realidad, no es necesario utilizar los tres cheque y si quieres un número entero positivo es posible que desee hacer lo contrario de lo que está en su código:

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

Comprobar la respuesta de Sören para más información sobre la diferencia entre is_int() y is_numeric()

+1

también '&&' no '||' – Mchl

+0

código catch :) cambiándolo ... gracias – JeroenEijkhof

+1

creo que probablemente no sea su problema, este fue un ejemplo muy básico;) –

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

y si desea limitar la longitud:

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

int Así pisitive con una longitud máxima de 6:

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

¿el preg_match permite int negativo? – SuperSpy

+0

Otro enfoque interesante ... pero es más difícil de leer, por lo que probablemente sea menos apto para usarlo. – geerlingguy

0

Si utiliza "is_int" la variable debe ser entero, por lo que no puede ser un valor flotante. (no se necesita ronda)

0
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. 
} 
2

Además de todas las otras respuestas: Usted probablemente está buscando ctype_digit. Busca una cadena que contiene solo dígitos.

5

La otra forma de comprobar un número entero es usar expresiones regulares. Puede usar el siguiente código para verificar el valor entero. Será falso para los valores de flotación.

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

Es mejor si puede comprobar si $ i> 0 también.

+0

esto devolverá 'TRUE' también para' 0'. –

2

Definición:

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

Entonces ...

is_numeric ($ i) || $ i < 1 || $ i! = round ($ i) es igual a ! A || B || ! C

Por lo tanto: (! A || C)

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

Ahora, usando el teorema de De Morgan, es decir, = (A & & C), entonces:

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

Ahora, tenga en cuenta que A & & C = is_numeric ($ i) & & $ i == round ($ i), pero si $ i == round ($ i) es TRUE, entonces is_numeric ($ i) es TRUE también, entonces podemos simplificar A & & C = C entonces,

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

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

lo que sólo necesita utilizar:

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

La mejor manera para la comprobación de los números enteros positivos cuando la variable puede ser INTEGER o cadena que representa el número entero:

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

is_int() devolverá verdadero si el tipo de valor es integer. ctype_digit() devolverá verdadero si el tipo es string pero el valor de la cadena es un número entero.

La diferencia entre este cheque y is_numeric() es que is_numeric() devolverá verdadero incluso para los valores que representan números que no son enteros (por ejemplo, "+0.123").

+2

+1 parece ser el más limpio, también funciona con cadenas muy largas hechas de dígitos. (Incluso cuando esta cadena comience con '-') –

+1

Tenga en cuenta que trata las cadenas numéricas con ceros a la izquierda (es decir, '' 00123'') como enteros, mientras que' FILTER_VALIDATE_INT' no lo hace. – retrowaver

29

No estoy seguro de por qué no hay ninguna sugerencia para usar filter_var en esto. Sé que es un hilo viejo, pero tal vez ayudará a alguien (después de todo, terminé aquí, ¿verdad?).

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


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

También podría agregar un valor máximo también.

$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

1

para verificar el uso entero positivo:

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

O

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

utilice la función que se adapte a su pur posar ya que son lo mismo.Los siguientes ejemplos demuestran la diferencia entre is_numeric() y 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

'is_int' comprueba el tipo de variable. No es aplicable a la entrada del usuario porque en la mayoría de los casos es una cadena. – Kirzilla

1

Todas estas respuestas pasan por alto el hecho de que el solicitante puede comprobar entrada de formulario.
El is_int() fallará porque la entrada del formulario es una cadena.
is_numeric() será verdadero también para los números flotantes.
Es por eso que la $ i == ronda ($ i) entra mientras se comprueba que la entrada sea un número entero.

1

Ok, sé que este hilo es muy viejo, pero comparto la opinión de @Jeffrey Vdovjak: ya que pude encontrarla, todavía podría ayudar a alguien más.

php's gmp_sign() puede ser otra manera fácil de verificar. Funciona para cadenas enteras y numéricas, y devuelve 1 si a es positivo, -1 si a es negativo y 0 si a es cero.

Así:

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

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

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

la Salida:

1 
-1 
0 

Ver Manual de funciones en http://php.net/manual/en/function.gmp-sign.php

P. S. Deberá tener habilitado php_gmp.dll en su archivo .ini.

0

me gustaría hacer algo como esto:

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

El número se encasillada en un número positivo o negativo dependiendo del signo de menos estar en el frente. Luego, compara el número de tipo de letra a ser mayor que 0 para determinar si el número es positivo.

0

Esta es mi solución, espero útiles:

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

puedo comprobar si la cadena es numérico, segunda comprobación para asegurarse de que es número entero y la tercera a seguro positivo

11

Es, definitivamente, en dirección a la tierra de micro optimización, pero oye: el código en el que estoy trabajando mastica millones de artículos todos los días y es viernes. Así que hice un poco de experimentación ...

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

que luego corrió las pruebas anteriores, tanto para los valores de número entero y la cadena

Opción 1: fundición sencilla/equivalencia pruebas

  • Entero: 0.3s
  • Cadena: 0.4s

Opción 2: usando is_int() y ctype_digit()

  • Entero: 0,9 segundos
  • de la secuencia: 1.45s

Opción 3: expresiones regulares

  • Entero: 1.83s
  • Cadena: 1.60s

Tal como era de esperar, la opción 1 es, con mucho, el más rápido, ya que no hay no hay llamadas a funciones, solo casting. También vale la pena señalar que a diferencia de otros métodos, la opción 1 trata el valor de cadena por flotación entero "5.0" como un entero:

$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 

Independientemente de si eso es una buena cosa para su uso-caso particular se deja como un ejercicio para el lector ...

2

laravel 4.2 regla de validación de número positivo

Se tarda sólo números positivos, incluyendo valores de coma flotante.

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

por ejemplo: 20,2.6,06

+0

algo que estoy buscando. –

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

¿Cómo aprender Reg Exp? –

+0

@MujahedAKAS mira aquí https://regex101.com/r/iI7eS8/1 –

1

En lugar de la comprobación de int O string con múltiples condiciones como:

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

puede simplificar esto simplemente echando la entrada a (string) para que la llamada ctype_digit compruebe las entradas string y int:

if(ctype_digit((string)$i)) 
{ 
    return TRUE; 
} 
+0

Buen uso de la fundición –

Cuestiones relacionadas