Недавно я заметил проблему при использовании функции array_search в моем коде. Я ищу массив «$ allcraftatts» для значения «sharp». Я попытался изолировать проблему, установив двухстрочный эксперимент:
$testcopy=$allcraftatts; $testsharp=array_search("sharp", $testcopy);
Использование "print_r (get_defined_vars ());" позже, я получаю этот результат:
[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
Я убедился, что я не изменяю эти переменные в любое другое время.
Теперь, если я изменю свой код на
$testcopy=$allcraftatts; unset($testcopy[0]); $testsharp=array_search("sharp", $testcopy);
с$testcopy=$allcraftatts; unset($testcopy[0]); $testsharp=array_search("sharp", $testcopy);
он возвращает «1».
Это заставляет меня думать, что он всегда возвращает первый ключ в массиве.
Меня это сбивает с толку! Это один из тех ошибок, который заставляет вас бояться чего-то не так с самим языком. Как бы это ни было сомнительно, я на самом деле в конечном итоге был вынужден взглянуть на источник PHP на то, что там не так, но, к сожалению, не мог этого понять.
Увидев, что это простая функция, я определенно буду полностью оскорблен неизбежно простым ответом, но на данный момент я просто хочу получить ответ.
array_search
использует ==
для сравнения значений во время поиска
FORM PHP DOC
Если для третьего параметра strict установлено значение TRUE, функция array_search () будет искать одинаковые элементы в стоге сена. Это означает, что он также проверяет типы иглы в стоге сена, а объекты должны быть одного и того же экземпляра.
Becasue первый элемент 0
строка была преобразована в 0
во время поиска
Простой тест
var_dump("sharp" == 0); //true var_dump("sharp" === 0); //false
Решение использует strict
вариант для поиска идентичных значений
$testsharp = array_search("sharp", $testcopy,true); ^---- Strict Option var_dump($testsharp);
Вывод
10
Если какой-либо ключ перед поисковым номером равен нулю , то этот ключ возвращается, потому что он выполняет «свободное» соответствие, в котором доминирует тип данных массива , а «sharp» (если преобразован в int
) считается равным нулю. Используя строгую проверку, найдено правильное значение.
В противном случае, выполняя
$testcopy = array_map('strval', $testcopy);
так что значения переводятся в строки, он также работает с «свободной» проверкой.
Добро пожаловать в прекрасный мир свободной печати. В php, array_search по умолчанию использует нестрогое сравнение ("=="), но вы можете добавить третий параметр, чтобы принудительно выполнить строгую ("==="). Вы почти всегда хотите строгого, хотя бывают случаи, когда нестрогая правильная операция.
проверьте следующее:
$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"; }
и выход:
[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 ===