我有 n 个 csv 文件,我需要相互比较并在之后修改它们。问题是每个 csv 文件大约有 800.000 行。
要读取 csv 文件,我使用fgetcsv并且效果很好。获得一些内存矛,但最终它足够快。但是,如果我尝试将数组相互比较,则需要很长时间。
另一个问题是我必须使用 foreach 来通过 fgetcsv 获取 csv 数据,因为有 n 个文件。我最终得到了一个超大数组,无法与 array_diff 进行比较。所以我需要将它与嵌套的 foreach 循环进行比较,这需要很长时间。
一个代码片段,以便更好地理解:
foreach( $files as $value ) {
$data[] = $csv->read( $value['path'] );
}
Run Code Online (Sandbox Code Playgroud)
我的 csv 类使用 fgetcsv 将输出添加到数组中:
fgetcsv( $this->_fh, $this->_lengthToRead, $this->_delimiter, $this->_enclosure )
Run Code Online (Sandbox Code Playgroud)
所有 csv 文件的每个数据都存储在 $data 数组中。这可能是只使用一个数组的第一个大错误,但我不知道如何在不使用 foreach 的情况下保持文件的灵活性。我尝试使用灵活的变量名,但我也坚持使用:)
现在我有这个大数组。通常,如果我尝试将这些值相互比较并找出文件 1 中的数据是否存在于文件 2 中等等,我会使用 array_diff 或 array_intersect。但在这种情况下,我只有这个大数组。正如我所说,运行 foreach 需要很长时间。
同样在只有 3 个文件之后,我有一个包含 3 * 800.000 个条目的数组。我猜最近 10 个文件后我的记忆会爆炸。
那么有没有更好的方法来使用 PHP 来比较 …
我正在处理来自geonames.org的 csv文件,因此我需要获得没有任何机箱的csv线路.
目前fgetcsv()要求您为$enclosure参数提供单个字符,否则不会处理CSV数据.
如何使用php本机功能检索没有机箱字符的csv数据?
我正在 yii 框架中读取 csv 文件。它遍历文件中的每个单词,但只保存最后一个单词。例如,我的 csv 文件中有以下单词。
First
Second
Third
Fourth
Run Code Online (Sandbox Code Playgroud)
以下是我遍历文件的代码。
$fileHandler=fopen("upload.csv",'r');
if($fileHandler){
while($line=fgetcsv($fileHandler,1000)){
$model->image_url=$line[0];
$model->save();
}
}
Run Code Online (Sandbox Code Playgroud)
它只是在我的数据库中保存值“第四”。请指导。
PHP 中的 fputcsv() 和 fgetcsv() 似乎存在编码问题或错误。
以下 PHP 代码:
$row_before = ['A', json_encode(['a', '\\', 'b']), 'B'];
print "\nBEFORE:\n";
var_export($row_before);
print "\n";
$fh = fopen($file = 'php://temp', 'rb+');
fputcsv($fh, $row_before);
rewind($fh);
$row_after = fgetcsv($fh);
print "\nAFTER:\n";
var_export($row_after);
print "\n\n";
fclose($fh);
Run Code Online (Sandbox Code Playgroud)
给我这个输出:
BEFORE:
array (
0 => 'A',
1 => '["a","\\\\","b"]',
2 => 'B',
)
AFTER:
array (
0 => 'A',
1 => '["a","\\\\',
2 => 'b""]"',
3 => 'B',
)
Run Code Online (Sandbox Code Playgroud)
很明显,数据在途中被损坏。最初该行只有 3 个单元格,后来该行有 4 个单元格。由于反斜杠也用作转义字符,中间的单元格被分割。
另请参阅 https://3v4l.org/nc1oE 或者此处,使用分隔符、封装、escape_char 的显式值: https: //3v4l.org/Svt7m …
尝试使用filegetcsv以下代码解析CSV文件并对其进行处理,包括PHP函数定义页面:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
print_r($data);
}
fclose($handle);
}
Run Code Online (Sandbox Code Playgroud)
但是代码在线上给了我一个无限循环的警告$data =:
PHP Warning: fgetcsv() expects parameter 1 to be resource, boolean given in...
Run Code Online (Sandbox Code Playgroud)
我知道文件不是太大或者格式不正确,因为我不断缩小原始文件以查看是否存在问题,最后只是在记事本中创建了一个自定义文件,其中只有两行:
Value1A,Value1B,Value1C,Value1D
仍然循环并且不提供数据.这是我正在使用的完整代码(使用一个大于行数的变量,所以我可以证明它会无限循环,而不会给我的服务器一个无限循环)
if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE) {
while ((($data = fgetcsv($handle, 1000, ',')) !== FALSE) && ($row < 10)) {
print_r($data);
$row++;
}
fclose($handle);
}
Run Code Online (Sandbox Code Playgroud)
所以我真的有两个问题.
1)我可能忽略了什么导致这个循环?我半信半疑,这真的是"面对面"的简单......
2)如果文件存在但是存在一些未知问题,为什么推荐的此函数代码会导致无限循环?我本以为 …
您知道如何通过从 zip 文件读取 CSV 文件来提高性能吗?
首先打开zip文件,然后将数据放入内存中,然后通过读取fgetcsv
$zip = new ZipArchive();
if ($zip->open($fileName)) {
$info = $zip->statIndex(0);
$fp = $zip->getStream($info['name']);
if(!$fp) exit("failed\n");
while (!feof($fp)) {
$contents .= fread($fp, 2);
}
fclose($fp);
$zip->close();
}
$temp = fopen("php://memory", "rw");
fwrite($temp, $contents);
fseek($temp, 0);
while (($data = fgetcsv($temp, 0)) !== false) {
....
}
Run Code Online (Sandbox Code Playgroud) 我有一个CSV文件,其中包含一个初始标题行和一个未知行数.行格式为:
name_data,email_data,cell_data,dob_data
我想打开CSV文件,然后在表格中描绘最后输入的行中的数据,如下所示:
Name: name_data
Email: email_data
Cell: cell_data
D.O.B.: dob_data
Run Code Online (Sandbox Code Playgroud)
我想我可以使用fgetcsv()但是我不知道如何在获得数据后解析数据.
有任何想法吗?
谢谢 - 乔
我正在开发cakephp中的应用程序,我想导入csv文件并将数据保存到数据库中.
所以我需要一些帮助将csv文件读入数组,然后我将进行一些验证并将数据插入数据库.
我搜索了很多,但找不到解决方案.
提前致谢.
我的任务是解析制表符分隔文件并将值插入数据库.在下面找到选项卡分隔文件的选择.
"030-36-2" 0 0 14 "P"
"030-38-2" 0 0 14 "S"
"030-40-2" 0 0 14 "S"
"031-2-2" 1 0 "O"
"031-3-2" 4 0 "O"
"032-36-26" 0 0 14 "S"
"032-38-26" 0 0 14 "S"
"032-40-26" 0 0 14 "S"
"070-140-161" 0 0 14 "S"
"070-140-162" 2 0 "D"
"070-83-161" 0 0 14 "S"
Run Code Online (Sandbox Code Playgroud)
我正在使用fgetcsv将我的分隔符设置为tab(9)但是在执行代码时,我只获得了插入数据库的总值的一小部分.这是我的代码:
if(($handle = fopen("mytabdelimitedfile.txt","r"))!==FALSE){
fgetcsv($handle, 0,chr(9));
while(($data = fgetcsv($handle,1000,chr(9)))!==FALSE){
print_r($data[0]);
$result = mysql_query("INSERT INTO $table (col1,col2,col3,col4,col5) VALUES('$data[0]','$data[1]','$data[2]','$data[3]','$data[4]')");
}
}
Run Code Online (Sandbox Code Playgroud)
前4个记录未插入,但以"031-3-2"开头,然后跳至"070-140-162".我担心结果可能与某些值缺失有关,但我似乎无法辨别出一种模式.
有没有人对此有任何见解?该问题是否与某些值缺失有关?有没有解决方法?(我对源数据没有任何控制权)
还有一点需要注意:当我使用Excel =>从text => tab-delimited导入数据时,结果非常完美.但当然我不能使用Excel,因为数据每小时更新一次.请,正确方向的任何一点都将非常感激.