I came across an issue with the php STRPOS() function today that I just had to share. Well – ok, the function acted as designed, although it’s default behavior is not what I would have intuitively guessed. Oh the excitements of a programmer 🙂
The issue was that I had a code routine using STRPOS() that was giving false positives approximately 1% of the time. Generally, the majority of errors with STRPOS() are around doing == vs === comparisons as STRPOS() can return a 0 for a found element. This can equate to False if you are not checking variable types. In our case however, our evaluation was setup properly.
Here is a little background on the routine. We had a string list of user ids separated by either commas or spaces. That was our whitelist. Each time the user loaded the page we wanted to evaluate whether or not the users id was then found in the whitelist. For speed of calculation (milliseconds do matter here) we wanted to use STRPOS() instead of breaking the whitelist into an array and searching for the exact value. The array could potentially be very large.
Here is an example of the whitelist: “20186931948 20075567261 31466598112 31208242755”
Here is an example of a user id: 31866955575
According to the STRPOS() function this returns a value of 15. Go ahead, give it a try.
Here is the actual code
$whitelist = "20186931948 20075567261 31466598112 31208242755"; $uid = 31866955575; echo strpos($whitelist, $uid);
The cause of our issue was that we were sending in a numeric value for the the needle of the STRPOS() function.
According to the PHP docs in reference to the needle param:
“If needle is not a string, it is converted to an integer and applied as the ordinal value of a character”.
This basically means that when we passed in a numeric user id as our needle. The STRPOS() function was converting the numeric user id into an ascii table based equivalent. It was then finding that ascii table based equivalent in the whitelist of approved ids.
The fix for this problem was actually very simple. All we did was add an empty string to the end of the user id before we sent it into the STRPOS() function for evaluation.
And here is the actual code:
$whitelist = "20186931948 20075567261 31466598112 31208242755"; $uid = 31866955575 . ""; echo strpos($whitelist, $uid);
Now it works just fine. We are now successfully handling the false positives thrown from the STRPOS() function when evaluating numeric values.