Question

This is the test.php file:

<?php

$string = 'A string with no numbers';

for ($i = 0; $i <= strlen($string)-1; $i++) {
    $char = $string[$i];
    $message_keyword = in_array($char, range(0,9)) ? 'includes' : 'desn\'t include';
}

// output
echo sprintf('This variable %s number(s)', codeStyle($message_keyword));

// function
function codeStyle($string) {
    return '<span style="background-color: #eee; font-weight: bold;">' . $string . '</span>';
}

?>

It splits the string character by character and check if the character is a number or not.

Problem: It's output is always "This variable includes number(s)". Please help me to find the reason. TIP: When I change range(0,9) to range(1,9) It works correctly (But it can't detect 0).

Was it helpful?

Solution

Use preg_match():

if (preg_match('~[0-9]+~', $string)) {
    echo 'string with numbers';
}

Althought you should not use it, as it is much slower than preg_match() I will explain why your original code is not working:

A non numerical character in the string when compared to a number (in_array() does that internally) would be evaluated as 0 what is a number. Check this example:

var_dump('A' == 0); // -> bool(true)
var_dump(in_array('A', array(0)); // -> bool(true)

Correct would be to use is_numeric() here:

$keyword = 'doesn\'t include';
for ($i = 0; $i <= strlen($string)-1; $i++) {
    if(is_numeric($string[$i]))  {
       $keyword = 'includes';
       break;
    }
}

Or use the string representations of the numbers:

$keyword = 'doesn\'t include';
// the numbers as stings
$numbers = array('0', '1', '2', /* ..., */ '9');

for ($i = 0; $i <= strlen($string)-1; $i++) {
    if(in_array($string[$i], $numbers)){
       $keyword = 'includes';
       break;
    }
}

OTHER TIPS

You can just use regexp :

$message_keyword = preg_match('/\d/', $string) ? 'includes' : 'desn\'t include';

Better way is using regular expression

<?php
    if (preg_match('#[0-9]#',$string)){
        $message_keyword = 'includes';
    }
    else{
        $message_keyword = 'desn\'t include';
    }  
?>

This is because of PHP loose type comparison, you are comparing string with integer, so PHP internally will cast this string to integer, and all character in your string will be casted to 0.

First step to fix your code, will be to create an array of strings instead of integers:

$numbers = array_map(function($n){ return (string)$n; }, range(0,9));
for ($i = 0; $i <= strlen($string)-1; $i++) {
    $char = $string[$i];
    $message_keyword = in_array($char,$numbers)?'includes' : 'doesn\'t include';
}

This will fix your case, but will not work as you expect it to, since $message_keyword is overwritten on each loop, so will receive message for last character only. If you are aiming to only check if string contains number, you can stop checking after encountering first number:

$message_keyword = 'doesn\'t include';
for ($i = 0; $i <= strlen($string)-1; $i++) {
    $char = $string[$i];
    if(in_array($char, $numbers)) {
        $message_keyword = 'includes';
        break; //found, no need to check next
    }   
}

To have this all logic in more compact form, use regular expresion, as posted by others before.

array range ( mixed $start , mixed $end [, number $step = 1 ] )

If a step value is given, it will be used as the increment between elements in the sequence. step should be given as a positive number. If not specified, step will default to 1.

In your case, you havent mentioned the third parameter that is why it is always set to 1

See Manual here

It's kinda late to answer this question after about 9 years, but If you want to detect integers (and not floats) nothing is better than ctype_digit. Using this function to detect floats with decimal point or other types would results in returning false.

<?php
$number = "123";
$notNumber = "123abc";
var_dump(ctype_digit($number));
var_dump(ctype_digit($notNumber));
?>

Output

bool(true)
bool(false)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top