【问题标题】:php str_getcsv array issuephp str_getcsv 数组问题
【发布时间】:2011-12-27 08:12:16
【问题描述】:

我正在上传一个 csv 文件,然后使用 str_getcsv 对其进行解析。一切都很好,只是我需要一种方法来循环它们。理想情况下,让数组返回并看起来像这样会很棒:

Array (      
    [1] => Array
       (
            [0] => 1 // first id in csv
            [1] => name
            [2] => address
            [3] => town
            [4] => state
            [5] => zip
            [6] => phone
            [7] => website
            [8] => other
            [9] => other
        )
    [22] => Array
       (
            [10] => name
            [11] => address
            [12] => town
            [13] => state
            [14] => zip
            [15] => phone
            [16] => website
            [17] => other
            [18] => other
        )
    [24] => Array
       (
            [19] => name
            [20] => address
            [21] => town
            [22] => state
            [23] => zip
            [24] => phone
            [25] => website
            [26] => other
            [27] => other
        )
)

但是数据返回如下:

Array
(
    [0] => 1 // first id in csv
    [1] => name
    [2] => address
    [3] => town
    [4] => state
    [5] => zip
    [6] => phone
    [7] => website
    [8] => other
    [9] => other
22 // id field
    [10] => name
    [11] => address
    [12] => town
    [13] => state
    [14] => zip
    [15] => phone
    [16] => website
    [17] => other
    [18] => other
24// id field
    [19] => name
    [20] => address
    [21] => town
    [22] => state
    [23] => zip
    [24] => phone
    [25] => website
    [26] => other
    [27] => other

关于如何解决这个问题,让它看起来像顶部的数组有什么建议吗? 现在我正在做:

$csvfile = file_get_contents($targetFile);
$csv = str_getcsv($csvfile);

【问题讨论】:

  • PHP CSV string to array 的可能重复项
  • 我已将此标记为重复,尽管该问题较早只是因为该问题更受欢迎

标签: php arrays parsing csv upload


【解决方案1】:

str_getcsv() 期望作为参数传递的字符串是一个记录。
但是由于您的源无论如何都是文件,因此最简单的方法可能是使用 fgetcsv() 而不是 str_getcsv()

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $data[] = fgetcsv($fp);
}
fclose($fp);

独立示例:

<?php
$targetFile = 'soTest.csv';
setup($targetFile);

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $data[] = fgetcsv($fp);
}
var_dump($data);


function setup($targetFile) {
    file_put_contents($targetFile, <<< eot
1,name,address,town,state,zip,phone,website,other,other
2,name,address,town,state,zip,phone,website,other,other
3,name,address,town,state,zip,phone,website,other,other
eot
    );
}

打印

array(3) {
  [0]=>
  array(10) {
    [0]=>
    string(1) "1"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
  [1]=>
  array(10) {
    [0]=>
    string(1) "2"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
  [2]=>
  array(10) {
    [0]=>
    string(1) "3"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
}

edit2:使用每条记录的第一个元素作为结果数组中的键:

<?php
$targetFile = 'soTest.csv';
setup($targetFile);

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $row = fgetcsv($fp);
    $id = array_shift($row);
    $data[$id] = $row;
}
var_dump($data);


function setup($targetFile) {
    file_put_contents($targetFile, <<< eot
1,name,address,town,state,zip,phone,website,other,other
2,name,address,town,state,zip,phone,website,other,other
3,name,address,town,state,zip,phone,website,other,other
eot
    );
}

【讨论】:

  • 这对我来说仍然返回相同的东西。我需要它看起来像问题顶部的数组
  • @Drew :那么也许你有一个问题,php 没有检测到文件中的行尾。见docs.php.net/…
  • 我会说仔细检查你的 csv 并确保每条记录也没有用逗号分隔。我没有运行此代码,但它看起来不错。并且应该导致您正在寻找的数组。哦,每条记录也应该换行。
【解决方案2】:

不是这个世界上最漂亮的东西,但我认为它有效。

//make the arrays needed
$csvtmp = array();
$csvFinal = array();

$csvfile = file_get_contents('test.csv');
$csv = str_getcsv($csvfile,"\n"); //make an array element for every record (new line)

//Loop through the result 
foreach ($csv as $key => $item) 
{
    array_push($csvtmp, str_getcsv($item,";")); //push each record to the csv temp array

    //here's the messy part. This set the key of the csvFinal array to the first field in the current record and for the value it gives it the array we got from the previous str_getcsv.
    $csvFinal[$csvtmp[$key][0]] = $csvtmp[$key]; 
    //Here we just unset the id row in the final array
    unset($csvFinal[$csvtmp[$key][0]][0]);

}

echo "<pre>";
    print_r($csvFinal);
echo "</pre>"; 

代码结果:

Array
(
    [22] => Array
        (
            [1] => name1
            [2] => address1
            [3] => town1
            [4] => state1
            [5] => zip1
            [6] => phone1
            [7] => website1
            [8] => other1
            [9] => other1
        )

    [23] => Array
        (
            [1] => name2
            [2] => address2
            [3] => town2
            [4] => state2
            [5] => zip2
            [6] => phone2
            [7] => website2
            [8] => other1
            [9] => other1
        )

    [24] => Array
        (
            [1] => name3
            [2] => address3
            [3] => town3
            [4] => state3
            [5] => zip3
            [6] => phone3
            [7] => website3
            [8] => other1
            [9] => other1
        )
}

希望对你有帮助

【讨论】:

  • 不应使用\n 确定csv 中的新行,如果任何列行中有多行,\n 将中断。
【解决方案3】:

好吧,只计算一个条目的项目数,然后在循环中创建一个循环

// loop on all items; $i+=$ITEM_SIZE go to the next item each outer loop
// (10 elements for ITEM in Opening Post's case)

// this for loops between all items
for ($i=0;$i<=$ARRAY_LENGHT;$i+=10)
{
    // this for loops between each item's elements
    for($c=1; $c<=10;$c++)
    {
        switch($c)
        {
            case 1:
              $id = $array[$i+$c];
              break;

            case 2:
              $name = $array[$i+$c];
              break;

            case 3:
              $address = $array[$i+$c];
              break;

            //etc to 10th element:

            case 10:
              $other = $array[$i+$c];
              break;

        }
    }

    // When the item is all done use the item
    // it as you need, example:

    echo "id: {$id}\nname: {$name}\naddress: {$adress}"; //etc

    // then unset($id,$name,$address, $etc);
    // for the next iteration of loop (next item)
}

这就是我刚刚所做的并且效果很好。

【讨论】:

    猜你喜欢
    • 2012-01-11
    • 2016-08-07
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 2010-10-04
    相关资源
    最近更新 更多