PHP - 重新组织查询字符串参数

时间:2016-02-24 18:49:54

标签: php arrays

假设我有一个像这样的查询字符串:

?foo1bar1=a&foo1bar2=b&foo1bar3=c&foo2bar1=d&cats1dogs1=z

此字符串中的参数可以是任意的,并且可以包含任意数量的索引(因此您可以只有foo=,您可以拥有foo1bar1=foo1bar1baz1=之类的内容。但是,参数及其相关指标将提前知道。

我希望能够获取此查询字符串,加上配置,并重新构造它......配置可能如下所示:

$indexes = array('foodex', 'bardex');
$columns = array('foo<foodex>bar<bardex>', 'cats<foodex>dogs<bardex>');

所需的输出将是&#34;列&#34;重组为由适当索引索引的行,准备存储在数据库行中。像这样......

array(
    array(
        'foodex' => 1,
        'bardex' => 1,
        'foo<foodex>bar<bardex>' => 'a',
        'cats<foodex>dogs<bardex>' => 'z'
    ),
    array(
        'foodex' => 1,
        'bardex' => 2,
        'foo<foodex>bar<bardex>' => 'b',
        'cats<foodex>dogs<bardex>' => null
    ),
    etc.
)

我已经想到了解决这个问题的几个想法,但没有什么看起来非常优雅......我可以:

  1. 编写一个递归函数,循环遍历已知索引的所有可能值,然后调用自身循环遍历下一个已知索引的所有可能值,然后记录结果。这可能会非常慢......您可能会遍历数千或数百万个可能的索引值,但只能在查询字符串中找到少数。
  2. 循环查询字符串中的每个实际值,进行某种正则表达式检查以查看它是否与我要查找的列中的一列相匹配,其中包含列在其中的每个索引的通配符。然后我可以使用索引构建某种多维数组,并最终将其展平为输出。这会跑得快得多,但看起来非常复杂。
  3. 是否有一个优雅的解决方案盯着我的脸?我很乐意听取建议。

1 个答案:

答案 0 :(得分:1)

这是您可以从以下开始的快速示例:

// your configuration
$indexes = array ('foodex', 'bardex');
$columns = array ('foo<foodex>bar<bardex>', 'cats<foodex>dogs<bardex>');

// column names converted into regexps
$columns_re = array_map ( function ($v) {
    global $indexes;
    return '/^' . str_replace ( array_map ( function ($v) {
        return '<' . $v . '>';
    }, $indexes ), '(\d+)', $v ) . '$/';
}, $columns );

// output array
$array = array ();
foreach ( $_GET as $key => $value ) {
    foreach ( $columns_re as $reIdx => $re ) {
        $matches = array ();
        if (preg_match_all ( $re, $key, $matches )) {
            // generate unique row id as combination of all indexes
            $rowIdx = '';
            foreach ( $indexes as $i => $idxName )
                $rowIdx .= $matches [$i + 1] [0] . '_';
            // fill output row with default values
            if (! isset ( $array [$rowIdx] )) {
                $array [$rowIdx] = array ();
                foreach ( $indexes as $i => $idxName )
                    $array [$rowIdx] [$idxName] = $matches [$i + 1] [0];
                foreach ( $columns as $name )
                    $array [$rowIdx] [$name] = null;
            }
            // fill actually found value
            $array [$rowIdx] [$columns [$reIdx]] = $value;
        }
    }
}

使用php 5.3测试,可以在任何版本下运行一些修改