# Solved: problem with stripos (php)



## andynic (May 25, 2007)

Hi,

What am I not understanding about the stripos or strpos function?

Given this code:

```
<?php
$scr = "adHocPages";
$pos = stripos($scr, "adHoc", 0 );
if ( $pos >= 0 ) { echo "scr contains adHoc<br />";  } else { echo "not because pos = $pos<br />"; }
?>
```
It displays as expected "scr contains adHoc".

Given this code, which is identical to the above except that $scr = "HocPages" instead.

```
<?php
$scr = "HocPages";
$pos = stripos($scr, "adHoc", 0 );
if ( $pos >= 0 ) { echo "scr contains adHoc<br />";  } else { echo "not because pos = $pos<br />"; }
?>
```
It also displays (unexpectedly to me) "scr contains adHoc".
(I would have expected "not because pos = ")

What am I doing wrong or misunderstanding?

Thanks for your help.
Andynic


----------



## JiminSA (Dec 15, 2011)

Hi there andynic, if you were using PHP version < 5.3 your second bit of code would pick a return value of zero (false).
But because of _a refinement*_ in PHP version >= 5.3 the return value is null instead of the expected value zero (false).
When you think about it this refinement* (mistakenly reported as a bug) is better - because the search can find the string at position 0 - so null is an accurate representation of a not found and anything >= 0 is a true representation of a found.

Hope that clears it up for you

IMO - a better way of coding it would be

```
<?php
$scr = "HocPages";
$pos = stripos($scr, "adHoc", 0 );
echo "pos [" . $pos . "]<br />";
if ( $pos == true ) { echo "scr contains adHoc<br />";  } else { echo "not because pos = $pos<br />"; }
?>
```
... which treats null return value as false


----------



## andynic (May 25, 2007)

Hi JiminSA

Thanks for the reply.

I tried what you suggest (or at least I think I did) and also go a weird result. So I've copied and pasted your code above into a test script, changing the value of $scr (adding "ad" to "HocPages") and got this:

```
$scr = "adHocPages";
$pos = stripos($scr, "adHoc", 0 );
echo "pos [" . $pos . "]<br />";
if ( $pos == true ) { echo "scr contains adHoc<br />";  } else { echo "not because pos = $pos<br />"; }
```
Resulting output:
pos [0]
not because pos = 0

Very strange indeed!

Some additional info:
php -v
PHP 5.3.26 (cli) (built: Jul 7 2013 18:30:38) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.1.1, Copyright (c) 2002-2011, by Derick Rethans

Thanks for your help.
Andynic


----------



## JiminSA (Dec 15, 2011)

Bit of a conundrum this one Andy
Because the if statement seems to treat 0 and null the same we can't use == effectively, so just test for numeric and we don't need to write complex if statements (KISS) ...

```
<?php

$scr = "Pages";		// swop these around for testing
$scr = "adHocPages";    //


$pos = stripos($scr, "adHoc", 0 );
echo "pos [" . $pos . "]<br />";
if (is_numeric( $pos ) )
{
	echo "$scr contains adHoc<br />"; 
} 
else 
{
	echo "adHoc not found in $scr<br />";
}
?>
```


----------



## andynic (May 25, 2007)

Thank you. Nice workaround.

It's a major bug. Anyone who has used stripos or strpos in PHP versions where it may have worked correctly has a problem if the search-string begins in the starting position of the sting to be searched. In these functions, PHP considers the starting position of a string to be position 0, not 1.

Apparently, in the version of PHP I am using (please see above), PHP does not make a distinction between false and the 
number zero, which the manual seems to indicate is intentional: http://www.php.net/manual/en/language.types.boolean.php. 
Strange!

So if one really needs the position number in which a string starts, and that position could be the first positon (position 0), 
one has to use is_numeric, as JiminSA suggests, to see if it is in the first position. Otherwise you'll get wrong results like this:

```
scr = "adHocPages";
$pos = stripos($scr, "adHoc" );
echo "pos [" . $pos . "]<br />";
if ( $pos ) //Testing for true/false is erroneous here.  EVEN USING ($pos === TRUE) DOES NOT WORK
{ 
  echo "scr contains adHoc and ord(pos) = " . ord($pos) . "<br />";  
} 
else 
{ 
   echo "string does not contain adHoc because pos = $pos and ord(pos) = ". ord($pos) . "<br />"; 
}
```
Output from the above code, which is mistaken (Note the value of $scr):
pos [0]
string does not contain adHoc because pos = 0 and ord(pos) = 48 <--WRONG RESULT

Looking at the above, one could be misled into thinking that the following should work -- 
but it does not. It SEEMS to work correctly when the string contains "adHoc", but gives
erroneous results when the string does not contain adHoc.

CASE: The string-to-be-searched, $scr, contains "adHoc"

```
$scr = "adHocPages";  // NOTE THE VALUE OF $scr. 
$pos = stripos($scr, "adHoc" );
echo "pos [" . $pos . "]<br />";
if ( $pos >= 0 )   
{ 
  echo "scr contains adHoc and ord(pos) = " . ord($pos) . "<br />";  
} 
else 
{ 
   echo "string does not contain adHoc because pos = $pos and ord(pos) = ". ord($pos) . "<br />"; 
}
```
Output of the above code SEEMS correct:
pos [0]
scr contains adHoc and ord(pos) = 48 <-- IN THIS CASE IT IS CORRECT

BUT:

CASE: The string-to-be-searched, $scr, does NOT contain "adHoc"

```
$scr = "HocPages";  // NOTE THE VALUE OF $scr. 
$pos = stripos($scr, "adHoc" );
echo "pos [" . $pos . "]<br />";
if ( $pos >= 0 ) 
{ 
  echo "scr contains adHoc and ord(pos) = " . ord($pos) . "<br />";  
} 
else 
{ 
   echo "string does not contain adHoc because pos = $pos and ord(pos) = ". ord($pos) . "<br />"; 
}
```
Output of the above code when the string does not contain adHoc:
pos []
scr contains adHoc and ord(pos) = 0 <-- THIS RESULT IS WRONG!!!!

Very confusing!

But for my case, your solution, JiminSA, works well. Thanks again.
Andynic


----------



## andynic (May 25, 2007)

I just discovered that reversing the if...else clauses and testing for ($pos === false) works.
(But note also, that keeping the clauses as they were and testing ($pos === true) DOES NOT WORK!!!
Still no less confusing.

```
scr = "dHocPages";
$pos = stripos($scr, "adHoc" );
echo "pos [" . $pos . "]<br />";
if ( $pos === false ) //Testing for true/false is erroneous here.
{ 
   echo "string does not contain adHoc because pos = $pos and ord(pos) = ". ord($pos) . "<br />"; 
} 
else 
{ 
  echo "scr contains adHoc and ord(pos) = " . ord($pos) . "<br />";  
}
```
Andynic


----------



## JiminSA (Dec 15, 2011)

Andy, have you tried checking for type and value (=== or >==) using your original code?


----------



## andynic (May 25, 2007)

Didn't think of that. Thanks!


----------

