PHP - 在多文件上载中对多维数组的值进行排序和分组

时间:2017-05-07 16:39:44

标签: php arrays sorting

我有以下表格,当发送多个图像时会生成一个多维数组,默认情况下会排序所有数据。

表单HTML和PHP:

<?php

if(array_key_exists('send', $_POST)) {
    echo "<pre>"; print_r($_FILES);
}

?>

<html>
    <body>
        <form enctype="multipart/form-data" action="" method="POST">
            <input name="image[]" type="file" multiple />
            <input type="submit" name="send" value="Send" />
        </form>
    </body>
</html>

发送它会生成此类型的数组:

$file1 = array(
    'imagen' => array(
        'name'      => array(
            'Image_name',
            'Image_name'
        ),
        'type'      => array(
            'jpg',
            'jpg'
        ),
        'tmp_name'  => array(
            'jpg',
            'jpg'
        ),
        'error'     => array(
            0,
            0
        ),
        'size'      => array(
            '200',
            '200'
        )
    )
);

我需要使用PHP和foreach循环对数据进行排序,最好是从这个数组中以更简单的方式排序,并且值可以在一起。

预期输出:

$file2 = array(
    array(
        'name' => 'Image_name',
        'type' => 'jpg',
        'tmp_name' => 'jpg',
        'error' => 0,
        'size' => 200
    ),
    array(
        'name' => 'Image_name',
        'type' => 'jpg',
        'tmp_name' => 'jpg',
        'error' => 0,
        'size' => 200
    )
);

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

是默认php功能的预期输出。所以你可以编写自定义函数来清理你想要的形式的数组:

<?php

function reArrayFiles(&$file_post) {

    $file_ary = array();
    $file_count = count($file_post['name']);
    $file_keys = array_keys($file_post);

    for ($i=0; $i<$file_count; $i++) {
        foreach ($file_keys as $key) {
            $file_ary[$i][$key] = $file_post[$key][$i];
        }
    }

    return $file_ary;
}

?>
Then u can do the following:

<?php

if ($_FILES['upload']) {
    $file_ary = reArrayFiles($_FILES['ufile']);

    foreach ($file_ary as $file) {
        print 'File Name: ' . $file['name'];
        print 'File Type: ' . $file['type'];
        print 'File Size: ' . $file['size'];
    }
}

?>

答案 1 :(得分:1)

方法#1 :此单行执行相同的操作,没有for / foreach循环函数:

array_walk($file1["imagen"]["name"],function($v,$k)use(&$result,$file1){$result[]=array_combine(array_keys($file1["imagen"]),array_column($file1["imagen"],$k));});

故障:

array_walk(                                  // iterate array
    $file1["imagen"]["name"],                // input to determine iterations (only 2)
    function($v,$k)                          // declare values and keys; only using keys
    use(                                     // include additional variables
        &$result,                            // declare $result as modifiable
        $file1                               // include original array
    ){
    $result[]=                               // autoincrement keys for each new array
        array_combine(                       // create an array from key & value arrays
        array_keys($file1["imagen"]),        // keys array
        array_column($file1["imagen"],$k)    // values array
    );
});

方法#2 :下一种方法实际上运行得更快但需要两行代码:

$input=current($file1);
array_walk($file1["imagen"]["name"],function($v,$k)use(&$result,$input){$result[]=array_combine(array_keys($input),array_column($input,$k));});

两种方法都在$result生成相同的所需数组。

随着子阵列的大小增加,这两种方法相对于for / foreach等效方法将变得越来越有效。

方法#3 :这种方法只使用一个for周期和一组预定的结果键,并使用php的数组函数来实现它们的发明(* note这种方法缓存$count变量,这使得它比Sahil更有效 - 他的方法调用count()然后减去1然后在每个循环创建一个索引数组):< / p>

*与Sahil的方法相比,此方法速度更快,占用的内存更少。

for($x=0,$count=sizeof($file1["imagen"]["name"]); $x<$count; ++$x){
    $result[]=array_combine(['name','type','tmp_name','error','size'],array_column($file1["imagen"],$x));
}
  

方法#4 :此方法再次缓存子数组计数以获得最高效率,但使用动态结果键声明。

     

这是目前页面上最有效的方法

for($x=0,$keys=array_keys($file1["imagen"]),$count=sizeof($file1["imagen"]["name"]); $x<$count; ++$x){
    $result[]=array_combine($keys,array_column($file1["imagen"],$x));
}

...如果以上太拥挤了 - 寻找你,这在多行上都是一样的:

$keys=array_keys($file1["imagen"]);         // declare all keys in subarray
$count=sizeof($file1["imagen"]["name"]);    // declare number of iterations
for($x=0; $x<$count; ++$x){
    $result[]=array_combine($keys,array_column($file1["imagen"],$x));
}

尽管这些对于初出茅庐的php编码器来说可能会显得令人生畏,但它将有利于您的工艺以实验和实现许多功能强大的功能,这些功能可以在您未来的项目中显示更高的效率和更简洁的代码。

上述四种方法中使用的函数:

方法#5 :最后,如果您已经完全设置了两个循环和零高级数组函数,那么最佳实践将要求您缓存(在循环之前)任何值保持不变:

// instantiating $result is not necessary
$count=sizeof($file1["imagen"]["name"]);  // cache the count outside of iterations
foreach($file1["imagen"] as $k=>$v){
    for($i=0; $i<$count; ++$i){           // iterate integers not array
        $result[$i][$k]=$v[$i];   
    }
}

方法#6 :在循环之前将子阵列索引声明并缓存为数组

$indexes=range(0,sizeof($file1["imagen"]["name"])-1);
foreach($file1["imagen"] as $k=>$v){
    foreach($indexes as $i){
        $result[$i][$k]=$v[$i];   
    }
}
  

以上所有方法都在$result生成相同的输出。

答案 2 :(得分:0)

我非常感谢所有在这篇文章中贡献自己知识的用户,帮助了我很多,有想法和不同的方法来组织和分组更好的多维安排,还有很多方法可以做到这一点,每个都有更多优点比其他优点,但他们实现了目标。

由于PHP社区,这里有代码,我将再做一个贡献,并提供一种方法。

方法#1:

<?php 

$files = array(
    'imagen' => array(
        'name' => array(
            'Image_name',
            'Image_name'
        ),
        'type' => array(
            'jpg',
            'jpg'
        ),
        'tmp_name' => array(
            'jpg',
            'jpg'
        ),
        'error' => array(
            0,
            0
        ),
        'size' => array(
            '200',
            '200'
        )
    )
);


function normalize_files_array($files = []) {

    $normalized_array = [];

    foreach($files as $index => $file) {

        if (!is_array($file['name'])) {
            $normalized_array[$index][] = $file;
            continue;
        }

        foreach($file['name'] as $idx => $name) {
            $normalized_array[$index][$idx] = [
                'name'      => $name,
                'type'      => $file['type'][$idx],
                'tmp_name'  => $file['tmp_name'][$idx],
                'error'     => $file['error'][$idx],
                'size'      => $file['size'][$idx]
            ];
        }

    }
    return $normalized_array;
}

echo "<pre>"; print_r(normalize_files_array($files));

?>

结果#1:

Array (
    [imagen] => Array
        (
            [0] => Array
                (
                    [name] => Image_name
                    [type] => jpg
                    [tmp_name] => jpg
                    [error] => 0
                    [size] => 200
                )

            [1] => Array
                (
                    [name] => Image_name
                    [type] => jpg
                    [tmp_name] => jpg
                    [error] => 0
                    [size] => 200
                )
        )
)

方法#2:

$file1 = array(
    'imagen' => array(
        'name'      => array(
            'Image_name',
            'Image_name'
        ),
        'type'      => array(
            'jpg',
            'jpg'
        ),
        'tmp_name'  => array(
            'jpg',
            'jpg'
        ),
        'error'     => array(
            0,
            0
        ),
        'size'      => array(
            '200',
            '200'
        )
    )
);

$array = array_map(null, $file1['imagen']['name'], $file1['imagen']['type'], $file1['imagen']['tmp_name'], $file1['imagen']['error'], $file1['imagen']['size']);

echo "<pre>"; print_r($array);

结果#2:

Array
(
    [0] => Array
        (
            [0] => Image_name
            [1] => jpg
            [2] => jpg
            [3] => 0
            [4] => 200
        )

    [1] => Array
        (
            [0] => Image_name
            [1] => jpg
            [2] => jpg
            [3] => 0
            [4] => 200
        )

)

方法#3

<?php

$file1 = array(
    'imagen' => array(
        'name'      => array(
            'Image_name',
            'Image_name'
        ),
        'type'      => array(
            'jpg',
            'jpg'
        ),
        'tmp_name'  => array(
            'jpg',
            'jpg'
        ),
        'error'     => array(
            0,
            0
        ),
        'size'      => array(
            '200',
            '200'
        )
    )
);


function array_map_key($name, $type, $tmp_name, $error, $size){
        $tmp_array['name']  = $name;
        $tmp_array['type']  = $type;
        $tmp_array['tmp_name'] = $tmp_name;
        $tmp_array['error']     = $error;
        $tmp_array['size']  = $size;
        return $tmp_array;
}

$array = array_map('array_map_key', $file1['imagen']['name'], $file1['imagen']['type'], $file1['imagen']['tmp_name'], $file1['imagen']['error'], $file1['imagen']['size']);


echo "<pre>"; print_r($array);

?>

结果#3:

Array
(
    [0] => Array
        (
            [name] => Image_name
            [type] => jpg
            [tmp_name] => jpg
            [error] => 0
            [size] => 200
        )

    [1] => Array
        (
            [name] => Image_name
            [type] => jpg
            [tmp_name] => jpg
            [error] => 0
            [size] => 200
        )

)