一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

PHP实现导入大量CSV数据介绍

时间:2022-09-19 编辑:坚强 来源:一聚教程网

本篇文章为大家详细的介绍了关于PHP实现导入大量CSV数据,本文通过详细的介绍和代码呈现给大家,感兴趣的小伙伴快来一起学习学习吧。

代码部分

一. controller 写法

//获取请求的参数
$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 读取数据以及处理空行方法

/**

* @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 几种方法:

方法一


方法二

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;
        }
    }
}
?>

方法三

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数据介绍的全部内容了,感兴趣的小伙伴记得点击关注哦。

热门栏目