分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

php 使用 生成器 yield关键字 处理 万级以上csv 文件,并重新导出

发布时间:2023-09-06 01:59责任编辑:苏小强关键词:暂无标签

  前几天有个任务是要解密excel中某个字段,本来是一个非常简单的事情,但问题是用phpexcel一直load不了excel,无论运行时间设置为不限,内存也增加到了2048M,仍然不行,最后各种问度娘,最后想到了前段时间看的生成器 yield, 刚好是一个测试的机会

  

class Qushu{ ???public function getDg(){ ???????set_time_limit(0); ???????$file = request()->get(‘file‘); ???????$path = ‘D:/path/‘.$file.‘.csv‘; ???????$key = ‘********‘; ???????$header = [‘订单‘,‘姓名‘,‘电话‘,‘地址‘,‘证件号‘,‘机构‘,‘社会代码‘,‘税务‘,‘测试‘,‘测试电话‘,‘得知‘,‘物品名称‘]; ???????$output = $this->csvSet("导出表名",$header); ???????$data = $this->getCsv($path); ???????$i = 0; ???????foreach ($data as $k=>$v) ???????{ ???????????if (!$v) break; ???????????$idcard = iconv(‘GBK‘,"UTF-8//TRANSLIT//IGNORE",$v[4]); ???????????// 根据条件判断是否要处理字段 ???????????if (!empty($idcard) && strlen($idcard)>18){ ???????????????// 处理字段的code.... ???????????????$v[4] = ‘‘; ???????????} ???????????//输出csv内容 ???????????fputcsv($output, array_values($v)); ???????????$i++; ???????} ???????//关闭文件句柄 ???????fclose($output) or die("can‘t close php://output"); ???????exit; ???} ???/** ???*获取csv内容 使用 yield ???*/ ???public function getCsv($fname) ???{ ???????$handle = fopen("$fname", ‘rb‘); ???????while (feof($handle)===false) { ???????????# code... ???????????yield fgetcsv($handle); ???????} ???????fclose($handle); ???} ???/**设置csv*/ ???public function csvSet($name,$head) ???{ ???????try { ???????????//设置内存占用 ???????????set_time_limit(0); ???????????ini_set(‘memory_limit‘, ‘512M‘); ???????????//为fputcsv()函数打开文件句柄 ???????????$output = fopen(‘php://output‘, ‘w‘) or die("can‘t open php://output"); ???????????//告诉浏览器这个是一个csv文件 ???????????header("Content-Type: application/csv"); ???????????header("Content-Disposition: attachment; filename=$name.csv"); ???????????header(‘Cache-Control:must-revalidate,post-check=0,pre-check=0‘); ???????????header(‘Expires:0‘); ???????????header(‘Pragma:public‘); ???????????// 文件名转码 ???????????$name = iconv(‘utf-8‘, ‘gbk‘, $name); ???????????//输出表头 ???????????foreach ($head as $i => $v) { ???????????????//CSV的Excel支持GBK编码,一定要转换,否则乱码 ???????????????$head[$i] = iconv(‘utf-8‘, ‘gbk‘, $v); ???????????} ???????????fputcsv($output, $head); ???????????return $output; ???????}catch (Exception $e){ ???????} ???}} ?

  从上面可以看出,只是通过 yield 标识就处理好了一个生成器,调用了 getCsv 方法获取到一个迭代器,那么通过循环此迭代器,进行逻辑操作即可。

总结:

  1. 生成器,提供了一种更容易的方法实现迭代,性能开销和复杂性大大降低
  2. 生成器函数看起来像普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值,并且每一次的生成返回值只是暂停当前的执行状态,当下次调用生成器函数时,PHP会从上次暂停的状态继续执行下去。
  3. 使用生成器处理大文件,由于yield 并不是一次取出全部数据,而是生成一个可以循环的迭代器,内部会为生成的值配对连续的整型索引,就像一个非关联的数组。每次循环,根据游标取指定的一条数据,节约内存资源

php 使用 生成器 yield关键字 处理 万级以上csv 文件,并重新导出

原文地址:https://www.cnblogs.com/wangfengzhu/p/9168338.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved