没有内置函数可以做到这一点,您必须自己动手。如果您将整个文件读入数组然后对其执行某种转换,则对 CSV 中的数据执行此类操作可能会导致内存问题,因此最好逐行执行此操作。通过这种方式,您可以将行流式传输到一个新文件中,而不是将它们全部存储在一个大数组中。
这是一个快速而肮脏的解决方案,您可以在其中提供一个列索引数组来定义新顺序。简单有效。
输入:
Header A,Header B,Header C,Header D
a,b,c,d
1,2,3,4
alpha,bravo,charlie,delta
$fh = fopen('reorder.csv', 'r');
/*
* Create an array with column indices in the order that they
* should appear in the output.
*
* Each column that should appear in the output must be included.
* This is both a feature and a potential gotcha.
*/
$colSpec = [0,3,2,1];
// Output buffer
$output = [];
while($currRow = fgetcsv($fh))
{
// Buffer for our output row
$currOutput = [];
/*
* Loop through the spec array and populate the row output buffer
* using the indices defined there
*/
foreach($colSpec as $currColumnIndex)
{
$currOutput[] = $currRow[$currColumnIndex];
}
// Append the new reordered row to the output buffer
$output[] = $currOutput;
}
fclose($fh);
print_r($output);
输出:
Array
(
[0] => Array
(
[0] => Header A
[1] => Header D
[2] => Header C
[3] => Header B
)
[1] => Array
(
[0] => a
[1] => d
[2] => c
[3] => b
)
[2] => Array
(
[0] => 1
[1] => 4
[2] => 3
[3] => 2
)
[3] => Array
(
[0] => alpha
[1] => delta
[2] => charlie
[3] => bravo
)
)
虽然这不是很直观,但数字索引很难从逻辑上理解哪一列在哪里。如果您的 CSV 有一个标题行,并且该行中的标签是不可变的,您可以执行以下操作以使其更直观:
/*
* Create an array with header values in the order that they
* should appear in the output.
*
* Each column that should appear in the output must be included.
* This is both a feature and a potential gotcha.
*/
$colSpec = ['Header C', 'Header A', 'Header B', 'Header D'];
// Create a map for column name to actual index in the file
$headerIndexMap = array_flip($colSpec);
// Output buffer
$output = [];
while ($currRow = fgetcsv($fh))
{
// If this is our first row, set up the column mapping
if(empty($output))
{
// Loop through the columns...
foreach($currRow as $index => $currHeaderLabel)
{
/*
* Trim the header value, in case there it leading/trailing whitespace in the data
*/
$currHeaderLabel = trim($currHeaderLabel);
// If this column is in our column spec, set the index in $headerIndexMap
if(array_key_exists($currHeaderLabel, $headerIndexMap))
{
$headerIndexMap[$currHeaderLabel] = $index;
}
}
}
// Buffer for our output row
$currOutput = [];
// Loop through the column spec...
foreach ($colSpec as $currColumn)
{
// Get the actual index of the column from the index map
$currIndex = $headerIndexMap[$currColumn];
// Append the data in the appropriate column to the row output buffer
$currOutput[] = $currRow[$currIndex];
}
// Append the new reordered row to the output buffer
$output[] = $currOutput;
}
fclose($fh);
print_r($output);
输出:
Array
(
[0] => Array
(
[0] => Header C
[1] => Header A
[2] => Header B
[3] => Header D
)
[1] => Array
(
[0] => c
[1] => a
[2] => b
[3] => d
)
[2] => Array
(
[0] => 3
[1] => 1
[2] => 2
[3] => 4
)
[3] => Array
(
[0] => charlie
[1] => alpha
[2] => bravo
[3] => delta
)
)
我通常将这类东西包装在一个帮助类中,使其可封装和可测试,并保持使用它的代码整洁。