简单键白名单过滤器
<?php
$arr = array('a' => 123, 'b' => 213, 'c' => 321);
$allowed = array('b', 'c');
print_r(array_intersect_key($arr, array_flip($allowed)));
?>
将返回
数组
(
[b] => 213
[c] => 321
)
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
array_intersect_key — 使用键进行比较来计算数组的交集
array_intersect_key() 返回一个数组,其中包含所有在所有参数中都存在键的 array
的条目。
array
要检查的主键的数组。
arrays
要比较键的数组。
返回一个关联数组,其中包含所有在所有参数中都存在键的 array
的条目。
版本 | 说明 |
---|---|
8.0.0 | 此函数现在可以只使用一个参数调用。以前,至少需要两个参数。 |
示例 #1 array_intersect_key() 示例
<?php
$array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
var_dump(array_intersect_key($array1, $array2));
?>
上面的示例将输出
array(2) { ["blue"]=> int(1) ["green"]=> int(3) }
在我们的示例中,您会看到只有键 'blue'
和 'green'
出现在两个数组中,因此被返回。另外请注意,键 'blue'
和 'green'
的值在两个数组中是不同的。仍然会匹配,因为只检查键。返回的值是 array
的值。
来自 key => value
对的两个键被认为相等,只有当 (string) $key1 === (string) $key2
时。换句话说,执行严格类型检查,因此字符串表示必须相同。
简单键白名单过滤器
<?php
$arr = array('a' => 123, 'b' => 213, 'c' => 321);
$allowed = array('b', 'c');
print_r(array_intersect_key($arr, array_flip($allowed)));
?>
将返回
数组
(
[b] => 213
[c] => 321
)
请注意,返回数组中键的顺序与源数组中键的顺序相同。
要按第二个数组排序,您可以通过 array_replace 来做到这一点。
<?php
$array = array(
'two' => 'a',
'three' => 'b',
'one' => 'c',
);
$keyswant = array(
'one' => '',
'three' => '',
);
print_r(array_intersect_key(array_replace($keyswant, $array), $keyswant));
?>
显示
数组
(
[one] => c
[three] => b
)
而不是
数组
(
[three] => b
[one] => c
)
[编辑注意:将 array_merge_recursive() 更改为 array_replace_recursive() 以修复脚本]
以下是如何使用一些默认值作为白名单合并设置的更好方法。
<?php
$defaults = [
'id' => 123456,
'client_id' => null,
'client_secret' => null,
'options' => [
'trusted' => false,
'active' => false
]
];
$options = [
'client_id' => 789,
'client_secret' => '5ebe2294ecd0e0f08eab7690d2a6ee69',
'client_password' => '5f4dcc3b5aa765d61d8327deb882cf99', // 被忽略
'client_name' => 'IGNORED', // 被忽略
'options' => [
'active' => true
]
];
var_dump(
array_replace_recursive($defaults,
array_intersect_key(
$options, $defaults
)
)
);
?>
输出
array (size=4)
'id' => int 123456
'client_id' => int 789
'client_secret' => string '5ebe2294ecd0e0f08eab7690d2a6ee69' (length=32)
'options' =>
array (size=2)
'trusted' => boolean false
'active' => boolean true
请注意,返回数组中键的顺序与源数组中键的顺序相同。例如
<?php
$array = array(
'two' => 'a',
'three' => 'b',
'one' => 'c',
);
$keyswant = array(
'one' => '',
'three' => '',
);
print_r(array_intersect_key($array, $keyswant));
?>
显示
数组
(
[three] => b
[one] => c
)
我发现以下内容很有帮助
<?PHP
function array_merge_default($default, $data) {
$intersect = array_intersect_key($data, $default); //获取数据,其中存在默认值
$diff = array_diff_key($default, $data); //获取数据中不存在的默认值
return $diff + $intersect; //数组具有不同的键,返回两个数组的并集
}
?>
它类似于它使用的两个函数,但保留默认值和_仅_默认值。它专为键数组设计,我不确定它在数字索引数组上如何工作。
示例
<?PHP
$default = array(
"one" => 1,
"two" => 2
);
$untrusted = array(
"one" => 42,
"three" => 3
);
var_dump(array_merge_default($default, $untrusted));
array(2) {
["two"]=>
int(2)
["one"]=>
int(42)
}
?>
Jesse:不,array_intersect_key 不会像你发布的内容一样实现相同的功能
array_flip (array_intersect (array_flip ($a), array_flip ($b)))
因为当数组被翻转时,值会变成键。具有重复的值不是问题,但具有重复的键是问题。array_flip 通过只保留一个重复项并丢弃其余项来解决它。当你开始交叉时,你已经丢失了信息。
关于 php at keithtylerdotcom 对模拟的解决方案
<?php
$z = someFuncReturningAnArray()['some_key'];
?>
他推荐的解决方案仍然会返回一个数组。要获取函数返回的数组中单个键的值,只需在食谱中添加 implode()
<?php
function someFuncReturningAnArray() {
return array(
'a' => 'b',
'c' => 'd',
'e' => 'f',
'g' => 'h',
'i' => 'j'
);
}
//传统方式
$temp = someFuncReturningAnArray();
$b = $temp['a'];
echo print_r($b, 1) . "\n----------\n";
//keithtylerdotcom 单行方法
$b = array_intersect_key(someFuncReturningAnArray(), array('a'=>''));
echo print_r($b, 1) . "\n----------\n";
//更好的单行方法
$b = implode('', array_intersect_key(someFuncReturningAnArray(), array('a'=>'')));
echo print_r($b, 1) . "\n----------\n";
?>
<?php
/**
* 计算两个数组的交集,类似于 array_intersect_key 但递归
*
* @param array/mixed 主数组
* @param array 应该在主数组中保留的键的数组
* @return array/mixed 清理后的主数组
*/
function myIntersect($master, $mask) {
if (!is_array($master)) { return $master; }
foreach ($master as $k=>$v) {
if (!isset($mask[$k])) { unset ($master[$k]); continue; } //如果键不存在于 $mask 中,则从 $master 中删除值
if (is_array($mask[$k])) { $master[$k] = $this->myIntersect($master[$k], $mask[$k]); } //当 mask 是数组时递归
//否则简单地保留值
}
return $master;
}
?>
如果你来这里是为了寻找一个函数,它返回一个包含所有具有相交键的数组值的数组
<?php
function array_merge_on_key($key, $array1, $array2) {
$arrays = array_slice(func_get_args(), 1);
$r = array();
foreach($arrays as &$a) {
if(array_key_exists($key, $a)) {
$r[] = $a[$key];
continue;
}
}
return $r;
}
// 示例:
$array1 = array("id" => 12, "name" => "Karl");
$array2 = array("id" => 4, "name" => "Franz");
$array3 = array("id" => 9, "name" => "Helmut");
$array4 = array("id" => 10, "name" => "Kurt");
$result = array_merge_on_key("id", $array1, $array2, $array3, $array4);
echo implode(",", $result); // => 12,4,9,10
?>
如果你想使用一个只包含 0 和 1 的数组作为另一个数组的掩码,这个简单的脚本可以实现(当然两个数组必须有相同的大小)。$outcome 是一个数组,它只包含 $source 中 $mask 等于 1 的值。
<?php
$outcome = array_values(array_intersect_key( array_values($source), array_filter(array_values($mask)) ));
?>
PS:array_values() 函数是必要的,以确保两个数组具有相同的编号/键,否则你的掩码不会按预期工作。
享受!