Php 确保fgetcsv()读取整行

Php 确保fgetcsv()读取整行,php,csv,Php,Csv,我使用PHP使用fgetcsv()从CSV文件导入数据,这将为每一行生成一个数组。最初,我将字符限制设置为1024,如下所示: while ($data = fgetcsv($fp, 1024)) { // do stuff with the row } 但是,具有200+列的CSV在许多行上超过了1024个限制。这导致行读取在中间行停止,然后下一次调用FGETCVS.()将从先前的一个开始,直到到达EOL为止。 此后,我将此限制提高到4096,这应该可以处理大多数情况,但我希望进行一次检

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

while ($data = fgetcsv($fp, 1024)) {
  // do stuff with the row
}
但是,具有200+列的CSV在许多行上超过了1024个限制。这导致行读取在中间行停止,然后下一次调用FGETCVS.()将从先前的一个开始,直到到达EOL为止。 此后,我将此限制提高到4096,这应该可以处理大多数情况,但我希望进行一次检查,以确保在获取每一行后读取整行。我该怎么办


我想检查数组最后一个元素的末尾是否有行尾字符(\n\r\r\n),但这些字符不是通过fgetcsv()调用解析出来的吗?

只需忽略长度参数。它在PHP5中是可选的

while ($data = fgetcsv($fp)) {
  // do stuff with the row
}

只要不指定限制,fgetcsv()将尽可能多地插入以捕获整行。如果您确实指定了一个限制,那么就完全由您来扫描文件流,并确保您没有从中间分割某些内容


但是,请注意,如果您首先无法控制此.csv的生成,则不指定限制可能会有风险。恶意CSV在一行上有很多TB的数据,这很容易让您的服务器陷入困境。

谢谢您的建议,但这些解决方案确实没有解决知道我们占了最长的行,但仍然提供了限制的问题。我可以通过
shell_exec()
使用
wc-L
UNIX命令来完成这一任务,以便在开始行获取之前确定文件中最长的行。代码如下:

// 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
}

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

我会小心使用您的最终解决方案。我能够上传一个名为
/的文件。;ls-a;。csv执行命令注入。如果使用此方法,请确保验证文件路径。另外,如果您的
wc
因任何原因失败,最好提供
默认长度

// use wc to find max line length
// uses a hardcoded default if wc fails
// this is relatively safe from command 
// injection since the file path is a tmp file
$wc = explode(" ", shell_exec('wc -L ' . $validated_file_path));
$longest_line = (int)$wc[0];
$length = ($longest_line) ? $longest_line + 4 : $default_length;
默认情况下,
fgetcsv()
用于逐行读取csv文件,但当它不以这种方式工作时,您必须在操作系统机器上检查
PHP\u EOL
字符 你只需要去:
C:\xampp\php\php.ini
并搜索:

;自动检测线结束=关闭

并将其取消注释并激活以:

auto\u detect\u line\u endings=On


重新启动Apache并检查。应该有效

我考虑过这一点,但有两点:1)我无法控制CSV的生成。它们是由(不可靠的)客户提供的,所以我真的想施加某种限制。2) 手册中说“忽略此参数(或在PHP 5.0.4及更高版本中将其设置为0)最大行长不受限制,这稍微慢一点。”我担心“稍微慢一点”会对一个包含100k+行的CSV文件产生什么影响。稍微慢一点=分块读取文件,直到它在该块中的某个位置找到换行符,然后倒回文件指针,以便下一次读取在中断后立即开始。您可以单独进行逐行读取,然后使用进行csv->数组解析。此外,我意识到我可以通过编程方式确定文件中最长的行,但这可能会对非常大的csv文件造成很大的开销。想知道如何确保每一行都是动态读取的。或者如果需要设置分隔符,将其设置为“0”<代码>fgetcsv($handle,0,“;”)
。与PHP文档一样:
省略此参数(或在PHP 5.1.0及更高版本中将其设置为0),最大行长度不受限制,稍慢。