PHP CSV字符串到数组

时间:2013-07-20 10:18:36

标签: php parsing csv

我正在尝试将CS​​V字符串解析为PHP中的数组。 CSV字符串具有以下属性:

Delimiter: ,
Enclosure: "
New line: \r\n

示例内容:

"12345","Computers","Acer","4","Varta","5.93","1","0.04","27-05-2013"
"12346","Computers","Acer","5","Decra","5.94","1","0.04","27-05-2013"

当我尝试像这样解析它时:

$url = "http://www.url-to-feed.com";
$csv = file_get_contents($url);
$data = str_getcsv($csv);
var_dump($data);

最后一个元素和一个元素串在一个字符串中:

[0]=> string(5) "12345"
...
[7]=> string(4) "0.04"
[8]=> string(19) "27-05-2013
"12346""

我该如何解决这个问题?任何帮助将不胜感激。

10 个答案:

答案 0 :(得分:96)

这样做:

$csvData = file_get_contents($fileName);
$lines = explode(PHP_EOL, $csvData);
$array = array();
foreach ($lines as $line) {
    $array[] = str_getcsv($line);
}
print_r($array);

它会给你一个这样的输出:

Array
(
    [0] => Array
        (
            [0] => 12345
            [1] => Computers
            [2] => Acer
            [3] => 4
            [4] => Varta
            [5] => 5.93
            [6] => 1
            [7] => 0.04
            [8] => 27-05-2013
        )

    [1] => Array
        (
            [0] => 12346
            [1] => Computers
            [2] => Acer
            [3] => 5
            [4] => Decra
            [5] => 5.94
            [6] => 1
            [7] => 0.04
            [8] => 27-05-2013
        )

)

我希望这可以提供一些帮助。

答案 1 :(得分:35)

Handy oneliner:

$csv = array_map('str_getcsv', file('data.csv'));

答案 2 :(得分:18)

您应该使用fgetcsv。由于您无法将文件作为流导入,因为csv是一个变量,因此您应该使用Date = c("2017-06-08 13:00:04", "2017-06-08 12:00:04", "2017-06-08 11:00:04", "2017-06-08 10:00:04", "2017-06-08 09:00:04") Val = c("520", "507", "501", "472", "444") Weekday = c("Thursday", "Thursday", "Thursday", "Thursday", "Thursday") df1 = as.data.frame(cbind(Date, Val, Weekday)) df1$Date = as.POSIXct(df1$Date) df1$Val = as.numeric(as.character(df1$Val)) Date1 = c("2017-06-08 12:00:04", "2017-06-08 11:00:04", "2017-06-08 10:00:04", "2017-06-08 09:00:04", "2017-06-08 09:00:03") Val1 = c("507", "501", "472", "444", "446") Weekday1 = c("Thursday", "Thursday", "Thursday", "Thursday", "Thursday") df2 = as.data.frame(cbind(Date1, Val1, Weekday1)) df2$Date1 = as.POSIXct(df2$Date1) df2$Val1 = as.numeric(as.character(df2$Val1)) colnames(df2)[1] = "Date" colnames(df2)[2] = "Val" colnames(df2)[3] = "Weekday" df1$Date = align.time(df1$Date, n = 60) df2$Date = align.time(df2$Date, n = 60) ndf = merge(df1, df2, by = c("Date", "Weekday"), all = TRUE, sort = TRUE) ndf 或{{将字符串欺骗为文件1}}首先:

php://temp

然后使用fgetcsv会没问题:

php://memory

$fp = fopen("php://temp", 'r+'); fputs($fp, $csvText); rewind($fp); 将是一个单个csv行的数组(可能包括换行符或逗号等),应该如此。

答案 3 :(得分:6)

我使用了以下函数将csv字符串解析为关联数组

public function csvToArray($file) {
    $rows = array();
    $headers = array();
    if (file_exists($file) && is_readable($file)) {
        $handle = fopen($file, 'r');
        while (!feof($handle)) {
            $row = fgetcsv($handle, 10240, ',', '"');
            if (empty($headers))
                $headers = $row;
            else if (is_array($row)) {
                array_splice($row, count($headers));
                $rows[] = array_combine($headers, $row);
            }
        }
        fclose($handle);
    } else {
        throw new Exception($file . ' doesn`t exist or is not readable.');
    }
    return $rows;
}

如果您的csv文件名是mycsv.csv,那么您将此函数称为:

$dataArray = csvToArray(mycsv.csv);

您也可以在http://www.scriptville.in/parse-csv-data-to-array/

中获取此脚本

答案 4 :(得分:1)

略短的版本,没有不必要的第二个变量:

$csv = <<<'ENDLIST'
"12345","Computers","Acer","4","Varta","5.93","1","0.04","27-05-2013"
"12346","Computers","Acer","5","Decra","5.94","1","0.04","27-05-2013"
ENDLIST;

$arr = explode("\n", $csv);
foreach ($arr as &$line) {
  $line = str_getcsv($line);
}

答案 5 :(得分:0)

如果需要csv列的名称,可以使用此方法

 $example= array_map(function($v) {$column = str_getcsv($v, ";");return array("foo" => $column[0],"bar" => $column[1]);},file('file.csv'));

答案 6 :(得分:0)

使用array_map修改以前的答案 用多行压缩CSV数据。

$csv = array_map('str_getcsv', explode("\n", $csvData));

答案 7 :(得分:0)

如果列中有回车/换行符,则str_getcsv将不起作用。

尝试https://github.com/synappnz/php-csv

使用:

include "csv.php";
$csv = new csv(file_get_contents("filename.csv"));
$rows = $csv->rows();
foreach ($rows as $row)
{
  // do something with $row
}

答案 8 :(得分:0)

您可以使用此功能将CSV字符串转换为Array。

    function csv2array(
        $csv_string,
        $delimiter = ",",
        $skip_empty_lines = true,
        $trim_fields = true,
        $FirstLineTitle = false
    ) {
        $arr = array_map(
            function ( $line ) use ( &$result, &$FirstLine, $delimiter, $trim_fields, $FirstLineTitle ) {
                if ($FirstLineTitle && !$FirstLine) {
                    $FirstLine = explode( $delimiter, $result[0] );
                }
                $lineResult = array_map(
                    function ( $field ) {
                        return str_replace( '!!Q!!', '"', utf8_decode( urldecode( $field ) ) );
                    },
                    $trim_fields ? array_map( 'trim', explode( $delimiter, $line ) ) : explode( $delimiter, $line )
                );
                return $FirstLineTitle ? array_combine( $FirstLine, $lineResult ) : $lineResult;
            },
            ($result = preg_split(
                $skip_empty_lines ? ( $trim_fields ? '/( *\R)+/s' : '/\R+/s' ) : '/\R/s',
                preg_replace_callback(
                    '/"(.*?)"/s',
                    function ( $field ) {
                        return urlencode( utf8_encode( $field[1] ) );
                    },
                    $enc = preg_replace( '/(?<!")""/', '!!Q!!', $csv_string )
                )
            ))
        );
        return $FirstLineTitle ? array_splice($arr, 1) : $arr;
    }

答案 9 :(得分:0)

尝试一下,它对我有用:

$delimiter = ",";
  $enclosure = '"';
  $escape = "\\" ;
  $rows = array_filter(explode(PHP_EOL, $content));
  $header = NULL;
  $data = [];

  foreach($rows as $row)
  {
    $row = str_getcsv ($row, $delimiter, $enclosure , $escape);

    if(!$header) {
      $header = $row;
    } else {
      $data[] = array_combine($header, $row);
    }
  }