Search code examples
phparraysstrpos

Unexpected PHP Array key behaviour


Ok I find this very weird but there should be an explanation. Here is what happens.

This code here should echo nothing:

$str = 'a@gmail.com';
$key = '11111';
echo strpos($str, $key);
exit;

.. and yes this is exactly what I get, nothing. But !! If I am to use the $key (which contains a string) as an actual key of an array:

$str = 'a@gmail.com';
$arr = array('11111' => 'test');
foreach ($arr as $key => $val)
{
    echo 'String: '.$str.'<br>';
    echo 'Key: '.$key.'<br>';
    echo 'Found at position: '.strpos($str, $key);
}
exit;

I get this amazing, magical result:

String: a@gmail.com
Key: 11111
Found at position: 2

So what php found here was the string 11111 to be the letter g But what is even more amazing, is that the number of digits changes the result:

$str = 'a@gmail.com';
$arr = array('111' => 'test');
foreach ($arr as $key => $val)
{
    echo 'String: '.$str.'<br>';
    echo 'Key: '.$key.'<br>';
    echo 'Found at position: '.strpos($str, $key);
}
exit;

This one gives:

String: a@gmail.com
Key: 111
Found at position: 9

Any experts on this ? Thank you.

EDIT: This is actual code example used in my project which gives such false positives:

$email = '[the email of the user here]';
$arr = array(
    // [...]
    '11111' => 'Banned',
    '22222' => 'Banned',
    '33333' => 'Banned',
    // [...]
);
foreach ($arr as $key => $reason)
{
    if (strpos($email, (string)$key) !== false)
    {
        return 'Keyword: '.(string)$key.' found in the user Email address with reason: '.(string)$reason;
    }
}

So even using the (string) in front of the variable $key it bans innocents at the login form


Solution

  • use this, It will work fine. I type casted $key into string. PHP function strpos for matching substring with in the string, not the integer value. If you look into the documentation, it is clearly mentioned

    Second parameter: If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.

    <?php
    ini_set('display_errors', 1);
    $str = 'a@gmail.com';
    $arr = array('11111' => 'test');
    foreach ($arr as $key => $val)
    {
        echo 'String: '.$str.'<br>';
        echo 'Key: '.$key.'<br>';
        echo 'Found at position: '.strpos($str, (string)$key);
    }