PHP Conference Japan 2024
添加注释

用户贡献的注释 17 个注释

228
turabgarip at gmail dot com
7 年前
关于在多维数组中搜索;关于“xfoxawy at gmail dot com”的两点说明;

它与 array_column()(PHP 5.5.0 或更高版本)结合使用时可以完美地搜索多维数组,但返回的结果可能与您预期的不符。

<?php array_search($needle, array_column($array, 'key')); ?>

由于 array_column() 将生成一个结果数组;它不会保留多维数组的键。因此,如果您检查键,它将会失败。

例如;

<?php
$people
= 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'));
?>

在这里,您可能会期望 $found_key 为“5”,但事实并非如此。它将是 1。因为它是由 array_column() 函数生成的数组的第二个元素。

其次,如果您的数组很大,我建议您先分配一个新变量,这样它就不会为每个搜索的元素调用 array_column()。为了获得更好的性能,您可以这样做:

<?php
$colors
= array_column($people, 'fav_color');
$found_key = array_search('blue', $colors);
?>
53
cue at openxbox dot com
21 年前
如果您在条件语句中使用 array_search 的结果,请确保使用 === 运算符而不是 == 来测试是否找到了匹配项。否则,搜索具有数字索引的数组将导致索引 0 始终被评估为 false/null。这种细微差别让我花费了大量时间和精力,所以我希望这能帮助到某些人。如果您不知道我在说什么,这里有一个例子

<?php
$code
= array("a", "b", "a", "c", "a", "b", "b"); // 臭名昭著的abacabb真人快打代码 :-P

// 这是错误的
while (($key = array_search("a", $code)) != NULL)
{
// 无限循环,无论是否使用unset
unset($code[$key]);
}

// 这是正确的
while (($key = array_search("a", $code)) !== NULL)
{
// 循环将会终止
unset($code[$key]);
}
?>
33
stefano@takys dot it
13年前
对于不区分大小写的搜索,最好使用这个

<?php
array_search
(strtolower($element),array_map('strtolower',$array));
?>
15
RichGC
18年前
为了扩展之前的评论,这里有一些例子
说明在IF语句中使用array_search可能会出错的地方
当你想要使用返回的数组键时。

假设你想要搜索以下两个数组

<?php
$fruit_array
= array("apple", "pear", "orange");
$fruit_array = array("a" => "apple", "b" => "pear", "c" => "orange");

if (
$i = array_search("apple", $fruit_array))
//问题:第一个数组返回的键为0,IF将其视为FALSE

if (is_numeric($i = array_search("apple", $fruit_array)))
//问题:适用于第一个数组的数字键,但第二个数组失败

if ($i = is_numeric(array_search("apple", $fruit_array)))
//问题:以上顺序错误会导致$i始终等于1

if ($i = array_search("apple", $fruit_array) !== FALSE)
//问题:显式使用,没有额外的括号会导致$i始终等于1

if (($i = array_search("apple", $fruit_array)) !== FALSE)
//正确:适用于两个数组,返回它们的键
?>
15
maciej at speccode dot com
9年前
仅供参考,记住严格模式可能会为你节省数小时的时间。

如果你正在搜索一个字符串,并且途中有一个“true”布尔值 - 你会得到它作为结果(第一次出现)。如下例所示

<?php

$arr
= [
'foo' => 'bar',
'abc' => 'def',
'bool' => true,
'target' => 'xyz'
];

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

?>
8
thinbegin at gmail dot com
6年前
尽管PHP拥有令人惊叹的数组函数和杂耍技巧,但我发现自己需要一种方法来获取与特定值完全匹配的数组键映射。此函数可以做到这一点,并返回一个包含到达该(第一个)值出现的相应键的数组。

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')
)
);

$search_value = 'insane';

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

var_dump($array_keymap);
// 输出
// array(3) {
// [0]=>
// string(1) "b"
// [1]=>
// string(5) "three"
// [2]=>
// string(3) "iii"
//}

----------------------------------------------

但是,对于上述解决方案,PHP再次在如何动态访问嵌套数组中特定元素的值方面存在不足。为此,我编写了第二个函数来提取上面映射的值。

function array_get_nested_value($keymap, $array)
{
$nest_depth = sizeof($keymap);
$value = $array;
for ($i = 0; $i < $nest_depth; $i++) {
$value = $value[$keymap[$i]];
}

return $value;
}

使用示例
-------------------
echo array_get_nested_value($array_keymap, $nested_array); // insane
6
opencart dot ocfilter at gmail dot com
3年前
小心!

<?php

var_dump
(array_search('needle', [ 0 => 0 ])); // int(0) (!)

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

?>

但是,在PHP 8中

<?php

var_dump
(array_search('needle', [ 0 => 0 ])); // bool(false)

?>
2
yasien dot dwieb at gmail dot com
4年前
当对混合使用字符串和整数的数组使用array_search时要小心,因为键的前缀可能会冲突,在我的例子中,我遇到了以下情况

假设你拥有以下数组
<?php
$arr
= [
1 => 'index 0',
2 => 'index 1',
3 => 'index 2',
'3anothersuffix' => 'index 3'
];

$index1 = array_search('3', array_keys($arr)); // 2
$index2 = array_search('3anothersuffix', array_keys($arr)); //2
?>

$index1和$index2将相同

使用严格类型搜索后

<?php
$index1
= array_search('3', array_keys($arr), true); // false
$index2 = array_search('3anothersuffix', array_keys($arr), true); //3
?>

它根本找不到$index1,而对于$index2返回正确的值;
3
azaozz, gmail
15年前
扩展hansen{}cointel.de的评论

当搜索字符串并且数组包含0(零)时,字符串将通过类型转换强制转换为(int),结果始终为0(也许相反的行为才是正确的,数组值0应该被转换为字符串)。如果未使用严格比较,则会产生意外的结果

<?php
$a
= array(0, "str1", "str2", "str3");
echo
"
str1 = "
.array_search("str1", $a).",
str2 = "
.array_search("str2", $a).",
str3 = "
.array_search("str3", $a).",

str1 strict = "
.array_search("str1", $a, true).",
str2 strict = "
.array_search("str2", $a, true).",
str3 strict = "
.array_search("str3", $a, true);
?>

这将返回
str1 = 0, str2 = 2, str3 = 3, str1 strict = 1, str2 strict = 2, str3 strict = 3
3
andreas dot damm at maxmachine dot de
16年前
结合array_search()的语法和array_keys()的功能,获取具有给定搜索值的数组的所有键值关联
<?php
function array_search_values( $m_needle, $a_haystack, $b_strict = false){
return
array_intersect_key( $a_haystack, array_flip( array_keys( $a_haystack, $m_needle, $b_strict)));
}
?>

用法
<?php
$array1
= array( 'pre'=>'2', 1, 2, 3, '1', '2', '3', 'post'=>2);
print_r( array_search_values( '2', $array1));
print_r( array_search_values( '2', $array1, true));
print_r( array_search_values( 2, $array1, true));
?>

将返回
array(4) {
["pre"] =>
string(1) "2"
[1] =>
int(2)
[4] =>
string(1) "2"
["post"] =>
int(2)
}
array(2) {
["pre"] =>
string(1) "2"
[4] =>
string(1) "2"
}
array(2) {
[1] =>
int(2)
["post"] =>
int(2)
}
5
codeslinger at compsalot dot com
15年前
需要注意的是,如果搜索值是字符串,而数组本身包含数字和字符串的混合值(甚至是看起来像数字的字符串),则array_search()将失败。

问题在于,除非指定“strict”,否则匹配使用 == 进行,在这种情况下,任何字符串都将匹配数值零,这并非你想要的结果。

-----

此外,PHP 可以非常快速地查找索引。对于许多场景来说,维护多个数组是可行的,其中一个数组的索引是搜索键,另一个数组包含数据。

<?php

$normal
[$index] = array('key'=>$key, 'data'=>'foo');
$inverse[$key] = $index;

//非常快速的查找,这比任何其他类型的搜索都要快

if (array_key_exists($key, $inverse))
{
$index = $inverse[$key];
return
$normal[$index];
}

?>
6
n-regen
15年前
如果你只知道数组中值的一部分,并且想知道完整的值,可以使用以下函数
<?php
function array_find($needle, $haystack)
{
foreach (
$haystack as $item)
{
if (
strpos($item, $needle) !== FALSE)
{
return
$item;
break;
}
}
}
?>
该函数返回包含$needle的$haystack的第一个完整值。
1
team at concerty dot com
一个月前
关于使用array_column在多维数组中搜索,补充“turabgarip at gmail dot com”的笔记,这里是一个查找正确键的解决方法

$array_column = 'name';
$searchValue = 'my value';
$result = array_filter($myArray, function ($subarray) use ($array_column, $searchValue) {
return isset($subarray[$array_column]) && $subarray[$array_column] === $searchValue;
});

echo key($result);
0
helenadeus at gmail dot com
15年前
我试图使用array_search检索所有与给定搜索值匹配的值,但事实证明只返回第一个匹配键。我构建了这个小函数,它就像array_search一样工作,但返回所有与给定搜索值匹配的键。输出是一个数组。

<?php

$haystack
= array('a','b','a','b');

$needle = 'a';

print_r(array_search_all($needle, $haystack));

//输出将是
// Array
// (
// [0]=>0
// [1]=>2
// )

function array_search_all($needle, $haystack)
{
#array_search_match($needle, $haystack) 返回$haystack中与$needle匹配的所有值的键

foreach ($haystack as $k=>$v) {

if(
$haystack[$k]==$needle){

$array[] = $k;
}
}
return (
$array);


}

?>
0
kermes [at] thesevens [dot] net
17年前
先前搜索的一个变体,返回与给定值匹配的键的数组

<?php
function array_ksearch($array, $str)
{
$result = array();
for(
$i = 0; $i < count($array); next($array), $i++)
if(
strtolower(current($array)) == strtolower($str))
array_push($result, key($array));

return
$result;
}
?>

用法如下
<?php
$testArray
= array('one' => 'test1', 'two' => 'test2', 'three' => 'test1', 'four' => 'test2', 'five' => 'test1');
print_r(array_ksearch($testArray, 'test1'));
?>
-1
stooshie at gmail dot com
13年前
返回索引而不是布尔值的递归二分查找示例。
<?php
// 返回 needle 在 haystack 中的索引
function binSearch($needle, $haystack)
{
// n 只在计算搜索深度时需要
global $n;
$n++;
// 获取传入数组的长度
$l = count($haystack);
// 如果长度为 0,则出现问题
if($l <= 0)
{
return -
1;
}
// 获取中间元素
$m = (($l+($l%2))/2);
// 如果中间值 >= 长度 (例如 l=1)
if($m >= $l)
{
$m = $m-1;
}
// 获取要与传入元素比较的索引元素,并根据情况进行分支
$compare = $haystack[$m];
switch(
true)
{
case(
$compare>$needle):
{
// 对下半部分递归
$new_haystack = array_slice($haystack, 0, $m);
$c = count($new_haystack);
$r = binSearch($needle, $new_haystack);
// 返回当前索引 - (下半部分的长度 - 下半部分中找到的索引)
return $m - ($c - $r);
break;
}
case(
$compare<$needle):
{
// 对上半部分递归
$new_haystack = array_slice($haystack, $m, ($l-$m));
$c = count($new_haystack);
$r = binSearch($needle, $new_haystack);
// 返回当前位置 + 上半部分中找到的索引
return $m + $r;
break;
}
case(
$compare==$needle):
{
// 找到它,所以返回索引
return $m;
break;
}
}
}
?>
-1
nordseebaer at gmx dot de
4年前
务必检查返回值是否不为 false!我使用 array_search() 来确定要取消设置的值的索引,然后意识到 $arr[false] === $arr[0]!

<?php
$arr
= ['apple', 'banana'];

var_dump($arr[0] === 'apple'); // true
var_dump($arr[false] === $arr[0]); // true
var_dump($arr[false] === 'apple'); // true

unset($arr[array_search('banana', $arr)]); //索引 = 1
var_dump($arr);

// 结果
// array(1) {
// [0]=>
// string(5) "apple"
// }

unset($arr[array_search('peach', $arr)]); // 未找到,结果为 false
var_dump($arr);

// 结果
// array(0) {
// }
// 因为 $arr[false] === $arr[0]
?>
因此,始终检查 array_search 的返回值!
To Top