服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - PHP教程 - PHP实现导入大量CSV数据的示例代码

PHP实现导入大量CSV数据的示例代码

2022-11-11 16:16PHP开源社区 PHP教程

这篇文章主要为大家详细介绍了PHP如何实现导入大量CSV数据功能,文中的示例代码讲解详细,对我们学习PHP有一定帮助,需要的可以参考一下

前言

网上有很多介绍大量上传数据的,感觉都是一个抄一个,这是自己写的处理方式,在一些项目中已经应用.

主要利用 yield 完成文件读取,这个重点看会了,其他基本就很简单.

代码部分

一. controller 写法

?
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
//获取请求的参数
$arrayParams = Request::all();
$objCsvFile = $arrayParams['csv_file'];
$strRealPath = $objCsvFile->getRealPath();//tmp路径, 这里可以先保存到自己预定路径,再进行读取
 
//**************重点在这一步********************//
$glob = CommonUtilFunction::readPathCsvFile($strRealPath);
//********************************************//
 
$intRowNum = 0;
while($glob->valid()) {
    $arrayNewLineData = [];
    $intRowNum++;
    if (1 === $intRowNum) {
        //第一行跳过,一般是标题
        $glob->next();
        continue;
    }
    $arrayLineData = $glob->current();
 
    //处理空字符串 空行
    /**
    * 一般csv有两种行数据可以被认为是空行
    * 第一种 ',,,,,,,,,,,,,,,,,,,,,,,,,,',类似这种纯逗号没有任何数据
    * 第二种 '                          ',是真的空行,什么也没有
    * 处理完成返回一个统一的数组 []
    */
    $arrayLineData = CommonUtilFunction::dealCsvLineData($arrayLineData);
    //跳过空行
    if (true === empty($arrayLineData)) {
        $glob->next();
        continue;
    }
    
    //自己的代码逻辑
    ...
    
    // 避免意外错误
    unset($arrayNewLineData);
    $glob->next(); // 处理下一行数据
 
}

二. yield 读取数据以及处理空行方法

?
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
/**
 
* @description 迭代器读取csv文件
* @param $strCsvPath
* @return \Generator
  */
  public static function readPathCsvFile($strCsvPath)
  {
    if ($handle = fopen($strCsvPath, 'r')) {
        while (!feof($handle)) {
            yield fgetcsv($handle);
        }
        fclose($handle);
    }
  }
 
 
/**
 
* @description 处理c单行信息
* @param $arrData
* @return \Generator
  */public static function dealCsvLineData($arrData = [])
  {
    $arrAfterData = [];
    if (false === empty($arrData)) {
        //去除每个字符串 前后空格
        foreach ($arrData as &$colData) {
            //检测对应编码格式 csv文件格式Shift-JIS
            $strEncodeType = mb_detect_encoding($colData, ['UTF-8', 'Shift-JIS']);
            //如果认为utf-8格式不用转码, shift-jis格式需要转为utf8格式
            if ('SJIS' === $strEncodeType) {
                //jis=>utf8
                $colData = mb_convert_encoding($colData, 'UTF-8', 'Shift-JIS');
            }
            $colData = trim($colData);
        
        //去除空行
        $isEmptyRow = true;
        foreach ($arrData as $item) {
            if ('' !== $item) {
                $isEmptyRow = false;
                break;
            }
        
        if (false === $isEmptyRow) {
            $arrAfterData = $arrData;
        }
    }
    return $arrAfterData;
  }

结论

使用 yield 可以很大程度上减低服务器开销,压力在数据库方面。上限没有测试过,不过 1 万条数据是很轻松.

知识点补充

yield是php5.6版本才有的函数,作用是实现生成器,作用的在读取文件的时候,可以一行一行的读取

简单的说可以理解为 php版本的非缓冲查询,意思即是 把数据一行行 读取到php运行内存,并非一次性读取到php运行内存,众所周知,php有很多内置函数,可以帮助我们对数据进行加工操作,因为数据都在内存里面,所以能操作,但是php的运行内存是有极限,默认128M。

以下附上php 实现 yield 链接 mysql 几种方法:

方法一

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$link = mysqli_connect('localhost','root','','advertising');
if( $result1 = mysqli_query($link, 'SELECT * FROM `test`',MYSQLI_USE_RESULT) )
{
    $result = $result1;
//    unset($result1);
//    mysqli_close($link); //如果这里切断 mysql 链接 将无法获取 数据,原因是加了MYSQLI_USE_RESULT
    while ( $res = mysqli_fetch_assoc($result1) ){
        echo $res['a'] . PHP_EOL;
        $i++;
        if( $i ==1000  ){
            exit;
        }
    }
}
?>

方法二

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$pdo = new \PDO('mysql:host=localhost;dbname=advertising','root','');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$res = $pdo->query("SELECT * FROM `test`");
//unset($pdo);
$i = 0;
if ($res) {
    while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
        echo $row['a'] . PHP_EOL;
        $i++;
        if( $i ==1000  ){
            exit;
        }
    }
}
?>

方法三

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$mysqli  = new mysqli("localhost", "root", "", "advertising");
$uresult = $mysqli->query("SELECT * FROM `test`", MYSQLI_USE_RESULT);
//$uresult->close();
if ($uresult) {
    while ($row = $uresult->fetch()) {
        echo $row['a'] . PHP_EOL;
        $i++;
        if( $i ==1000  ){
            exit;
        }
    }
}

到此这篇关于PHP实现导入大量CSV数据的示例代码的文章就介绍到这了,更多相关PHP导入CSV数据内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://mp.weixin.qq.com/s/U4tdvE_r3D4wJf6g_uss8g

延伸 · 阅读

精彩推荐
  • PHP教程php等比例缩放图片及剪切图片代码分享

    php等比例缩放图片及剪切图片代码分享

    这篇文章给大家分享的是使用php实现的等比例缩放图片及剪切图片的代码,非常的简单实用,附上用法,有需要的小伙伴可以参考下。...

    PHP教程网4062020-12-20
  • PHP教程php生成二维码时出现中文乱码的解决方法

    php生成二维码时出现中文乱码的解决方法

    这篇文章主要介绍了php生成二维码时出现中文乱码的解决方法,较为详细的分析了php生成二维码的方法,以及出现乱码时的解决方法,具有一定的参考借鉴价值...

    PHP教程网1802020-08-22
  • PHP教程PHP可逆加密/解密函数分享

    PHP可逆加密/解密函数分享

    很多项目的会员系统,都要求要有记住登录功能,在通过cookies实现功能是,由于要将客户信息直接保存到cookies,如果直接写入cookies势必会带来安全隐患,...

    PHP教程网5662020-01-12
  • PHP教程PHP实现mysqli批量执行多条语句的方法示例

    PHP实现mysqli批量执行多条语句的方法示例

    这篇文章主要介绍了PHP实现mysqli批量执行多条语句的方法,结合实例形式分析了php连接mysqli并批量执行多条语句的相关操作技巧,需要的朋友可以参考下...

    3wlog5512021-06-07
  • PHP教程PHP中命名空间的使用例子

    PHP中命名空间的使用例子

    今天小编就为大家分享一篇关于PHP中命名空间的使用例子,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看...

    CODETC6112021-07-27
  • PHP教程PHP中phar包的使用教程

    PHP中phar包的使用教程

    php中的phar类似于java中的打包文件jar,即将一个文件夹中的一类文件压缩。下面这篇文章主要给大家介绍了关于PHP中phar包使用的相关资料,文中介绍的还是...

    leayrainy5542021-05-28
  • PHP教程如何用RabbitMQ和Swoole实现一个异步任务系统

    如何用RabbitMQ和Swoole实现一个异步任务系统

    从最开始的使用redis实现的单进程消费的异步任务系统到加入swoole的多进程消费模式,现在,我们的异步任务系统终于又能迈进一步。这回基于RabbitMQ的异步...

    八重樱6012021-11-17
  • PHP教程让你的PHP7更快之Hugepage用法分析

    让你的PHP7更快之Hugepage用法分析

    这篇文章主要介绍了让你的PHP7更快之Hugepage用法,较为详细的分析了php7中Hugepage的功能与具体的设置技巧,需要的朋友可以参考下...

    Laruence6072021-01-24