Php array search не работает

array_search — Ошибка

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

array_search — Осуществляет поиск данного значения в массиве и возвращает соответствующий ключ в случае удачи

Описание

Ищет в haystack значение needle .

Список параметров

Если needle является строкой, сравнение происходит с учетом регистра.

Если третий параметр strict установлен в TRUE , то функция array_search() будет искать идентичные элементы в haystack . Это означает, что также будут проверяться типы needle в haystack , а объекты должны быть одни и тем же экземпляром.

Возвращаемые значения

Возвращает ключ для needle , если он был найден в массиве, иначе FALSE .

Если needle присутствует в haystack более одного раза, будет возвращён первый найденный ключ. Для того, чтобы возвратить ключи для всех найденных значений, используйте функцию array_keys() с необязательным параметром search_value .

Эта функция может возвращать как boolean FALSE , так и не-boolean значение, которое приводится к FALSE . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.

Список изменений

Версия Описание
5.3.0 Вместе со всеми внутренними функциями PHP начиная с 5.3.0, array_search() возвращает NULL , если ей были переданы неверные параметры.
4.2.0 До PHP 4.2.0, array_search() при неудаче возвращал NULL вместо FALSE .

Примеры

Пример #1 Пример использования array_search()

= array( 0 => ‘blue’ , 1 => ‘red’ , 2 => ‘green’ , 3 => ‘red’ );

$key = array_search ( ‘green’ , $array ); // $key = 2;
$key = array_search ( ‘red’ , $array ); // $key = 1;
?>

Смотрите также

  • array_keys() — Возвращает все или некоторое подмножество ключей массива
  • array_values() — Выбирает все значения массива
  • array_key_exists() — Проверяет, присутствует ли в массиве указанный ключ или индекс
  • in_array() — Проверяет, присутствует ли в массиве значение

Источник

array_search не может найти элемент, который явно там

Почему работает следующий код:

Но следующее не делает:

Если бы у вас был смешанный массив, скажем, из mysql_fetch_array ($ result, MYSQL_BOTH) и вы взяли ключи, которые вам нужны для поиска, вы бы тоже не смогли — он никогда не прогрессировал бы дальше 0.

Решение

Стараться сделать array_search(‘test4’,$test, TRUE); , 3-й параметр говорит ему использовать === вместо == при сравнении.

Поскольку ваш массив содержит как строки, так и числа, когда он сравнивается с 0 (1-й элемент), он преобразует ‘test4’ на номер (он останавливается на 1-м нечисловом символе) и он совпадает.

Я имею в виду: ‘test4’ == 0 => 0 == 0 => true ,

Когда вы проходите TRUE в качестве третьего параметра он использует === , а также ‘test4’ === 0 автоматически false так как типы не совпадают, нет преобразования.

Другие решения

Решение = заставить значение 0 быть строкой:

Вы не можете найти номер для строки и ожидать хорошего результата.

Я предполагаю, что он видит значение как число, поэтому он преобразует вашу строку в число (что не может), так что строка преобразуется в 0. Таким образом, значение 0 равно строке поиска, которая также равна 0, и вот твой результат.

Если значение равно 1, оно не будет совпадать, так как строка поиска преобразуется в 0 (поскольку вы не можете преобразовать строку в число), поэтому она не будет соответствовать следующему.

$ test = array (0 => 1, ‘field0’ => ‘test2’, 1 => ‘test3’, ‘field1’ => ‘test4’);

Вы получите точный сценарий, только когда это значение в массиве равно 0.

Источник

Php array search не работает

В этой статье, я разберу одну достаточно частную и частую проблему, которая может возникнуть в процессе разработки на php. Эта проблема является отражением не столько проблем организации языка программирования php, сколько не полного понимания некоторых особенностей этого языка начинающими программистами.

При работе в php очень часто приходится иметь дело с массивами, и в частности иногда встает задача поиска элемента в массиве, совпадающего с некоторым искомым значением. Для решения этой частной задачи, очень удобно пользоваться функцией:

Согласно документации php, функция осуществляет поиск по массиву $haystack и ищет в нем элемент, значение которого совпадает со значением $needle. В качестве результата, функция возвращает либо ключ элемента в массиве (читай «номер элемента в списке»), либо, если ничего не найдено — возвращает ошибку «false». В общем-то, кажется что все нормально и логично. Однако, могут возникать ситуации, когда ответы возвращаемые этой функцией могут ввести в заблуждение и приводить к ошибкам работы разрабатываемого скрипта. Приведу для наглядности конкретные примеры, когда array_search() как будто бы перестает работать.

Случай первый.

в результате исполнения кода получим на первый взгляд странный ответ – «город не найден». То есть элемент совпадающий с «Москва» в массиве есть, но он почему-то не «ищется» ….

Случай второй.

Аналогичная ситуация. Элемент в массиве совершенно очевидно присутствует, но в качестве результата мы получаем ответ, что «элемент не найден».

Случай третий.

Аналогично – получаем ответ «элемент не найден».

Случай четвертый.

Тоже самое, при исполнении кода получим на мониторе «элемент не найден».

Случай пятый.

«И опять, двадцать пять»…. Как говорится.

Причина возникающей ошибки и ее решение.

На самом деле причина возникающих ошибок кроется не в самой функции array_search(), а в том какой результат она возвращает и как мы его проверяем. Дело в том, что в php, как и в большинстве других языков программирования, при обработке информации, важное значение имеет не только конкретное значение переменной, но и тип данных, к которым она относится.

В частности в данном случае, функция возвращает либо «false» (тип данных boolean), либо ключ элемента в массиве. Этот ключ может представлять собой или целое число (integer), или строку (string), или вещественное число с десятичной добью (float), или специфический тип данных, обозначающий неопределенное значение (NULL). И ошибка в выше приведенных примерах связана с тем, что некоторые значения не boolean данных могут быть преобразованы в boolean. В частности, согласно самой справки php, следующие значение могут быть преобразованы в булев «false»:

  • само значение booleanFALSE
  • integer 0 (ноль)
  • float 0.0 (ноль)
  • пустая строка, и строка «0»
  • массив без элементов
  • объект без полей (только для PHP 4)
  • особый тип NULL (включая неустановленные переменные)
  • Объекты SimpleXML, созданные из пустых тегов
  • Все остальные значения рассматриваются как TRUE (включая любой resource).

Разберем каждый из перечисленных выше примеров.

Случай первый.

По умолчанию, нумерация ключей элементов массива начинается с 0, если не задано иначе специально. Соответственно, функция array_search() вернула правильный результат – номер ключа 0 (integer, целое число), но при сравнении этот результат был приведен к булеву «false», а это в свою очередь выполнило условие, что «элемент не найден».

Случай второй.

Заданы ключи элементов массива, которые являются строками, но при этом ключ искомого элемента равен пустой строке «». И при проверке условия, эта пустая строка была интерпретирована как булев «false», что опять же выполнило условие для вывода «элемент не найден».

Случай третий.

Ключи массива заданы строками, при этом ключ искомого элемента равен строке «0». Именно строке, не целому числу, а строке. Именно этот ключ функция вернула, но при проверке это значение было приведено к boolean «false».

Случай четвертый.

Ключи элементов массива заданы в виде чисел с плавающей точкой (float). Ключ целевого элемента массива оказался равен нулю (0.0), который при сравнении был рассмотрен как «false», что выполнило условие для вывода результата о том, что элемент в массиве не найден.

Случай пятый.

Думаю, что уже ясно. Там ключ нужного нам элемента массива задан специальным значением NULL, которое при сравнении в блоке условия было воспринято как булев «false» — ошибка.

Решение.

Решением данной ошибки, является более строгая проверка результата работы функции array_search(). Во всех перечисленных примерах выше проверялось лишь значение возвращенного результата, без проверки типа данных к которым относится полученный ответ. Поэтому для наглядности, следовало бы во всех выше перечисленных примерах вместо строки

то есть в таком случае мы не только проверяем значение ответа функции, но и убеждаемся (в данном случае), что оно он относится к типу данных boolean.

Функция is_bool() проверяет – относится ли переданное ей значение к типу boolean.

Но, конечно же, обычно так условие никто не записывает. Так как есть специальный оператор «тождественно равно» (===) и ему противоположный «тождественно не равно» (!==). Это операторы строгой проверки, когда проверяется не только конкретное значение присланной переменной, но и тип ее данных. Поэтому для исправления ошибки во всех приведенных примерах, в блоке условия проверку следует переписать так:

тогда мы начнем получать правильные ответы от работы кода.

Обобщение.

Вообще говоря, строгая проверка, о которой говорится в этой статье, полезна и для многих других функций php, которые могут возвращать либо ошибку «false», либо какое-то вычисленное, найденное, извлеченное значение… Потому, что иногда вычисленное, найденное, извлеченное значение может совпадать со значением «false», хотя и относиться к другому типу данных (то есть любой тип данных кроме boolean).

Например: mysql_query() функция осуществляет запрос к базе данных. И при запросах SELECT — в качестве ответа возвращает результат выборки из базы данных, либо «false» — в случае ошибки. А если в целевой ячейке таблицы базы данных записано NULL, или 0, или 0.0, или «» (пустая строка, ничего не записано) – то при дальнейшей проверке мы можем опять же получить некорректную работу нашего скрипта. Чтобы этого не происходило, нужно опять же пользоваться оператором строго сравнения «===» или «!==».

Так что будьте внимательны. И не забывайте про типы данных, которые могут помещаться в переменные используемые в Вашем коде. И многих проблем можно избежать сразу.

Если информация этой статьи будет интересна и полезна Вашему кругу друзей и знакомых, то Вы можете опубликовать ссылку — тогда им проще будет ее найти. Они Вам будут благодарны:).

Источник

Есть код php, который не пропускает формат jpeg, в чем проблема я уже понял, когда он находит формат jpeg в массиве, возвращает true и следом порядковый номер элемента, а номер элемента 0 и условие интерпретирует его как false. Как решить эту проблему?

1 ответ 1

Эта функция может возвращать как логическое значение FALSE, так и значение не типа boolean, которое приводится к FALSE. За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.
https://www.php.net/manual/ru/function.array-search.php

Из чего следует, что вам необходимо использовать оператор === , а вашем случае его эквивалент НЕ равно: !== .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками php или задайте свой вопрос.

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.10.19.40496

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

(PHP 4 >= 4.0.5, PHP 5, PHP 7, PHP 8)

array_search — Осуществляет поиск данного значения в массиве и возвращает ключ первого найденного элемента в случае успешного выполнения

Описание

Ищет в haystack значение needle .

Список параметров

Если needle является строкой, сравнение происходит с учётом регистра.

Если третий параметр strict установлен в true , то функция array_search() будет искать идентичные элементы в haystack . Это означает, что также будут проверяться типы needle в haystack , а объекты должны быть одним и тем же экземпляром.

Возвращаемые значения

Возвращает ключ для needle , если он был найден в массиве, иначе false .

Если needle присутствует в haystack более одного раза, будет возвращён первый найденный ключ. Для того, чтобы возвратить ключи для всех найденных значений, используйте функцию array_keys() с необязательным параметром search_value .

Эта функция может возвращать как логическое значение false , так и значение не типа boolean, которое приводится к false . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.

Примеры

Пример #1 Пример использования array_search()

= array( 0 => ‘blue’ , 1 => ‘red’ , 2 => ‘green’ , 3 => ‘red’ );

$key = array_search ( ‘green’ , $array ); // $key = 2;
$key = array_search ( ‘red’ , $array ); // $key = 1;
?>

Смотрите также

  • array_keys() — Возвращает все или некоторое подмножество ключей массива
  • array_values() — Выбирает все значения массива
  • array_key_exists() — Проверяет, присутствует ли в массиве указанный ключ или индекс
  • in_array() — Проверяет, присутствует ли в массиве значение

User Contributed Notes 46 notes

in (PHP 5 >= 5.5.0) you don’t have to write your own function to search through a multi dimensional array

$userdb=Array
(
(0) => Array
(
(uid) => ‘100’,
(name) => ‘Sandra Shush’,
(url) => ‘urlof100’
),

(1) => Array
(
(uid) => ‘5465’,
(name) => ‘Stefanie Mcmohn’,
(pic_square) => ‘urlof100’
),

(2) => Array
(
(uid) => ‘40489’,
(name) => ‘Michael’,
(pic_square) => ‘urlof40489’
)
);

simply u can use this

$key = array_search(40489, array_column($userdb, ‘uid’));

About searcing in multi-dimentional arrays; two notes on «xfoxawy at gmail dot com»;

It perfectly searches through multi-dimentional arrays combined with array_column() (min php 5.5.0) but it may not return the values you’d expect.

( $needle , array_column ( $array , ‘key’ )); ?>

Since array_column() will produce a resulting array; it won’t preserve your multi-dimentional array’s keys. So if you check against your keys, it will fail.

= array(
2 => array(
‘name’ => ‘John’ ,
‘fav_color’ => ‘green’
),
5 => array(
‘name’ => ‘Samuel’ ,
‘fav_color’ => ‘blue’
)
);

$found_key = array_search ( ‘blue’ , array_column ( $people , ‘fav_color’ ));
?>

Here, you could expect that the $found_key would be «5» but it’s NOT. It will be 1. Since it’s the second element of the produced array by the array_column() function.

Secondly, if your array is big, I would recommend you to first assign a new variable so that it wouldn’t call array_column() for each element it searches. For a better performance, you could do;

= array_column ( $people , ‘fav_color’ );
$found_key = array_search ( ‘blue’ , $colors );
?>

I needed a function, that returns a value by specifying a keymap to the searched value in a multidimensional array and came up with this.

$s is the keymap to the needle and $a the haystack array.

// search keymap $s in array $a
function get_key_in_array ( $s , $a )
<
if( is_array ( $s ) && is_array ( $a [ key ( $s )])) <
return get_key_in_array ( reset ( $s ), $a [ key ( $s )]);
> else <
if( is_array ( $s )) $s = reset ( $s );
return isset( $a [ $s ])? $a [ $s ]: false ;
>
>

$s = [ ‘foo’ =>[ ‘bar’ => ‘baz’ ]];
var_dump ( get_key_in_array ( $s , $arr ));

$s = [ ‘foo’ =>[ ‘bar’ =>[ ‘baz’ ]]];
var_dump ( get_key_in_array ( $s , $arr ));

$s = [ ‘foo’ =>[ ‘bar’ =>[ ‘nix’ ]]];
var_dump ( get_key_in_array ( $s , $arr ));

$s = [ ‘foo’ => ‘bar’ ];
var_dump ( get_key_in_array ( $s , $arr ));

$s = [ ‘foo’ ];
var_dump ( get_key_in_array ( $s , $arr ));

$s = ‘foo’ ;
var_dump ( get_key_in_array ( $s , $arr ));

$array = [‘a’, ‘b’, ‘c’];
$key = array_search(‘a’, $array); //$key = 0
if ($key)
<
//even a element is found in array, but if (0) means false
//.
>

It’s what the document stated «may also return a non-Boolean value which evaluates to FALSE.»

About searcing in multi-dimentional arrays;
note on «xfoxawy at gmail dot com»:

If you use your own keys in a multidimensional array, this will not work. Better use for this situation:

array_search($searchingValue, array_map(function($val), $inputArray));

the recursive function by tony have a small bug. it failes when a key is 0

here is the corrected version of this helpful function:

function recursive_array_search ( $needle , $haystack ) <
foreach( $haystack as $key => $value ) <
$current_key = $key ;
if( $needle === $value OR ( is_array ( $value ) && recursive_array_search ( $needle , $value ) !== false )) <
return $current_key ;
>
>
return false ;
>
?>

If you are using the result of array_search in a condition statement, make sure you use the === operator instead of == to test whether or not it found a match. Otherwise, searching through an array with numeric indicies will result in index 0 always getting evaluated as false/null. This nuance cost me a lot of time and sanity, so I hope this helps someone. In case you don’t know what I’m talking about, here’s an example:

= array( «a» , «b» , «a» , «c» , «a» , «b» , «b» ); // infamous abacabb mortal kombat code 😛

// this is WRONG
while (( $key = array_search ( «a» , $code )) != NULL )
<
// infinite loop, regardless of the unset
unset( $code [ $key ]);
>

// this is _RIGHT_
while (( $key = array_search ( «a» , $code )) !== NULL )
<
// loop will terminate
unset( $code [ $key ]);
>
?>

Despite PHP’s amazing assortment of array functions and juggling maneuvers, I found myself needing a way to get the FULL array key mapping to a specific value. This function does that, and returns an array of the appropriate keys to get to said (first) value occurrence.

function array_recursive_search_key_map($needle, $haystack) <
foreach($haystack as $first_level_key=>$value) <
if ($needle === $value) <
return array($first_level_key);
> elseif (is_array($value)) <
$callback = array_recursive_search_key_map($needle, $value);
if ($callback) <
return array_merge(array($first_level_key), $callback);
>
>
>
return false;
>

$nested_array = $sample_array = array(
‘a’ => array(
‘one’ => array (‘aaa’ => ‘apple’, ‘bbb’ => ‘berry’, ‘ccc’ => ‘cantalope’),
‘two’ => array (‘ddd’ => ‘dog’, ‘eee’ => ‘elephant’, ‘fff’ => ‘fox’)
),
‘b’ => array(
‘three’ => array (‘ggg’ => ‘glad’, ‘hhh’ => ‘happy’, ‘iii’ => ‘insane’),
‘four’ => array (‘jjj’ => ‘jim’, ‘kkk’ => ‘kim’, ‘lll’ => ‘liam’)
),
‘c’ => array(
‘five’ => array (‘mmm’ => ‘mow’, ‘nnn’ => ‘no’, ‘ooo’ => ‘ohh’),
‘six’ => array (‘ppp’ => ‘pidgeon’, ‘qqq’ => ‘quail’, ‘rrr’ => ‘rooster’)
)
);

$array_keymap = array_recursive_search_key_map($search_value, $nested_array);

But again, with the above solution, PHP again falls short on how to dynamically access a specific element’s value within the nested array. For that, I wrote a 2nd function to pull the value that was mapped above.

function array_get_nested_value($keymap, $array)
<
$nest_depth = sizeof($keymap);
$value = $array;
for ($i = 0; $i

Be careful when search for indexes from array_keys() if you have a mixed associative array it will return both strings and integers resulting in comparison errors

// This syntax is allowed by PHP
$arr = array(
«nice» ,
«car» => «fast» ,
«none»
);

// Print the keys
var_dump ( array_keys ( $arr ));

/* The above prints this, as you can see we have mixed keys
array(3) <
[0]=>
int(0)
[1]=>
string(3) «car»
[2]=>
int(1)
>
*/

// Search for the index «car»
var_dump ( array_search ( «car» , array_keys ( $arr ))); // Prints «int(0)» which is WRONG
?>

This happens because PHP, when comparing strings and integers, casts strings TO integers and this results in most of the cases in string becoming 0, so that’s why when array_search() compares the first index (0) with the key «car» it gets true because apparently («car» == 0) IS TRUE.
Setting array_search() to strict mode won’t solve the problem because then array_search(«0», array_keys($arr)) would return false even if an element with index 0 exists.
So my solution just converts all indexes from array_keys() to strings and then compares them correctly:

( array_search ( «car» , array_map ( «strval» , array_keys ( $arr )))); // Prints «int(1)» which is CORRECT
?>

for searching case insensitive better this:

( strtolower ( $element ), array_map ( ‘strtolower’ , $array ));
?>

hallo every body This function matches two arrays like
search an array like another or not array_match which can match

if ($keys1 === $keys2 && $values1 === $values2)
<

if ($keys1 == $keys2 && $values1 == $values2)
<

About searcing in multi-dimentional arrays;
note on «xfoxawy at gmail dot com» and turabgarip at gmail dot com;

$xx = array_column($array, ‘NAME’, ‘ID’);
will produce an array like :
$xx = [
[ID_val] => NAME_val
[ID_val] => NAME_val
]

$yy = array_search(‘tesxt’, array_column($array, ‘NAME’, ‘ID’));
will output expected ID;

By extension of `sunelbe at gmail dot com` solution to search for a specific array element with key value in a multidimensional array, this one also returns the parent.

function array_search_multi (
$array ,
$key ,
$value ,
$parent = false
) <
$results = array();

foreach ( $array as $id => $subarray ) <
$found = array_search_multi (
$subarray , $key , $value
);

if(!empty( $found )) <
if( $parent ) <
$results [ $id ] =
$array [ $id ];
> else <
$results = $found ;
>
>
>
>

$array = array(
‘key1’ => array(
‘ID’ => 1 ,
‘key2’ => array(
‘ID’ => 2 ,
‘key3’ => array(
‘ID’ => 3
)
)
),
‘key4’ => 4 ,
‘key6’ => array(
‘ID’ => 5 ,
‘key7’ => array(
‘ID’ => 6 ,
‘key8’ => array(
‘ID’ => 7 ,
‘value’ => ‘test’
)
)
)
);

array_search_multi ( $array , ‘ID’ , 7 , false );

[ 0 ] => Array
(
[ ID ] => 7
[ value ] => test
)

array_search_multi ( $array , ‘ID’ , 7 , true );

[ key6 ] => Array
(
[ ID ] => 5
[ key7 ] => Array
(
[ ID ] => 6
[ key8 ] => Array
(
[ ID ] => 7
[ value ] => test
)

I was going to complain bitterly about array_search() using zero-based indexes, but then I realized I should be using in_array() instead.

// if ( isset( $_GET[‘table’] ) and array_search( $_GET[‘table’], $valid_tables) ) < // BAD: fails on first[0] element
// if ( isset( $_GET[‘table’] ) and ( FALSE !== array_search( $_GET[‘table’], $valid_tables) ) ) < OK: but wasteful and convoluted
if ( isset( $_GET[‘table’] ) and in_array( $_GET[‘table’], $valid_tables) ) < // BETTER

The essence is this: if you really want to know the location of an element in an array, then use array_search, else if you only want to know whether that element exists, then use in_array()

hey i have a easy multidimensional array search function

function search ( $array , $key , $value )
<
$results = array();

foreach ( $array as $subarray )
$results = array_merge ( $results , search ( $subarray , $key , $value ));
>

Better solution of multidimensional searching.

function multidimensional_search ( $parents , $searched ) <
if (empty( $searched ) || empty( $parents )) <
return false ;
>

$parents = array();
$parents [] = array( ‘date’ => 1320883200 , ‘uid’ => 3 );
$parents [] = array( ‘date’ => 1320883200 , ‘uid’ => 5 );
$parents [] = array( ‘date’ => 1318204800 , ‘uid’ => 5 );

echo multidimensional_search ( $parents , array( ‘date’ => 1320883200 , ‘uid’ => 5 )); // 1
?>

I needed a way to return the value of a single specific key, thus:

function recursive_return_array_value_by_key ( $needle , $haystack ) <
$return = false ;
foreach( $haystack as $key => $val ) <
if( is_array ( $val )) <
$return = recursive_return_array_value_by_key ( $needle , $val );
>
else if( $needle === $key ) <
return » $val \n» ;
>
>
return $return ;
>

To expand on previous comments, here are some examples of
where using array_search within an IF statement can go
wrong when you want to use the array key thats returned.

Take the following two arrays you wish to search:

= array( «apple» , «pear» , «orange» );
$fruit_array = array( «a» => «apple» , «b» => «pear» , «c» => «orange» );

if ( $i = array_search ( «apple» , $fruit_array ))
//PROBLEM: the first array returns a key of 0 and IF treats it as FALSE

if ( is_numeric ( $i = array_search ( «apple» , $fruit_array )))
//PROBLEM: works on numeric keys of the first array but fails on the second

if ( $i = is_numeric ( array_search ( «apple» , $fruit_array )))
//PROBLEM: using the above in the wrong order causes $i to always equal 1

if ( $i = array_search ( «apple» , $fruit_array ) !== FALSE )
//PROBLEM: explicit with no extra brackets causes $i to always equal 1

if (( $i = array_search ( «apple» , $fruit_array )) !== FALSE )
//YES: works on both arrays returning their keys
?>

FYI, remember that strict mode is something that might save you hours.

If you’re searching for a string and you have a «true» boolean on the way — you will get it as result (first occurrence). Example below:

var_dump ( array_search ( ‘xyz’ , $arr ) ); //bool
var_dump ( array_search ( ‘xyz’ , $arr , true ) ); //target

one thing to be very aware of is that array_search() will fail if the needle is a string and the array itself contains values that are mixture of numbers and strings. (or even a string that looks like a number)

The problem is that unless you specify «strict» the match is done using == and in that case any string will match a numeric value of zero which is not what you want.

also, php can lookup an index pretty darn fast. for many scenarios, it is practical to maintain multiple arrays, one in which the index of the array is the search key and the normal array that contains the data.

[ $index ] = array( ‘key’ => $key , ‘data’ => ‘foo’ );
$inverse [ $key ] = $index ;

//very fast lookup, this beats any other kind of search

if ( array_key_exists ( $key , $inverse ))
<
$index = $inverse [ $key ];
return $normal [ $index ];
>

A better array_isearch would be to store all results in an array, then return the KEYS stored in $found, such as:

function array_isearch ( $str , $array ) <
$found = array();
foreach ( $array as $k => $v )
if ( strtolower ( $v ) == strtolower ( $str )) $found [] = $k ;
return $found ;
>
?>

To use, simply have an array to search from then search it, for example:

function array_isearch ( $str , $array ) <
$found = array();
foreach( $array as $k => $v )
if( strtolower ( $v ) == strtolower ( $str )) $found [] = $k ;
return $found ;
>

$stored = «these are an array» ;
$stored = explode ( » » , $stored );

$compare = array( «these» , «are» , «some» , «results» , «stored» , «in» , «an» , «array» );
foreach( $stored as $store ) <
$results = array_isearch ( $store , $compare );
foreach( $results as $key => $result )
echo «Key: » . $results [ $key ]. «
Found: » . $compare [ $result ]. «
» ;
>

I had an array of arrays and needed to find the key of an element by comparing actual reference.
Beware that even with strict equality (===) php will equate arrays via their elements recursively, not by a simple internal pointer check as with class objects. The === can be slow for massive arrays and also crash if they contain circular references.

This function performs reference sniffing in order to return the key for an element that is exactly a reference of needle.

$valA = 1 ; $valB = 1 ;
echo ‘array_ref_search: ‘ , array_ref_search ( $valB , $list ), ‘ ‘ ; // key ‘B’
echo ‘array_search: ‘ , array_search ( $valB , $list , true ), ‘ ‘ ; // key ‘A’

$valA = array( 1 , 2 , 3 ); $valB = array( 1 , 2 , 3 );
echo ‘array_ref_search: ‘ , array_ref_search ( $valB , $list ), ‘ ‘ ; // key ‘B’
echo ‘array_search: ‘ , array_search ( $valB , $list , true ), ‘ ‘ ; // key ‘A’ because ($valA === $valB) is true by elements

$valB [] = & $valB ; // circular reference
echo ‘array_ref_search: ‘ , array_ref_search ( $valB , $list ), ‘ ‘ ; // key ‘B’
echo ‘array_search: ‘ , array_search ( $valB , $list , true ), ‘ ‘ ; // crash because ($valB === $valB) causes infinite loop
?>

A simple recursive array_search function :

function recursive_array_search ( $needle , $haystack ) <
foreach( $haystack as $key => $value ) <
$current_key = $key ;
if( $needle === $value OR ( is_array ( $value ) && recursive_array_search ( $needle , $value ))) <
return $current_key ;
>
>
return false ;
>
?>

Warning, array_search() and in_array() both search for values exactly matching the value of an element, and don’t match if a value is within the value of an element. Example:

$a = array(«test»);
if (array_search(«te», $a) !== false)
echo «found»;
else
echo «not found»;

// outputs «not found»

You’ll need to iterate the array with a strpos() check if you’d like to search for a value within a value of an array.

foreach ($a as $val) <
if (strpos($val, «te») !== false) <
echo «found»
>
>
// outputs «found»

My function get_key_in_array() needed some improvement:

( array_search ( ‘needle’ , [ 0 => 0 ])); // int(0) (!)

var_dump ( array_search ( ‘needle’ , [ 0 => 0 ], true )); // bool(false)

( array_search ( ‘needle’ , [ 0 => 0 ])); // bool(false)

An implementation of a search function that uses a callback, to allow searching for objects of arbitrary complexity:

function array_usearch (array $array , Closure $test ) <
$found = false ;
$iterator = new ArrayIterator ( $array );

return $found ;
>
?>

The above takes a closure, rather than a callable, but that could easily be altered. Like array_search, this will return false if no match is found. I made the closure the last parameter in case php one day implements trailing-closure syntax.

For instance, if you have an array of objects with an id property, you could search for the object with a specific id like this:

class Thing <
public $id ;
public $name ;

public function __construct ( $id , $name , $category ) <
$this -> id = $id ;
$this -> name = $name ;
>
>

$listOfThings = [
new Thing ( 1 , ‘one’ ),
new Thing ( 2 , ‘two’ ),
new Thing ( 3 , ‘three’ ),
new Thing ( 4 , ‘four’ ),
];

$id4Index = array_usearch ( $listOfThings , function( $thing ) <
return $thing -> id === 4 ;
>);
?>

Since the Closure can capture information, it becomes simple to write a function that takes search criteria as parameters, creates a closure with those criteria, and calls the above. A simple example that does the same search as above would be

= function( $id ) <
return function( $item ) use ( $id ) <
return $item -> id = $id ;
>
>

$id4Index = array_usearch ( $idClosure ( 4 ));
?>

It’s more complex to set up, but now any search for an id can be written in a single line, making things clean and concise.

For a more complex example, this function takes an array of key/value pairs and returns the key for the first item in the array that has all those properties with the same values.

function firstIndexMatching (array $array , array $criteria , bool $useStrict = true ) <

if ( count ( $criteria ) 1 ) <
return false ;
>

// create a closure that has captured the search criteria
$testWithCriteria = function( $criteria , $useStrict ) <

return function( $item ) use ( $criteria , $useStrict ) <

return array_usearch ( $array , $testWithCriteria ( $criteria , $useStrict ));
>
?>

If you have a list of people, for instance, you can now simply find the person record with a specific first and last name:

= firstIndexMatching ( $people , [
‘firstName’ => ‘Joe’ ,
‘lastName’ => ‘Schlabotnik’
]);
?>

Obviously firstIndexMatching could be modified to use case-insensitive comparisons or anything else that fits your use-case. They idea is capturing the input data.

The final step is a function that returns the item, rather than its key, or null if no match found:

function firstItemMatching (array $array , array $criteria , bool $useStrict = true ) <
// fun fact: $array[false] is equivalent to $array[0]
$index = firstIndexMatching ( $array , $criteria , $useStrict );
return $index !== false ? $array [ $index ] ?? null : null ;
>
?>

Источник

Читайте также:  Как починить двигатель насоса
Оцените статью