0

我最近一直在处理表单,并决定制作一个 php 脚本来简化我看到自己重复的某些方面,我不会发布我创建的完整怪物,而是我会请你帮我简化如果可能,请使用以下代码:

function add($name,$input,&$array)
{
 $p = explode('[',$name);
 if(isset($p[1]))
 {
  list($key) = explode(']',$p[1]);
  if(ctype_digit($key))
  {
    $array['forms'][$p[0]][$key] = $input;
  }else{
    $array['forms'][$p[0]][] = $input;
  } 
 }else{
    $array['forms'][$name] = $input;
 }
}


$array = array();
add('image[]','',$array);
add('image[8]','',$array);
add('image[1]','',$array);
add('image[]','',$array);

echo '<PLAINTEXT>';
print_r($array);

它使 $array 变成:

Array
(
    [forms] => Array
        (
            [image] => Array
                (
                    [0] => 
                    [8] => 
                    [1] => 
                    [9] => 
                )

        )

)

这里的问题是,如果你添加一个“image”作为$name,那么它必须像posted一样添加到数组中,所以它将是array(image=>data),如果你输入image[],那么它将是数组(图像=>数组(0=>数据))。

我发现我的代码太庞大了,我找到了 parse_str,它解析“图像 []”,但它没有为我服务,因为我需要单独添加名称......

这个功能可以做得更优雅吗?

澄清:

有没有更好的方法将“name[]”添加到数组中,就好像它是要添加到数组中的名称列表的一部分一样。

所以我需要一个不会覆盖 $array 的 parse_str 替换。例子:

$array = array();
parse_str('image[]=test',$array);
parse_str('image[]=test1',$array);
parse_str('image[]=test2',$array);

但结果看起来像:

Array
(
    [image] => Array
        (
            [0] => test2
        )

)

但需要看起来像:

Array
(
    [image] => Array
        (
            [0] => test
            [1] => test1
            [2] => test2
        )

)

这将真正简化上述功能!

4

3 回答 3

1

是的,考虑到您的澄清,再次尝试:

function add($name,&$array)
{
    $type = explode('[',$name);
    $key = str_replace(array($type['0'], ']=', '[', ']'), '', $name);
    $array[$type['0']][] = $key;
}

$array = array();
add('image[]=test',$array);
add('image[test1]',$array);
add('image[]=test2',$array);
add('video[test5]',$array);

echo '<PLAINTEXT>';
print_r($array);

将返回:

Array
(
  [image] => Array
      (
          [0] => test
          [1] => test1
          [2] => test2
      )

  [video] => Array
      (
          [0] => test5
      )

)

好,最后一招!据我所知,没有合适的功能,而且整理现有代码也不是一件容易的事,但我已经尽力了!

function add($name,&$array)
{
    $type = explode('[',$name);
    $key = (!empty($type[1])) ? explode(']', $type[1]) : false;
    $value = str_replace(array($key[0], $type[0], ']=', '[', ']'), '', $name);
    if ($key[0]) $array[$type['0']][$key[0]] = $value;
    else $array[$type['0']][] = $value;
}

$array = array();
add('image[]=test',$array);
add('image[text8]=test4',$array);
add('image[]=test2',$array);
add('video[test5]',$array);

echo '<PLAINTEXT>';
print_r($array);

将返回:

Array
(
  [image] => Array
      (
          [0] => test
          [text8] => test4
          [1] => test2
      )

  [video] => Array
      (
          [test5] => 
      )

)
于 2010-10-21T12:19:51.733 回答
1

也许加入 array_merge_recursive 可以帮助您稍微简化代码。根据 John 的方法签名,它可能看起来像这样:

function add($value, &$target) {
    $temp = array();
    parse_str($value, $temp);
    $target = array_merge_recursive($target, $temp);
}

$array = array();
add('image[]=test',$array);
add('image[text8]=test4',$array);
add('image[]=test2',$array);
add('video[test5]',$array);

哪个(正如预期的那样,我相信)也产生

Array
(
    [image] => Array
        (
            [0] => test
            [text8] => test4
            [1] => test2
        )

    [video] => Array
        (
            [test5] => 
        )

)

希望这会有所帮助:)

编辑 :

如果您希望具有完全相同的行为(以最少的行数),您总是可以重建查询字符串,附加您的值并再次解析它。生成的代码不是最佳的或漂亮的,但它可以完成工作;)。图解:

function add($value, &$target) {
    $query = urldecode(http_build_query($target, '', '&'));
    $query = "{$query}&{$value}";
    parse_str($query, $target);
}

$array = array();

add($array, 'image[]');
add($array, 'image[8]=test4');
add($array, 'image[1]=test2');
add($array, 'image[]');

print_r($array);

会导致

Array
(
    [image] => Array
        (
            [0] => 
            [8] => test4
            [1] => test2
            [9] => 
        )

)
于 2010-10-22T08:41:08.110 回答
1

我不太确定为什么还没有提到 preg,但这似乎是你真正想要的

function add( $input, &$target )
{
    // sanity check.  If the brackets are missing, add them.
    if( strpos( $input, '[' ) === FALSE )
    {
        $input = str_replace( '=', '[]=',  $input );
    }
    // The regex means, "Get the starting variable name segment" 
    // (begins with a letter here, you could just make it \w+)
    // followed by the portion between the left and right brackets
    // and finally by the value after the period until the end of the input
    preg_match( '/^([a-zA-Z]\w*)\[(\w*)\]=?(.*)$/', $input, $matches );

    // the first value in the matches array is the original string.
    array_shift( $matches );

    // sanity check -- if the string doesn't match the above regex, ignore it.
    if( !isset( $matches[ 1 ] ) ) return;
    $m1 = $matches[ 1 ];
    $m2 = ( isset( $matches[ 2 ] ) )? $matches[ 2 ]: NULL;

    // numeric keys are translated to the equivalent of array_push.
    if( is_numeric( $m1 ) || $m1 == "" )
    {
        $target[ $matches[ 0 ] ][] = $m2;
    }
    // non-numerics are kept as is.
    else
    {
        $target[ $matches[ 0 ] ][ $m1 ] = $m2;
    }
}
于 2010-10-22T10:02:15.403 回答