Heim >Backend-Entwicklung >PHP-Tutorial >PHP-CSV-Export
Dieser Artikel stellt den Inhalt des PHP-CSV-Exports vor, der einen bestimmten Referenzwert hat. Jetzt werde ich ihn mit Ihnen teilen , Freunde in Not können sich auf
Aktuelle Unternehmensprojekte erfordern zusätzlich die Ausgabe von Daten Es gibt zwar eine Exportfunktion, aber die Datenmenge ist dieses Mal relativ groß. Wenn der Import 7 oder 30 Tage dauert Die Datenmenge kann leicht eine Million oder sogar eintausend Wan überschreiten, daher habe ich während des Entwicklungsprozesses einige Fallstricke entdeckt, die ich gerne mit Ihnen teilen und voneinander lernen möchte.
set_time_limit – Legen Sie die maximale Ausführungszeit des Skripts fest:
Diese Konfiguration beträgt in PHP im Allgemeinen 30 Sekunden. Wenn Sie kleine Datenmengen haben, wird dieses Einstellungsproblem möglicherweise nicht auftreten, aber wenn Ihre Daten Millionen von Ebenen zum Exportieren erreichen, reichen 30 Sekunden oft nicht aus Sie müssen set_time_limit(0) zu Ihrem Skript hinzufügen, damit das Skript jetzt keine Ausführungszeit hat
memory_limit – PHP-Speicherlimit:
Dies Konfiguration Im Allgemeinen beträgt der Standardwert von PHP 128 MB. Wenn Sie zuvor kleine Datenmengen erstellt haben, haben Sie diese Konfiguration möglicherweise geändert, um viele Probleme zu lösen. Vielleicht denken einige Leute, dass Sie dies auch für große Datenmengen erhöhen können. Dann ist es wirklich zu jung und zu nativ. Wenn Sie 1G oder unbegrenzt lokal einstellen können, ist das möglicherweise kein Problem, aber in der formalen Welt wird früher oder später etwas passieren, wenn Sie dies tun. Ein PHP-Programm belegt so viel Speicher Wenn Sie den Betrieb und die Wartung Ihres Unternehmens anrufen, ist dies für die Server-Hardware wahrscheinlich zu aufwändig. Daher sollten wir versuchen, eine Erhöhung dieser Einstellung zu vermeiden.
Da wir Daten exportieren, dachte natürlich jeder sofort an das Excel-Format, das zum Anzeigen von Daten so praktisch ist. Allerdings hätten wir nie erwartet, dass Excel dies auch tut ein Temperament!
Tabellendatenlimit:
Excel 2003及以下的版本。一张表最大支持65536行数据,256列。 Excel 2007-2010版本。一张表最大支持1048576行,16384列。
1
2
Das heißt, wenn Sie problemlos Millionen von Elementen auf einmal in eine Excel-Tabelle importieren möchten, ist es nicht möglich, die Daten zumindest aufzuteilen, um dies sicherzustellen Die Daten dürfen 104 W pro Fläche nicht überschreiten.
PHPexcel-Speicherüberlauf:
Da die Daten auf 104 W begrenzt sind, ist Datenteilung gleich Datenteilung, also versuchen Sie, die Tabelle zu importieren Es gibt jedoch eine Funktion in PHPexcel, die einen Speicherüberlauffehler meldet. Anschließend wird ein Speicherüberlauffehler angezeigt, bis Sie jeweils 5 W importieren. Warum ist das so? Obwohl Sie die Daten aufteilen, um mehrere Datentabellen zu importieren, fügt PHPexcel am Ende immer noch alle Tabellendaten auf einmal in eine Variable ein, um die Datei zu erstellen ... Nun, diese Millionen von Daten werden in einer Variablen gespeichert willst du? Es ist wirklich schwierig zu verhindern, dass die Erinnerung überläuft.
(Später habe ich einige Artikel gelesen und festgestellt, dass PHPExcel auch eine Lösung hat. Die Methode PHPExcel_Settings::setCacheStorageMethod ändert die Puffermethode, um die Speichernutzung zu reduzieren)
Excel ist so mühsam. Ist es nicht in Ordnung, wenn ich es nicht verwende? Ich verwende CSV-Dateien, um sie zu speichern. Ich kann sie auch direkt mit Excel anzeigen. Ist es nicht großartig, das Ziel zu erreichen? ein Stein? Hey, was für eine tolle Idee, junger Held! Doch CSV hat auch seine Tücken!
Zu viele Ausgabepuffer:
Wenn Sie die native PHP-Funktion putcsv() verwenden, verwenden Sie tatsächlich den Ausgabepufferpuffer Geben Sie ein paar ein. Wenn mit dieser Funktion immer Millionen von Daten ausgegeben werden, ist der Ausgabepuffer zu groß und es wird ein Fehler gemeldet. Daher müssen wir den Inhalt des Ausgabepuffers alle bestimmte Zeit herausnehmen und auf den Wert setzen Wartender Ausgabezustand. Der spezifische Vorgang ist:
ob_flush();flush();
1
2
具体说明介绍:PHP flush()与ob_flush()的区别详解
EXCEL查看CSV文件数量限制:
大多数人看csv文件都是直接用EXCEL打开的。额,这不就是回到EXCEL坑中了吗?EXCEL有数据显示限制呀,你几百万数据只给你看104W而已。什么?你不管?那是他们打开方式不对而已?不好不好,我们解决也不难呀,我们也把数据分割一下就好了,再分开csv文件保存,反正你不分割数据变量也会内存溢出。
分析完上面那些坑,那么我们的解决方案来了,假设数据量是几百万。
1、那么我们要从数据库中读取要进行数据量分批读取,以防变量内存溢出,
2、我们选择数据保存文件格式是csv文件,以方便导出之后的阅读、导入数据库等操作。
3、以防不方便excel读取csv文件,我们需要104W之前就得把数据分割进行多个csv文件保存
4、多个csv文件输出给用户下载是不友好的,我们还需要把多个csv文件进行压缩,最后提供给一个ZIP格式的压缩包给用户下载就好。
//导出说明:因为EXCEL单表只能显示104W数据,同时使用PHPEXCEL容易因为数据量太大而导致占用内存过大, //因此,数据的输出用csv文件的格式输出,但是csv文件用EXCEL软件读取同样会存在只能显示104W的情况,所以将数据分割保存在多个csv文件中,并且最后压缩成zip文件提供下载 function putCsv(array $head, $data, $mark = 'attack_ip_info', $fileName = "test.csv") { set_time_limit(0); $sqlCount = $data->count(); // 输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: application/vnd.ms-excel;charset=utf-8'); header('Content-Disposition: attachment;filename="' . $fileName . '"'); header('Cache-Control: max-age=0'); $sqlLimit = 100000;//每次只从数据库取100000条以防变量缓存太大 // 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小 $limit = 100000; // buffer计数器 $cnt = 0; $fileNameArr = array(); // 逐行取出数据,不浪费内存 for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) { $fp = fopen($mark . '_' . $i . '.csv', 'w'); //生成临时文件 // chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限 $fileNameArr[] = $mark . '_' . $i . '.csv'; // 将数据通过fputcsv写到文件句柄 fputcsv($fp, $head); $dataArr = $data->offset($i * $sqlLimit)->limit($sqlLimit)->get()->toArray(); foreach ($dataArr as $a) { $cnt++; if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题 ob_flush(); flush(); $cnt = 0; } fputcsv($fp, $a); } fclose($fp); //每生成一个文件关闭 } //进行多个文件压缩 $zip = new ZipArchive(); $filename = $mark . ".zip"; $zip->open($filename, ZipArchive::CREATE); //打开压缩包 foreach ($fileNameArr as $file) { $zip->addFile($file, basename($file)); //向压缩包中添加文件 } $zip->close(); //关闭压缩包 foreach ($fileNameArr as $file) { unlink($file); //删除csv临时文件 } //输出压缩文件提供下载 header("Cache-Control: max-age=0"); header("Content-Description: File Transfer"); header('Content-disposition: attachment; filename=' . basename($filename)); // 文件名 header("Content-Type: application/zip"); // zip格式的 header("Content-Transfer-Encoding: binary"); // header('Content-Length: ' . filesize($filename)); // @readfile($filename);//输出文件; unlink($filename); //删除压缩包临时文件 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
其实上面代码还是有优化的空间的,比如说用异常捕捉,以防因为某些错误而导致生成了一些临时文件又没有正常删除,还有PHPexcel的缓存设置也许能解决内存溢出问题,可以生成一个EXCEL文件多个工作表的形式,这样对于文件阅读者来说更友好。
以上便是本人对PHP大数据导出的见解,希望能帮到您们,同时不足的地方请多多指教!
————————————————————————————————————
2017年12月17日
PS:最近了解其实关于内存溢出的问题,用迭代器来处理会方便多了。
版权声明:每一篇原创文章都是我的心血,欢迎转载,但请转载前留个评论,感谢您的支持!!! https://blog.csdn.net/Tim_phper/article/details/77581071
相关推荐:
Das obige ist der detaillierte Inhalt vonPHP-CSV-Export. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!