搜索 php 多维关联数组,使用键值对和 sql like '%LIKE%' 结构
search php multidimensional associative array using key value pair with sql like '%LIKE%' construct
我有这个 PHP 函数,它可以很好地使用键值对搜索多维关联数组。我现在想扩展它以搜索一个数组,其中键值对具有类似 SQL 的结构,类似于:name = '%john%'
.
function search($array, $key, $value)
{
$results = array();
like_search_r($array, $key, $value, $results);
return $results[0];
}
function like_search_r($array, $key, $value, &$results)
{
if (!is_array($array)) {
return;
}
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
like_search_r($subarray, $key, $value, $results);
}
}
我在这里找到了一个很好的例子 filter values from an array similar to SQL LIKE '%search%' using PHP 但它只搜索一维数组。这个例子中的关键是 preg_grep 但我还没有想出如何在多维关联数组中使用它。感谢任何帮助。
已编辑:我希望能够传递一组键值对来执行一个 sql 之类的过滤器。原始要求保持不变。过滤器必须支持类似于 sql '%like%' 的东西,不需要输入,return 满足匹配组合时的根数组。如果 key/value 对不匹配,忽略并继续下一个 key/value 对。我的输入数组如下所示:
array('FIRST_NAME'=>'ma','MIDDLE_NAME'=>'bill',
'LAST_NAME'=>'jo','ALIASES'=>'phil',
'DOB'=>'2017-07-05','COUNTRY_OF_BIRTH'=>'Jamaica',
'Countries1'=>array(array('COUNTRY_CODE'=>'JM'),array('COUNTRY_CODE'=>'AL')),
'Countries2'=>array(array('COUNTRY_CODE'=>'JM'),array('COUNTRY_CODE'=>'AL')));
可以在此处找到要过滤的示例数组:https://www.tehplayground.com/dIMKbb6Tcw5YU38R
我认为要走的路是 preg_match()
:
function match($search, $subject)
{
$search = str_replace('/', '\/', $search);
return preg_match("/$search/i", (string)$subject);
}
function like_search_r($array, $key, $value, array &$results = [])
{
if (!is_array($array)) {
return;
}
$key = (string)$key;
$value = (string)$value;
foreach ($array as $arrayKey => $arrayValue) {
if (match($key, $arrayKey) && match($value, $arrayValue)) {
// add array if we have a match
$results[] = $array;
}
if (is_array($arrayValue)) {
// only do recursion on arrays
like_search_r($arrayValue, $key, $value, $results);
}
}
}
$array1 = [
'foo' => 'bar',
'subarr' => [
'test' => 'val',
'dangerous/characters' => 1,
],
];
$results1 = [];
like_search_r($array1, 'fo', 'bar', $results1);
print_r($results1);
/*
Array
(
[0] => Array
(
[foo] => bar
[subarr] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
)
*/
$results2 = [];
like_search_r($array1, 'est', 'val', $results2);
print_r($results2);
/*
Array
(
[0] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
*/
$results3 = [];
like_search_r($array1, 's/c', 1, $results3);
print_r($results3);
/*
Array
(
[0] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
*/
根据您的评论进行了调整:
function match($search, $subject) { /* no change */ }
function like_search_r($array, $key, $value, array &$results = [], $level = 0)
{
if (!is_array($array)) {
return false;
}
$key = (string)$key;
$value = (string)$value;
$found = false;
foreach ($array as $arrayKey => $arrayValue) {
if (match($key, $arrayKey) && match($value, $arrayValue)) {
return true;
}
if (is_array($arrayValue)) {
// only do recursion on arrays
// results are only added on top level
if (like_search_r($arrayValue, $key, $value, $results, $level+1)) {
if ($level == 1) {
$results[] = $array;
}
$found = true;
}
}
}
return $found;
}
$array2 = [['id' => 0, 'values' => ['name' => 'bill']], ['id' => 1, 'values' => ['name' => 'john']]];
$results4 = [];
like_search_r($array2, 'name', 'john', $results4);
print_r($results4);
/*
Array
(
[0] => Array
(
[id] => 1
[values] => Array
(
[name] => john
)
)
)
*/
我有这个 PHP 函数,它可以很好地使用键值对搜索多维关联数组。我现在想扩展它以搜索一个数组,其中键值对具有类似 SQL 的结构,类似于:name = '%john%'
.
function search($array, $key, $value)
{
$results = array();
like_search_r($array, $key, $value, $results);
return $results[0];
}
function like_search_r($array, $key, $value, &$results)
{
if (!is_array($array)) {
return;
}
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
like_search_r($subarray, $key, $value, $results);
}
}
我在这里找到了一个很好的例子 filter values from an array similar to SQL LIKE '%search%' using PHP 但它只搜索一维数组。这个例子中的关键是 preg_grep 但我还没有想出如何在多维关联数组中使用它。感谢任何帮助。
已编辑:我希望能够传递一组键值对来执行一个 sql 之类的过滤器。原始要求保持不变。过滤器必须支持类似于 sql '%like%' 的东西,不需要输入,return 满足匹配组合时的根数组。如果 key/value 对不匹配,忽略并继续下一个 key/value 对。我的输入数组如下所示:
array('FIRST_NAME'=>'ma','MIDDLE_NAME'=>'bill',
'LAST_NAME'=>'jo','ALIASES'=>'phil',
'DOB'=>'2017-07-05','COUNTRY_OF_BIRTH'=>'Jamaica',
'Countries1'=>array(array('COUNTRY_CODE'=>'JM'),array('COUNTRY_CODE'=>'AL')),
'Countries2'=>array(array('COUNTRY_CODE'=>'JM'),array('COUNTRY_CODE'=>'AL')));
可以在此处找到要过滤的示例数组:https://www.tehplayground.com/dIMKbb6Tcw5YU38R
我认为要走的路是 preg_match()
:
function match($search, $subject)
{
$search = str_replace('/', '\/', $search);
return preg_match("/$search/i", (string)$subject);
}
function like_search_r($array, $key, $value, array &$results = [])
{
if (!is_array($array)) {
return;
}
$key = (string)$key;
$value = (string)$value;
foreach ($array as $arrayKey => $arrayValue) {
if (match($key, $arrayKey) && match($value, $arrayValue)) {
// add array if we have a match
$results[] = $array;
}
if (is_array($arrayValue)) {
// only do recursion on arrays
like_search_r($arrayValue, $key, $value, $results);
}
}
}
$array1 = [
'foo' => 'bar',
'subarr' => [
'test' => 'val',
'dangerous/characters' => 1,
],
];
$results1 = [];
like_search_r($array1, 'fo', 'bar', $results1);
print_r($results1);
/*
Array
(
[0] => Array
(
[foo] => bar
[subarr] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
)
*/
$results2 = [];
like_search_r($array1, 'est', 'val', $results2);
print_r($results2);
/*
Array
(
[0] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
*/
$results3 = [];
like_search_r($array1, 's/c', 1, $results3);
print_r($results3);
/*
Array
(
[0] => Array
(
[test] => val
[dangerous/characters] => 1
)
)
*/
根据您的评论进行了调整:
function match($search, $subject) { /* no change */ }
function like_search_r($array, $key, $value, array &$results = [], $level = 0)
{
if (!is_array($array)) {
return false;
}
$key = (string)$key;
$value = (string)$value;
$found = false;
foreach ($array as $arrayKey => $arrayValue) {
if (match($key, $arrayKey) && match($value, $arrayValue)) {
return true;
}
if (is_array($arrayValue)) {
// only do recursion on arrays
// results are only added on top level
if (like_search_r($arrayValue, $key, $value, $results, $level+1)) {
if ($level == 1) {
$results[] = $array;
}
$found = true;
}
}
}
return $found;
}
$array2 = [['id' => 0, 'values' => ['name' => 'bill']], ['id' => 1, 'values' => ['name' => 'john']]];
$results4 = [];
like_search_r($array2, 'name', 'john', $results4);
print_r($results4);
/*
Array
(
[0] => Array
(
[id] => 1
[values] => Array
(
[name] => john
)
)
)
*/