php CSV 到关联数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4801895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CSV to Associative Array
提问by ParoX
I've seen numerous examples on how to take a CSV file and then create an associative array with the headers as the keys.
我已经看到了许多关于如何获取 CSV 文件,然后创建一个以标题为键的关联数组的示例。
For example:
例如:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
Where it would create an Array such as Array[$num][$key]
where $key
would be Brand, Model, Part, Test.
它将在哪里创建一个数组,例如在 Array[$num][$key]
哪里$key
将是品牌、型号、零件、测试。
So If I wanted to access the test value "434" I would have to loop every index in the array and then ignore any Brands that were not honda, and any models that were not Civic
所以如果我想访问测试值“434”,我必须循环数组中的每个索引,然后忽略任何不是本田的品牌,以及任何不是思域的模型
What I need to do is access the value most directly, instead of running through a for loop going through each $num index. I want to be able to access the value test "434" with:
我需要做的是最直接地访问该值,而不是通过 for 循环遍历每个 $num 索引。我希望能够通过以下方式访问值测试“434”:
Array['Honda']['Civic']['135']
Array['Honda']['Civic']['135']
or control a for statement with looping through every model Honda has... something like
或通过循环遍历本田拥有的每个模型来控制 for 语句......
foreach $model in Array['Honda']
foreach $model in Array['Honda']
At the very least I need to be able to go through every model given a known Brand and access all the relative info for each.
至少我需要能够浏览给定已知品牌的每个模型并访问每个模型的所有相关信息。
Edit:
编辑:
Just to confirm I was setting this up an example. My actually data has headers like:
只是为了确认我正在设置一个示例。我的实际数据有如下标题:
brand model part price shipping description footnote
brand model part price shipping description footnote
Of which I need to access all the information tied to the part (price, shipping,desc, footnote)
其中我需要访问与该部分相关的所有信息(价格、运输、描述、脚注)
回答by Daerik
Too many long solutions. I've always found this to be the simplest:
太长的解决方案。我一直觉得这是最简单的:
<?php
/* Map Rows and Loop Through Them */
$rows = array_map('str_getcsv', file('file.csv'));
$header = array_shift($rows);
$csv = array();
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
?>
回答by Haim Evgi
run over the csv file line by line, and insert to array like:
逐行运行 csv 文件,并插入到数组中,如:
$array = $fields = array(); $i = 0;
$handle = @fopen("file.csv", "r");
if ($handle) {
while (($row = fgetcsv($handle, 4096)) !== false) {
if (empty($fields)) {
$fields = $row;
continue;
}
foreach ($row as $k=>$value) {
$array[$i][$fields[$k]] = $value;
}
$i++;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
回答by mario
To create an associative list array use something like:
要创建关联列表数组,请使用以下内容:
$keys = fgetcsv($f);
while (!feof($f)) {
$array[] = array_combine($keys, fgetcsv($f));
}
And to traverse and filter by specific attributes write a function like:
并通过特定属性遍历和过滤编写一个函数,如:
function find($find) {
foreach ($array as $row) {
if (array_intersect_assoc($row, $find) == $find) {
$result[] = $row;
}
}
}
Where you would invoke it with $find = array(Brand=>Honda, Model=>Civic, Part=>135)
to filter out the searched models. The other positional array structure seems not very workable, unless you only want to access the "Test" attribute.
您将在哪里调用它$find = array(Brand=>Honda, Model=>Civic, Part=>135)
以过滤掉搜索到的模型。其他位置数组结构似乎不太可行,除非您只想访问“测试”属性。
回答by Tom Carnell
Try this simple algorithm:
试试这个简单的算法:
$assocData = array();
if( ($handle = fopen( $importedCSVFile, "r")) !== FALSE) {
$rowCounter = 0;
while (($rowData = fgetcsv($handle, 0, ",")) !== FALSE) {
if( 0 === $rowCounter) {
$headerRecord = $rowData;
} else {
foreach( $rowData as $key => $value) {
$assocData[ $rowCounter - 1][ $headerRecord[ $key] ] = $value;
}
}
$rowCounter++;
}
fclose($handle);
}
var_dump( $assocData);
回答by Brad
Here is a solutions that will work by specifying a local file or URL. You can also switch the association on and off. Hopefully this helps.
这是一个通过指定本地文件或 URL 来工作的解决方案。您还可以打开和关闭关联。希望这会有所帮助。
class CSVData{
public $file;
public $data;
public $fp;
public $caption=true;
public function CSVData($file=''){
if ($file!='') getData($file);
}
function getData($file){
if (strpos($file, 'tp://')!==false){
copy ($file, '/tmp/csvdata.csv');
if ($this->fp=fopen('/tmp/csvdata.csv', 'r')!==FALSE){
$this->readCSV();
unlink('tmp/csvdata.csv');
}
} else {
$this->fp=fopen($file, 'r');
$this->readCSV();
}
fclose($this->fp);
}
private function readCSV(){
if ($this->caption==true){
if (($captions=fgetcsv($this->fp, 1000, ","))==false) return false;
}
$row=0;
while (($data = fgetcsv($this->fp, 1000, ",")) !== FALSE) {
for ($c=0; $c < count($data); $c++) {
$this->data[$row][$c]=$data[$c];
if ($this->caption==true){
$this->data[$row][$captions[$c]]=$data[$c];
}
}
$row++;
}
}
}
Try this usage:
试试这个用法:
$o=new CSVData();
$o->getData('/home/site/datafile.csv');
$data=$o->data;
print_r($data);
回答by mickmackusa
Using fgetcsv()
seems the most direct and sensible tool for the job.
使用fgetcsv()
似乎是这项工作最直接、最明智的工具。
csv.csv contents:
csv.csv 内容:
Brand,Model,Part,Test
Honda,Civic,123,244
Honda,Civic,135,434
Toyota,Supra,511,664
Code:
代码:
$assoc_array = [];
if (($handle = fopen("csv.csv", "r")) !== false) { // open for reading
if (($data = fgetcsv($handle, 1000, ",")) !== false) { // extract header data
$keys = $data; // save as keys
}
while (($data = fgetcsv($handle, 1000, ",")) !== false) { // loop remaining rows of data
$assoc_array[] = array_combine($keys, $data); // push associative subarrays
}
fclose($handle); // close when done
}
echo "<pre>";
var_export($assoc_array); // print to screen
echo "</pre>";
Output:
输出:
array (
0 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '123',
'Test' => '244',
),
1 =>
array (
'Brand' => 'Honda',
'Model' => 'Civic',
'Part' => '135',
'Test' => '434',
),
2 =>
array (
'Brand' => 'Toyota',
'Model' => 'Supra',
'Part' => '511',
'Test' => '664',
),
)