确保fgetcsv()读取整行

Dan*_*rno 7 php csv

我使用PHP使用fgetcsv()从CSV文件导入数据,这会为每行生成一个数组.最初,我将字符限制设置为1024,如下所示:

while ($data = fgetcsv($fp, 1024)) {
  // do stuff with the row
}
Run Code Online (Sandbox Code Playgroud)

但是,具有200多列的CSV超过了许多行的1024限制.这导致行读取停止在行的中间,然后下一次调用fgetcsv()将从前一个停止的地方开始,依此类推,直到达到EOL.

我已将此限制提高到4096,这应该照顾大多数情况,但我想检查以确保在获取每一行后读取整行.我该怎么做?

我正在考虑检查数组的最后一个元素的结尾是否为行尾字符(\n,\ r,\ r \n \n),但这些不会被fgetcsv()调用解析出来吗?

Roc*_*mat 8

只需省略length参数即可.它在PHP5中是可选的.

while ($data = fgetcsv($fp)) {
  // do stuff with the row
}
Run Code Online (Sandbox Code Playgroud)

  • 或者如果您还需要设置分隔符,请将其设置为“0”。`fgetcsv($handle, 0, ";")`。根据 PHP 文档:“省略此参数(或在 PHP 5.1.0 及更高版本中将其设置为 0)最大行长度不受限制,这会稍微慢一些。” (2认同)

Dan*_*rno 0

感谢您的建议,但这些解决方案确实没有解决我们在提供限制的同时占据最长线路的问题。我能够通过使用wc -LUNIX 命令 viashell_exec()在开始获取行之前确定文件中最长的行来完成此操作。代码如下:

// open the CSV file to read lines
$fp = fopen($sListFullPath, 'r');

// use wc to figure out the longest line in the file
$longestArray = explode(" ", shell_exec('wc -L ' . $sListFullPath));
$longest_line = (int)$longestArray[0] + 4; // add a little padding for EOL chars

// check against a user-defined maximum length
if ($longest_line > $line_length_max) {
    // alert user that the length of at least one line in the CSV is too long
}

// read in the data
while ($data = fgetcsv($fp, $longest_line)) {
    // do stuff with the row
}
Run Code Online (Sandbox Code Playgroud)

这种方法确保每一行都被完整读取,并且仍然为非常长的行提供安全网,而无需使用 PHP 逐行遍历整个文件。