Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I recently noticed trouble when using the array_search function in my code. I am searching the array "$allcraftatts" for the value "sharp". I tried to isolate the problem by setting up a two line experiment:

$testcopy=$allcraftatts;
$testsharp=array_search("sharp", $testcopy);

Using "print_r(get_defined_vars());" later on, I get this result:

[testcopy] => Array
                (
                    [0] => 0
                    [1] => 0
                    [2] => 0
                    [3] => 0
                    [4] => 0
                    [5] => 0
                    [6] => Sharp Stone
                    [7] => Sharp Stones
                    [8] => stone
                    [9] => object
                    [10] => sharp
                    [11] => hard
                    [12] => 0
                    [13] => 0
                    [14] => 0
                    [15] => 0
                    [16] => 0
                    [17] => 0
                    [18] => 0
                )

[testsharp] => 0

I made sure that I do not modify these variables at any other time.

Now, if I change my code to

$testcopy=$allcraftatts;
unset($testcopy[0]);
$testsharp=array_search("sharp", $testcopy);

it returns "1".

This leads me to believe that it always returns the first key in the array.

It baffles me! This is one of those bugs that makes you fear something wrong with the language itself. However doubtful this is, I actually was eventually driven to looking at the PHP source for something wrong there, but unfortunately could not understand it.

Seeing that it is a function simple as this, I will most definitely be completely humiliated by the inevitably simple answer, but at this point, I just want an answer.

share|improve this question
 
What version of PHP are you using? Also can you show us the output of a var_dump on those variables instead of print_r? It will show whether you have any extra spaces (which is a common hiccup people experience with array_search) –  cillosis Nov 6 '12 at 21:25
add comment

3 Answers

up vote 5 down vote accepted

array_search is using == to compare values during search

FORM PHP DOC

If the third parameter strict is set to TRUE then the array_search() function will search for identical elements in the haystack. This means it will also check the types of the needle in the haystack, and objects must be the same instance.

Becasue the first element is 0 the string was converted to 0 during search

Simple Test

var_dump("sharp" == 0); //true
var_dump("sharp" === 0); //false

Solution use strict option to search identical values

$testsharp = array_search("sharp", $testcopy,true);
                                               ^---- Strict Option

var_dump($testsharp);

Output

10
share|improve this answer
add comment

If any key before the searched one is numeric zero, then that key is returned, because it is performing a "loose" match dominated by the array's data type, and "sharp" (if converted to int) counts as zero. Using a strict checking, the correct value is found.

Otherwise, by executing

$testcopy = array_map('strval', $testcopy);

so that values are translated to strings, it works also with "loose" check.

share|improve this answer
add comment

Welcome to the wonderful world of loose typing. In php, array_search defaults to nonstrict comparisons ("=="), but you can add a third parameter to force strict ("==="). You almost always want strict, though there are times when nonstrict is the correct operation.

check out the following:

$allcraftatts = array(0, 0, 0, 0, 0, 0, "Sharp Stone", "Sharp Stones", "stone", new stdClass(), "sharp", "hard", 0, 0, 0, 0, 0,0 ,0);
$testcopy=$allcraftatts;
$testsharp=array_search("sharp", $testcopy);
$testsharpStrict=array_search("sharp", $testcopy, true);

print_r(get_defined_vars());                                                                                                                                                                                                                        

if(0 == "sharp"){
    echo "true for == \n";
}else{
    echo "false == \n";
}
if(0 === "sharp"){
    echo "true for === \n";
}else{
    echo "false === \n";
}

and the output:

[testcopy] => Array
        (
            [0] => 0
            [1] => 0
            [2] => 0
            [3] => 0
            [4] => 0
            [5] => 0
            [6] => Sharp Stone
            [7] => Sharp Stones
            [8] => stone
            [9] => stdClass Object
                (
                )

            [10] => sharp
            [11] => hard
            [12] => 0
            [13] => 0
            [14] => 0
            [15] => 0
            [16] => 0
            [17] => 0
            [18] => 0
        )

    [testsharp] => 0
    [testsharpStrict] => 10
)
true for == 
false === 
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.