PHP 生成器

知识往往从需求中来,

那么下面就提出一个需求,比如 hank 哥上次给了一个 17.6G 的大sql文件,需要分析些数据粗来。接下来到我了,

首先,(知识点1)这可是个 17.6G 大文件,用phpMyadmin等数据库管理工具导入数据库里面是很慢的,这里有效的解决办法是,在控制台导入,它执行的真的很快。

打开控制台:cmd

cd C:\....(你的mysql路径下的bin文件夹下);//或把mysql加入到环境变量中去,这里不细说

mysql -uname -ppswd ;

use tname;

source hank.sql;

//然后就开始导入啦。

但是!

知识点2来了,source 命令还是Mysql命令,它的过程是每次执行一句sql并输出,效率还是不行。

不要紧,我们还有法器,用shell命令,mysql -u root -p dbname

这是shell命令,它会做一个批处理,也就是一次执行多条,不用我说了,效率高出很多倍!就用它了...

导入ing....

情节并没有想象的那么乏味,过了一会,导入停止,报告老板,某某某行 sql 语法存在错误。 我了个乖乖,咋么办尼,17.6G,我又不能通过编辑器打开,怎么查那条语句!

知识点3来了,写个程序读一下文件呗,读到出错那一行打印出来看看呗。

开始coding...

看起来是不是很完美?

再次但是,

知识点4来了,也是本文重点登场,上面代码,把所有17.6G的文件读入内存,去处理,你让内存怎么想?

没关系,下面介绍一个东西叫 PHP 生成器。

生成器读取文件的规则是一次读取一行,每次放入内存也就一行。调用生成器的函数,PHP 返回的是一个对象(Generator类的)。

生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,

生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。

这次就真的完美了!

不过话说回来,当时处理这个问题的时候,最终采取的方法是把数据库版本替换成了sql文件内容一致的版本。

把手册里关于生成器的例子贴到下面,加深一下理解。

标准的 range() 函数需要在内存中生成一个数组包含每一个在它范围内的值,然后返回该数组, 结果就是会产生多个很大的数组。 比如,调用 range(0, 1000000) 将导致内存占用超过 100 MB。

做为一种替代方法, 我们可以实现一个 xrange() 生成器, 只需要足够的内存来创建 Iterator 对象并在内部跟踪生成器的当前状态,这样只需要不到1K字节的内存。

不懂的留言,每天一篇分享,玩转我们共同的爱好!

你也来投搞!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171217G0104E00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券