【问题标题】:fopen() returning unexpected array with Mac Excel generated csvfopen() 使用 Mac Excel 生成的 csv 返回意外数组
【发布时间】:2013-10-14 22:56:31
【问题描述】:

我遇到了一个有趣的问题。我用 Excel 创建了一个 CSV 文件,并尝试使用 fopen()fgetcsv() 将文件读入 PHP。出乎意料的是,我的代码返回的数组让我认为该文件有一行有 76 个字段,而 5 行有 16 个(我知道,数学不正确......稍后会解释)。 TextEdit 消除了该理论,因为它为每一行呈现文件时都带有新行。当我在 TextEdit 中删除新行,然后为每一行重新输入一个换行符时,csv 被正确读取。

在删除新行之前,我在 NetBeans 中使用显示隐藏字符功能打开了文件,netbeans 似乎认为它是一个段落。似乎fopen() 没有。

我从php str_getcsv array issue 看到了类似的问题,我使用了第一个示例中提供的代码,但无济于事。看起来 Excel 确实提供了一个换行符,大多数其他东西都将其识别为换行符,但 fopen() 没有。这是我的代码和 csv 文件,以防人们感兴趣。

$data= array();      
$handle = fopen(Yii::app()->basePath ."/csv/test.csv", "rb");
while ( !feof($handle) ) {
    $data[] = fgetcsv($handle);

}
echo "<pre>";
die(var_dump($data));
fclose($handle);

这是 csv 文件:

id,first_name,last_name,address_1,address2,city,state,postal,image_path1,image_path2,image_path3,image_path4,image_path5,text_area,template_name,order_date
id,first_name,last_name,address_1,address2,city,state,postal,image_path1,image_path2,image_path3,image_path4,image_path5,text_area,template_name,order_date
id,first_name,last_name,address_1,address2,city,state,postal,image_path1,image_path2,image_path3,image_path4,image_path5,text_area,template_name,order_date
best ever!,,,704 west jefferson,,winterset,ia,50273,,,,,,,dummy,
hello!!,,,Welcome,,,,,,,,,,,,

这是一个指向 Excel 表格屏幕截图的链接:http://grab.by/r9sg

另外,我刚刚注意到每一行的最后一个字段都有一个新行,即应该是第一行末尾的数组值是order\nid(我认为......它至少有\n 在字符串中...)。这看起来很奇怪...我将提供我从 var_dump 中看到的数组...:

array(1) {
  [0] =>
  array(76) {
    [0] =>
    string(2) "id"
    [1] =>
    string(10) "first_name"
    [2] =>
    string(9) "last_name"
    [3] =>
    string(9) "address_1"
    [4] =>
    string(8) "address2"
    [5] =>
    string(4) "city"
    [6] =>
    string(5) "state"
    [7] =>
    string(6) "postal"
    [8] =>
    string(11) "image_path1"
    [9] =>
    string(11) "image_path2"
    [10] =>
    string(11) "image_path3"
    [11] =>
    string(11) "image_path4"
    [12] =>
    string(11) "image_path5"
    [13] =>
    string(9) "text_area"
    [14] =>
    string(13) "template_name"
    [15] =>
    string(13) "order_date
id"
    [16] =>
    string(10) "first_name"
    [17] =>
    string(9) "last_name"
    [18] =>
    string(9) "address_1"
    [19] =>
    string(8) "address2"
    [20] =>
    string(4) "city"
    [21] =>
    string(5) "state"
    [22] =>
    string(6) "postal"
    [23] =>
    string(11) "image_path1"
    [24] =>
    string(11) "image_path2"
    [25] =>
    string(11) "image_path3"
    [26] =>
    string(11) "image_path4"
    [27] =>
    string(11) "image_path5"
    [28] =>
    string(9) "text_area"
    [29] =>
    string(13) "template_name"
    [30] =>
    string(13) "order_date
id"
    [31] =>
    string(10) "first_name"
    [32] =>
    string(9) "last_name"
    [33] =>
    string(9) "address_1"
    [34] =>
    string(8) "address2"
    [35] =>
    string(4) "city"
    [36] =>
    string(5) "state"
    [37] =>
    string(6) "postal"
    [38] =>
    string(11) "image_path1"
    [39] =>
    string(11) "image_path2"
    [40] =>
    string(11) "image_path3"
    [41] =>
    string(11) "image_path4"
    [42] =>
    string(11) "image_path5"
    [43] =>
    string(9) "text_area"
    [44] =>
    string(13) "template_name"
    [45] =>
    string(21) "order_date
best ever!"
    [46] =>
    string(0) ""
    [47] =>
    string(0) ""
    [48] =>
    string(18) "704 west jefferson"
    [49] =>
    string(0) ""
    [50] =>
    string(9) "winterset"
    [51] =>
    string(2) "ia"
    [52] =>
    string(5) "50273"
    [53] =>
    string(0) ""
    [54] =>
    string(0) ""
    [55] =>
    string(0) ""
    [56] =>
    string(0) ""
    [57] =>
    string(0) ""
    [58] =>
    string(0) ""
    [59] =>
    string(5) "dummy"
    [60] =>
    string(8) "
hello!!"
    [61] =>
    string(0) ""
    [62] =>
    string(0) ""
    [63] =>
    string(7) "Welcome"
    [64] =>
    string(0) ""
    [65] =>
    string(0) ""
    [66] =>
    string(0) ""
    [67] =>
    string(0) ""
    [68] =>
    string(0) ""
    [69] =>
    string(0) ""
    [70] =>
    string(0) ""
    [71] =>
    string(0) ""
    [72] =>
    string(0) ""
    [73] =>
    string(0) ""
    [74] =>
    string(0) ""
    [75] =>
    string(0) ""
  }
}

我想我试图解释为什么如果我只是在编辑器(Netbeans、Coda、TextEdit)中删除一个新行并重新输入新行代码会按预期工作,但如果我没有使用excel生成的文件。想法?提前感谢您的帮助。

【问题讨论】:

  • 如果 PHP 在读取 Macintosh 计算机上或由 Macintosh 计算机创建的文件时无法正确识别行尾,启用 auto_detect_line_endings 运行时配置选项可能有助于解决问题。

标签: php excel csv


【解决方案1】:

您使用的是 Mac。在 Mac OS 的 UNIX 化之前,CR(ASCII 代码 13)是 Mac 的换行符。 Post Mac OS X, LF (ASCII code 10) 是换行符。

Excel 显然表现得像 Mac OS X 之前的应用程序并使用 CR 作为换行符,这会混淆在 UNIX 机器上运行的 PHP,它需要 LF。

TextEdit 识别两种换行约定以实现兼容性,但优先插入 LF 作为换行符,因为这是 UNIX 工具所期望的。这就是为什么删除和重新插入换行“修复”问题的原因; CR 正在悄悄地被替换为 LF。

修复 CSV 文件的最简单方法是使用 UNIX 命令:

tr '\015' '\012' new.csv

【讨论】:

  • 感谢您的解释以及修复 csv 的解决方案!
猜你喜欢
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多