【问题标题】:PHP fgetcsv() delimiter ';' not recognizedPHP fgetcsv() 分隔符 ';'未识别
【发布时间】:2016-06-10 12:19:07
【问题描述】:

我的“;”似乎有问题分隔符。这是我的 csv 文件:

First Name;Last Name;Email;Age
Julie;Brown;julie@example.com;52
Dan;Wong;dan@example.com;19
Tim;Hortons;tim@example.com;27

还有我的 PHP 代码:

$row = 1;
if (($handle = fopen("upload/".$_FILES['fichier']['name'], "r")) !== FALSE) {
    while (($data = fgetcsv($handle, ";")) !== FALSE) {
        $num = count($data);
        echo "<p> $num champs à la ligne $row: <br /></p>\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
fclose($handle);
}

我有这个输出:

1 champs à la ligne 1: 
First Name;Last Name;Email;Age
1 champs à la ligne 2: 
Julie;Brown;julie@example.com;52
1 champs à la ligne 3: 
Dan;Wong;dan@example.com;19
1 champs à la ligne 4: 
Tim;Hortons;tim@example.com;27

当我使用“,”分隔符时,不是这样的

4 champs à la ligne 1: 
First Name
Last Name
Email
Age

此外,我想知道是否可以有各种分隔符。因为我想显示用户上传的 csv 文件,我不想强​​迫他们使用一个预定的分隔符。

谢谢

【问题讨论】:

  • 更新了我的答案,例如您的第二个问题,即使用用户定义的多个分隔符或逐行解析 CSV 数据。

标签: php csv


【解决方案1】:

第二个参数是长度,所以你的fgetcsv应该是

fgetcsv($handle, 0, ';');

导致

4 champs à la ligne 1: 

First Name
Last Name
Email
Age
4 champs à la ligne 2: 

Julie
Brown
julie@example.com
52
4 champs à la ligne 3: 

Dan
Wong
dan@example.com
19
4 champs à la ligne 4: 

Tim
Hortons
tim@example.com
27

关于变量分隔符的第二个问题。到目前为止,最简单的方法是允许用户定义要在上传表单上使用的分隔符,可能使用可接受分隔符的选择元素,然后在读取 csv 时使用它。

举例

function filter_delimiter($v) {
    return in_array($v, [',', ';'], true) ? $v : null;
}

//validate $_POST['delimiter'];
$delimiter = filter_input(INPUT_POST, 'delimiter', FILTER_CALLBACK, ['options' => 'filter_delimiter']);
if (!$delimiter) {
    $delimiter = ';';
    //optionally redirect to form error message
}

或者解析行以确定适当的分隔符。

$filename = "upload/".$_FILES['fichier']['name'];
if (($handle = fopen($filename, "r")) !== false) {
    $content = fread($handle, filesize($filename));
    fclose($handle);
    //count the delimiters
    $semiColons = substr_count($content, ';');
    $commas = substr_count($content, ',');
    //read each row
    $rows = str_getcsv($content, "\n");
    $rowCount = count($rows);
    $delimiter = null;
    foreach ($rows as $line => $row) {
        //check the delimiters
        if (false === isset($delimiter)) {
            /* 
              determine if the delimiter total divided by the number 
              of rows matches the delimiters found on this row 
              and use it to parse the columns 
            */
            if ($semiColons > 0 && $semiColons / $rowCount === substr_count($row, ';')) {
                $delimiter = ';';
            } elseif ($commas > 0 && $commas / $rowCount === substr_count($row, ',')) {
                $delimiter = ',';
            }
        }
        //read the columns using the detected delimiter 
        //otherwise use a default if a delimiter could not be determined
        $columns = str_getcsv($row, $delimiter ? : ';');
        echo "<p>$rowCount champs à la ligne " . ($line + 1) . "</p>\n";
        foreach ($columns as $column) {
            echo $column . "<br/>\n";
        }
    }
}

【讨论】:

    【解决方案2】:

    数组 fgetcsv ( 资源 $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\" ]]]])

    Manual

    第二个参数是长度。

    fgetcsv($handle, 0, ";")
    

    【讨论】:

    • 哦,非常感谢。您对我的第二个问题有解决方案吗?例如,有人使用“;”上传了一个 csv 文件分隔符和另一个带有“,”分隔符的分隔符如何处理这两种情况?以及其他带有其他分隔符的情况
    • 读取第一行并搜索;,并在之后使用或不使用fgetcsv并逐行读取文件并使用preg_split('/[;|,]/', $line)
    • 谢谢,我会看的:)
    【解决方案3】:

    函数fgetcsv 包含五个参数。这是它的声明:

    fgetcsv(resource, lenght, delimiter, enclosure, escape)
    

    这是我的资源file.csv:

    "mydata1|mydata2|mydata3|my;data;with;ugly"char;|myprice|etc|etc|
    

    在我的例子中,分隔符是一个竖线字符|。分号不是分隔符。由于数据中有双引号",因此我们使用单引号字符' 作为包围。没有外壳,输出将为空。

    这里是源代码:

    $mycsv = fopen("file.csv", "r");
    
    while (($data = fgetcsv($mycsv, 0, "|", "'")) == true) {
       print_r($data);
    }
    

    这是输出数据:

    Array
    (
        [0] => "mydata1
        [1] => mydata2
        [2] => mydata3
        [3] => my;data;with;ugly"char;
        [4] => myprice
        [5] => etc
        [6] => etc
        [7] => 
    )
    

    您还可以查看以下 Ideone sn-p:https://ideone.com/30OF1Kfile.csv 文件已替换为 stdin

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2011-06-13
      相关资源
      最近更新 更多