What strpos() returns when the searched value is not found?

Asked

Viewed 160 times

1

I have a code that is causing me a doubt when returning the method strpos() of PHP.

See what is returned when the value sought is found:

$string = "vermelho";
$result = strpos($string, "vermelho"); 

echo $result . "<br>";

if($result == false)
{
    echo "Retornou false<br>";      
}

if($result == "")
{
    echo "Retornou vazio<br>";      
}

if($result == 0)
{
    echo "Retornou zero<br>";       
}

if($result == "0")
{
    echo "Retornou zero<br>";       
}

inserir a descrição da imagem aqui

Now look what is returned when value is not found:

$string = "vermelho";
$result = strpos($string, "azul"); 

echo $result."<br>";


if($result == false)
{
    echo "Retornou false<br>";      
}

if($result == "")
{
    echo "Retornou vazio<br>";      
}

if($result == 0)
{
    echo "Retornou zero<br>";       
}

if($result == "0")
{
    echo "Retornou zero<br>";       
}

inserir a descrição da imagem aqui

The return is virtually the same and comes in all conditions for both of the above cases.

In the documentation says:

If Needle is not found, strpos() will return Boolean FALSE.

FALSE would not equal 0?

I saw a code in which a comparison is made of the result of strpos() with -1. In any case it is returned -1 of strpos()?

  • 5

    The documentation comments on the function returns. If the sought character is in the first position it returns zero, PHP converts the zero to false, in this scenario you should compare using the === checking whether the type and value are equal

  • But if I put a String to be searched, how is the position of that string found within the other string ? For example, if I put "a" to be searched in "blue" it is right to return 0, because the character was found in the first position. However, if I put "blue" to be searched in "blue", how is returned 0 in this case ?

  • 2

    strpos searches for the first occurrence of a string within another and returns the position where this occurrence starts. strpos("azul", "a") returns 0 because position 0 is the first occurrence of "a" in "blue". strpos("azul", "az") also returns 0, as it is in this position that begins the first occurrence of "az" within "blue". Then strpos("azul", "azul") tb returns zero for the same reason

  • Thanks for the clarification, guys.

  • Strpos() will return FALSE. For more information, see the php documentation. php.net

2 answers

5


According to the documentation of strpos, the function takes two strings (which there are called "haystack" and "needle") and the return is (in free translation):

The position where the needle is, relative to the beginning of the string haystack.
Returns FALSE if the needle is not found.

So basically it returns the position of the string at which the first occurrence of substring starts. For example, strpos("azul", "az") returns 0 because it is in the zero position of "blue" that the first occurrence of "az" begins. The same goes for strpos("azul", "a") and strpos("azul", "azul"), the return of both is also 0.

And when the substring does not occur within the string, the return is FALSE. That is, the return can be either an integer or a boolean. For example, for the code below:

var_dump(strpos("azul", "az")); // retorna 0
var_dump(strpos("azul", "xyz")); // retorna FALSE

The exit is:

int(0)
bool(false)

The problem begins when checking the returned value. According to documentation, the operator == that you used to compare the operands after applying the type Juggling. That means if you compare 0 == FALSE, they will be considered equal (see comparison table "loose").

Therefore, the code below prints "X":

if (0 == FALSE) {
    echo "X"; // imprime X
} else {
    echo "Y";
}

Already if we use the operator ===, is not done the type Juggling, and are followed strict rules of comparison, which also checks if the operands are of the same type. That is, the code below prints "Y":

if (0 === FALSE) {
    echo "X";
} else {
    echo "Y"; // imprime Y
}

The same goes for the other tests you did. Both the empty string ("") as to string "0", when compared to ==, are considered equal to FALSE (see the comparison table "loose" already quoted above).


Therefore, the problem is how you are checking the return. Inclusive, own documentation of strpos says to use the operator === to check the return of this function. Ex:

$result = strpos("azul", "az");

if ($result === FALSE) {
    echo "Não foi encontrada nenhuma ocorrência";
} else {
    echo "Encontrada ocorrência na posição $result";
}

Or, if you want to verify that a specific position was found, it could be something like:

if ($result === 0) {
    echo "Encontrada ocorrência no início da string";
} else if ($result === FALSE) {
    echo "Não foi encontrada nenhuma ocorrência";
} else {
    echo "Encontrada ocorrência, mas não no início da string (posição $result)";
}

As to compare the return with -1, is an alternative way suggested in the documentation. But it’s not to compare whether the return is equal to -1 (as the documentation does not mention any case where strpos returns -1), and yes if the returned value is greater that -1. That’s because when checking FALSE is greater than -1, the result will be false:

if (FALSE > -1) {
    echo "X";
} else {
    echo "Y"; // imprime Y
}

Therefore, another way to check the return is:

$result = strpos($string1, $string2);

if ($result > -1) {
    echo "Encontrada ocorrência, na posição $result";
} else {
    echo "Não foi encontrada nenhuma ocorrência";
}

3

When you compare, it is recommended that you do it with three equals (==). Thus, you compare the value of the variable and the type as well. The way you wrote (==), the values zero, empty string and false, will always be false, but if you make the comparison with === PHP will compare the type of the variable too.

if($result === false)
{
    echo "Retornou false<br>";      
}

if($result === "")
{
    echo "Retornou vazio<br>";      
}

if($result === 0)
{
    echo "Retornou zero<br>";       
}

if($result === "0")
{
    echo "Retornou zero<br>";       
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.