¿Hay alguna diferencia entre is_int() y ctype_digit()?

5 minutos de lectura

¿Es uno más preferido o funciona mejor que el otro?

avatar de usuario
roberto apuesta

is_int() devuelve verdadero si el argumento es de tipo entero, ctype_digit() toma un argumento de cadena y devuelve verdadero si todos los caracteres de la cadena son dígitos.

Ejemplo:

┌──────────┬───────────┬────────────────┐
│          │  is_int:  │  ctype_digit:  │
├──────────┼───────────┼────────────────┤
│ 123      │  true     │  false         │
├──────────┼───────────┼────────────────┤
│ 12.3     │  false    │  false         │
├──────────┼───────────┼────────────────┤
│ "123"    │  false    │  true          │
├──────────┼───────────┼────────────────┤
│ "12.3"   │  false    │  false         │
├──────────┼───────────┼────────────────┤
│ "-1"     │  false    │  false         │
├──────────┼───────────┼────────────────┤
│ -1       │  true     │  false         │
└──────────┴───────────┴────────────────┘

  • Impresionante respuesta!

    – Jugador 1

    27 de noviembre de 2019 a las 13:12

También hay is_numeric que devuelve verdadero si se pasa el valor se puede analizar como número.

ingrese la descripción de la imagen aquí

Si trato de comparar el rendimiento de las funciones en PHP 5.5.30 aquí están los resultados:

ingrese la descripción de la imagen aquí

Este es el código que usé para el punto de referencia

// print table cell and highlight if lowest value is used
function wr($time1, $time2, $time3, $i) {
    if($i == 1) $time = $time1;
    if($i == 2) $time = $time2;
    if($i == 3) $time = $time3;

    echo('<td>');
    if(min($time1, $time2, $time3) === $time) printf('<b>%.4f</b>', $time);
    else printf('%.4f', $time);
    echo('</td>');
}


$test_cases = array( 123, 12.3, '123', true);
$tests = 1000000;
$result = true;  // Used just to make sure cycles won't get optimized out
echo('<table>'.PHP_EOL);
echo('<tr><td>&nbsp;</td><th>is_int</th><th>ctype_digit</th><th>is_numeric</th></tr>');
foreach($test_cases as $case) {
    echo('<tr><th>'.gettype($case).'</th>');

    $time = microtime(true);
    for($i = 0; $i < $tests; $i++) {
        $result |= is_int((int)rand());
    }
    $time1 = microtime(true)-$time;

    $time = microtime(true);
    for($i = 0; $i < $tests; $i++) {
        $result |= ctype_digit((int)rand());
    }
    $time2 = microtime(true)-$time;

    $time = microtime(true);
    for($i = 0; $i < $tests; $i++) {
        $result |= is_numeric((int)rand());
    }
    $time3 = microtime(true)-$time;

    wr($time1, $time2, $time3, 1);
    wr($time1, $time2, $time3, 2);
    wr($time1, $time2, $time3, 3);
    echo('</tr>'.PHP_EOL);
}

echo('</table>');

exit();

Lo último de lo que debería preocuparse es qué tan rápido es uno de estos. No hay forma de que verificar que una cadena sea un número entero sea un cuello de botella en su código.

ctipo no siempre falso retorno en tipo entero.

foreach(range(-1000 , 1000)as $num){
    if(ctype_digit($num)){
        echo $num . ", ";
    }    
}

ctype_digit devuelve verdadero para el siguiente número de tipo entero.

-78,-77,-71,48,49,50,51,52,53,54,55,56,57,178,179,185, 256,257,258,259,260,261,262,263,264,265,266,267,268,269,270 a 1000

la práctica básica es convertir cada número en cadena eq strval($num) o (String) $num en este caso, el valor negativo (-78) siempre devolverá falso.

is_int le devolverá verdadero en el valor de tipo int entre -2147483647 y 2147483647. cualquier valor que exceda ese número le devolverá falso suponiendo que se está ejecutando en un sistema de 32 bits. en 64 bits puede ir hasta el rango de -9223372036854775807 a 9223372036854775807

en términos de rendimiento personalmente muy difícil de decir. ctype_digit puede ser más rápido que is_int, pero si tiene que convertir todos los valores en cadenas, el rendimiento se reduce en general.

avatar de usuario
No no

Bueno, es muy interesante 🙂 Aquí está toda la historia:

is_numeric: — Encuentra si una variable es un número o una cadena numérica, sin importar que el valor sea negativo, booleano, cadena o cualquier tipo de número, si el valor es puramente un número, devolverá 'true' más 'false'.

Recuerde: No hay carácter, solo número de cualquier tipo 🙂


is_init— Averigüe si el tipo de una variable es entero, si el valor es puramente entero, devolverá ‘verdadero’, de lo contrario, ‘falso’.

Recuerde: sin carácter, doble o negativo, solo entero


in_integer— Alias ​​de is_int()


intval:— Obtenga el valor entero de una variable, toma todo tipo de valor y devuelve solo el valor entero, si los valores son negativos, devuelve ‘-Integer‘ valor. No importa si los valores son Entero, Flotante, Negativo o ‘NumberString‘ o ‘NumberStringCharacter‘. Es restar los valores enteros de la cadena “If String Starts with
Number
“.

  • NúmeroCadena = Un valor numérico en formato de cadena
  • NúmeroCadenaCarácter = Una cadena comienza con un número

Recuerde: obtendrá un valor entero de Número, Flotante, Negativo o Cadena que comienza con Número.


ctype_digit— Verifique los caracteres numéricos. Si se proporciona un número entero en formato de cadena, obtendrá ‘true‘ más ‘false‘. Funcionará solo con StringNumber, No Float, No Negative solo Whole Number como String.

Recuerde: número entero como cadena, sin número negativo, sin número flotante, sin tipo de número, sin carácter, solo número como cadena.

Vista panorámica:

ingrese la descripción de la imagen aquí

Gracias a http://php.net/

avatar de usuario
gruñido

Si realmente no le importa si el argumento es de tipo int o una cadena con números, use is_numeric. Volverá verdadero para flotadores también, aunque.

Ctype_digit devuelve falso si el rango de enteros está en el rango negativo o entre 0 y 47 o entre 58 y 255. Puede verificar el comportamiento de ctype_digit usando el siguiente fragmento.

setlocale(LC_ALL, 'en_US.UTF-8');
var_dump(
    true === array_every(range(-1000, -1), 'ctype_digit_returns_false'),
    true === array_every(range(0, 47), 'ctype_digit_returns_false'),
    true === array_every(range(48, 57), 'ctype_digit_returns_true'),
    true === array_every(range(58, 255), 'ctype_digit_returns_false'),
    true === array_every(range(256, 1000), 'ctype_digit_returns_true')
);

// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every
function array_every(array $array, $callable)
{
    $count = count($array);

    for ($i = 0; $i < $count; $i +=1) {

        if (!$callable($array[$i])) {

            return false;

        }

    }

    return true;
}

function ctype_digit_returns_true($v)
{
    return true === ctype_digit($v);
}

function ctype_digit_returns_false($v)
{
    return false === ctype_digit($v);
}

¿Ha sido útil esta solución?