There’s a few things wrong with your script. The first (and most obvious) is that you’ve put a semi-colon (signifying an empty statement) at the end of you WHILE loop condition. This means it will continue to execute until the condition is false. Fortunately for you, it will be false on the first time round (I’ll explain why in a second). That is why the code in-between the braces outputs once.
So we now have the following (semicolon omitted):
<?php
$sentence='is is is';
$search='is';
$length=strlen($search);
$offset=0;
$j=1;
while (strpos($sentence,$search,$offset))
{
echo $j.'. '.strpos($sentence,$search,$offset).'<br>';
$offset += $length;
$j++;
}
As the above code stands, the body will not execute at all now. Why? Because if you have a look at the manual, the strpos()
function returns FALSE if no match is found, or the offset (as an integer) if one is found. BUT what you have to remember is that indexes start at 0, and right now the offset of your first match will return 0 - and 0 in PHP is a falsey value (see here for other falsey values). This means that the condition for your WHILE loop actually evaluates to false, thus not executing the body of you loop.
So let’s fix that by using a strict comparison and also remove some repetition by performing an assignment in your WHILE’s condition to be used throughout the WHILE body:
<?php
$sentence='is is is';
$search='is';
$length=strlen($search);
$offset=0;
$j=1;
while(($pos = strpos($sentence,$search,$offset)) !== FALSE)
{
echo $j.'. '.$pos.'<br>';
$offset += $length;
$j++;
}
The above will now output:
1. 0
2. 3
3. 6
4. 6
So where’s the fourth result coming from? It’s coming from the fact that your $offset
value is being calculated incorrectly. Upon each execution of the WHILE loop body, you’re simply adding on the length of the string to find. So what if a match is found at offset 5 of that string on the initial loop? The loop body will execute, adding on (in your case above) 2 to the offset, and so your strpos
function will start searching at offset 2 next time. When searching from offset 2, it will again find the same match (at offset 5 last time), but this time it will be at an offset of 3. Your code will also find the same match again the next iteration too. So in order to calculate the correct offset, you must add the $pos
variable onto it as well:
$sentence='is is is';
$search='is';
$length=strlen($search);
$offset=0;
$j=1;
while(($pos = strpos($sentence,$search,$offset)) !== FALSE)
{
echo $j.'. '.$pos.'<br>';
$offset = $pos + $length;
$j++;
}
The above should now output:
1. 0
2. 3
3. 6
EDIT: @Dormilich beat me to the initial problems your script was facing - though my reply continues to explain what else was wrong with it.