exportation php-csv

不言
Libérer: 2023-03-24 12:56:01
original
2581 Les gens l'ont consulté



Cet article présente le contenu de l'exportation php csv, qui a une certaine valeur de référence. Maintenant, je vais le partager avec vous. , Les amis dans le besoin peuvent se référer à


Aperçu :


Les projets récents de l'entreprise nécessitent que les données soient sorties en plus de pages. Il existe une fonction d'exportation. Bien que j'aie déjà effectué plusieurs fonctions d'exportation, la quantité de données cette fois est relativement importante. Il y a près de 200 000 données en une journée. la quantité de données peut facilement dépasser un million, voire mille. Wan, j'ai donc découvert quelques pièges dans l'exportation du Big Data au cours du processus de développement. J'aimerais les partager avec vous et apprendre les uns des autres.

Préparation :

1. Fosse de paramétrage PHP :

  • set_time_limit – Définir le temps d'exécution maximum du script :

Cette configuration est généralement de 30 secondes par défaut en PHP. Si vous avez de petites données, vous ne rencontrerez peut-être pas ce problème de paramétrage, mais si vos données atteignent des millions de niveaux à exporter, 30 secondes ne suffisent souvent pas, donc vous devez ajouter set_time_limit(0) à votre script pour que le script n'ait plus de temps d'exécution maintenant

  • memory_limit – Limite de mémoire PHP :

Ceci configuration Généralement, la valeur par défaut de PHP est 128M. Si vous avez déjà utilisé du small data, vous avez peut-être modifié cette configuration pour résoudre de nombreux problèmes. Peut-être que certaines personnes pensent, pouvez-vous également augmenter cette valeur pour le big data ? Ensuite, c'est vraiment trop jeune et trop natif. Si vous pouvez définir 1G ou illimité localement, cela ne pose peut-être pas de problème, mais dans le monde formel, quelque chose se produira tôt ou tard si vous faites cela. Un programme PHP occupe une si grande mémoire. espace. Si vous appelez, l'exploitation et la maintenance de votre entreprise aideront à ajuster la configuration. Je suppose que l'exploitation et la maintenance doivent être très réticentes à faire cela pour le matériel du serveur. Nous devrions donc essayer d’éviter d’augmenter ce paramètre.

2. Les pièges d'Excel :

Puisque nous exportons des données, bien sûr, tout le monde a immédiatement pensé au format Excel, qui est si pratique pour visualiser les données. Cependant, nous ne nous attendions pas à ce qu'Excel le soit également. un tempérament !

  • Limite de données du tableau :

Excel 2003及以下的版本。一张表最大支持65536行数据,256列。
Excel 2007-2010版本。一张表最大支持1048576行,16384列。
Copier après la connexion
  • 1

  • 2

C'est-à-dire que si vous souhaitez importer facilement des millions d'éléments dans une table EXCEL à la fois, ce n'est pas possible. Vous devez au moins diviser les données pour vous en assurer. les données ne peuvent pas dépasser 104W par surface.

  • Débordement de mémoire PHPexcel :

Comme les données sont limitées à 104W, alors la division des données est une division de données, vous essayez donc d'importer la table 50 W à la fois. Cependant, il existe une fonction dans PHPexcel qui signale une erreur de dépassement de mémoire, puis vous continuez à réduire la quantité de données jusqu'à ce que vous importiez 5 W à la fois, vous trouverez une erreur de dépassement de mémoire. Pourquoi ? Bien que vous ayez divisé les données pour importer plusieurs tables de données, PHPexcel place toujours toutes les données de la table dans une seule variable pour créer le fichier... Eh bien, ces millions de données sont stockées dans une seule variable. tu veux ? C'est vraiment difficile d'empêcher la mémoire de déborder.
(Plus tard, j'ai lu quelques articles et découvert que PHPExcel avait également une solution. La méthode PHPExcel_Settings::setCacheStorageMethod modifie la méthode de mise en mémoire tampon pour réduire l'utilisation de la mémoire)

3. EXCEL est tellement gênant, n'est-ce pas normal si je ne l'utilise pas ? J'utilise des fichiers csv pour les stocker. Il n'y a pas de limite de quantité. Je peux les visualiser directement via EXCEL. Je peux également importer les fichiers dans la base de données plus tard. N'est-ce pas génial de faire d'une pierre deux coups ? Hé, quelle bonne idée, jeune héros ! Mais le CSV comporte aussi des pièges !

    Trop de tampons de sortie :
  • Lorsque vous utilisez la fonction native PHP putcsv(), vous utilisez en fait le tampon de sortie si vous le faites. mettez-en quelques-uns Si des millions de données sont toujours sorties à l'aide de cette fonction, le tampon de sortie sera trop grand et une erreur sera signalée. Par conséquent, nous devons retirer le contenu du tampon de sortie tous les certain temps et le définir sur le. état de sortie en attente. L'opération spécifique est :

ob_flush();flush();
Copier après la connexion
    1
  • 2

具体说明介绍:PHP flush()与ob_flush()的区别详解

  • EXCEL查看CSV文件数量限制:

大多数人看csv文件都是直接用EXCEL打开的。额,这不就是回到EXCEL坑中了吗?EXCEL有数据显示限制呀,你几百万数据只给你看104W而已。什么?你不管?那是他们打开方式不对而已?不好不好,我们解决也不难呀,我们也把数据分割一下就好了,再分开csv文件保存,反正你不分割数据变量也会内存溢出。

4、总结做法

分析完上面那些坑,那么我们的解决方案来了,假设数据量是几百万。

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 . &#39;_&#39; . $i . &#39;.csv&#39;, &#39;w&#39;); //生成临时文件
      //     chmod(&#39;attack_ip_info_&#39; . $i . &#39;.csv&#39;,777);//修改可执行权限
            $fileNameArr[] = $mark . &#39;_&#39; .  $i . &#39;.csv&#39;;        // 将数据通过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(&#39;Content-disposition: attachment; filename=&#39; . basename($filename)); // 文件名
        header("Content-Type: application/zip"); // zip格式的
        header("Content-Transfer-Encoding: binary"); //
        header(&#39;Content-Length: &#39; . filesize($filename)); //
        @readfile($filename);//输出文件;
        unlink($filename); //删除压缩包临时文件
    }
Copier après la connexion
  • 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

相关推荐:

php 逐行读取csv数据入库

PHP进行读取CSV文件数据和生成CSV文件

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!