0

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

durduvakis
  • 189
  • 4
  • 16
  • Possible duplicate of [Problem with Strpos In PHP](https://stackoverflow.com/questions/1039738/problem-with-strpos-in-php) – mickmackusa May 23 '17 at 01:58

1 Answers1

1

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);
}
Sahil Gulati
  • 15,028
  • 4
  • 24
  • 42
  • thanks for your answer, well this is exactly what I am doing in my project's code loop but it still hits this false positive. So again, the question is, WHY is this happening without or even WITH the (string) before the `$key` ? It is funny ! – durduvakis Apr 18 '17 at 04:11
  • @durduvakis Please check my current code, if it is still not working, then please share that code in your post which is not working. – Sahil Gulati Apr 18 '17 at 04:13
  • If you notice it is a string once it is in single quotes. – durduvakis Apr 18 '17 at 04:13
  • yes i see,but in itself `strpos` is treating it as integer, so if you type cast it into `string` It will start working the way you want. – Sahil Gulati Apr 18 '17 at 04:14
  • right, give me a moment to find my code exactly at that point which banned a user an hour ago due to this false positive. – durduvakis Apr 18 '17 at 04:18
  • @durduvakis Okay no issues, take your time. – Sahil Gulati Apr 18 '17 at 04:18
  • please check my updated question at the end. The code is very similar to the original examples I gave. – durduvakis Apr 18 '17 at 04:27
  • @durduvakis can you provide that email id, a sample one. – Sahil Gulati Apr 18 '17 at 04:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141930/discussion-between-sahil-gulati-and-durduvakis). – Sahil Gulati Apr 18 '17 at 04:29