¿Hay alguna diferencia entre is_int () y ctype_digit ()?
Pregunta
¿Se prefiere uno más o funciona mejor que el otro?
Solución
is_int ()
devuelve verdadero si el argumento es un 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 │
└──────────┴───────────┴────────────────┘
Otros consejos
También hay is_numeric
que devuelve verdadero si se pasa el valor se puede analizar como número.
Si trato de comparar el rendimiento de las funciones en PHP 5.5.30 aquí están los resultados:
Este es el código que utilicé 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> </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 será un cuello de botella en su código.
ctype no siempre devuelve falso 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 base es poner en mayúsculas y minúsculas cada número para encadenar e.q. 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 a 2147483647.
cualquier valor que exceda ese número le devolverá falso suponiendo que se esté ejecutando en un sistema de 32 bits.
en 64bits puede subir al 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 cada valor en el rendimiento de la cadena se reduce en general.
Si realmente no le importa si el argumento es un 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 utilizando 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);
}
Bueno, es muy interesante :) Aquí está toda la historia:
is_numeric:
: determina si una variable es un número o una cadena numérica, sin importar si el valor es negativo o booleano o de cadena o de cualquier tipo de número, si el valor es puramente número, devolverá'true'
else'false'
.Recuerde: sin número de caracteres solamente de ningún tipo :)
is_init
: compruebe si el tipo de una variable es entero, si el valor es puramente entero, devolverá 'verdadero' más 'falso'.Recuerde: sin caracteres, doble o negativo, solo entero
in_integer
- Alias ??de is_int ()
intval:
: obtiene el valor entero de una variable, toma todo tipo de valor y devuelve solo el valor entero, si los valores son negativos, entonces devuelve el valor '-Integer
'. No importa los valores son Integer, Float, Negativo o 'NumberString
' o 'NumberStringCharacter
'. Resta los valores enteros de la cadena "Si la cadena comienza con Número
" ;.
- NumberString = Un valor numérico en formato de cadena
- NumberStringCharacter = 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
: compruebe los caracteres numéricos, si se proporciona un número entero en formato de cadena obtendrá 'true
'else'false
'. Va a funciona solo con StringNumber, Sin flotante, Sin negativo Solo Número entero como cadena.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 de pájaro:
Gracias a http://php.net/