Why PHP strpos appears to give wrong answer?

Posted in Articles

Tweet This Share on Facebook Bookmark on Delicious Digg this Submit to Reddit

The strpos function in PHP may appear to give the wrong answer when it is not used properly.

strpos is designed to return the integer position of the first occurrence of a “substring” in a “string” where substring is the “needle” passed as the second argument and “string” is the “haystack” passed as the first argument …

int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

The third argument is optional (so we will not worry about that in this example).

However, many times, strpos is used to determine if a string is contained within another string.  For example, to see if the word “cat” is contained in the word “category”, the correct way to do it is …

correct use of strpos

Alternatively, you can write …

also correct use of strpos

which is also correct.

strpos(“category”, “cat”) will return the boolean false if and only if it can not find the second argument in the first.   Note that we use the triple equal sign === for the “identical” operator and not just the double equal sign == of the “equals” operator.   Same with the negative version.  Use !== and not !=.

The problem occurs when the wrong operator is used.   If the “equals” operator was used as in …

wrong use of strpos

it would appear that strpos gives the wrong answer.  Because it displays “cats is not in category” when it clearly is.

This is because …

strpos(“category”, “cat”) 

returns 0 (the numeral zero).  “cat” is found in the zero index position of “category”.  The numeral 0 equals to false when using the equals operator of double-equal.   The numeral 0 is not identical to false when compared with the triple equal sign.

PHP manual on strpos says …

“This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. … Use the === operator for testing the return value of this function.”

The triple equal is what we should use here.  The same goes for the other strpos-like functions such as stripos, strrpos, and strripos.