在写PHP程序的时候,须要处理的数据比较大的时候常常会出现“Allowed memory size of xxx bytes”这个问题,对这个问题通常也是去修改php.ini中的配置,那是一个颇有效的方法,可是有没有其余的办法来解决这个问题,固然是有,在这里我会从数据库查询和读文件的两个经常使用的例子来讲说这个问题的解决思路。
php
文章中我使用的机器配置并不算高,是ubuntu 14.04的系统。mysql
现有代码是:sql
$sql = "select * from `user` order by `id`"; $conn = mysql_connect($host, $user, $pwd); $db = mysql_select_db($db_name); $result = mysql_query($sql); if ($result) { while ($row = mysql_fetch_assoc($result)) { // 一些操做的代码 } }
果不其然,在我特地配置的小内存运行环境下出现了“Allowed memory size of xxx bytes” 的问题。数据库
原文代码处理是将全部数据先读取数据进入内存,而后在进行处理,在数据超出配置的最大内存的时候,就出现了这个提示。ubuntu
在php中这里有个说法,一个是缓存查询,就是咱们上面这种,另一种就是非缓存查询,思路和处理流文件的处理有些相似,只缓存须要处理的数据,这样虽然会增长一部分服务器的负载,可是在内存上会有些优化。缓存
好比在上面的样例中,我使用memory_get_usage();函数获取的内存使用为18973784 byte。下面我会展现三种写法以及截取的他们内存的占用状况,这样的对比可能不是很准确,可是提供思路为主,抛砖引玉。服务器
代码1:函数
$conn = mysql_connect($host, $user, $pwd); $db = mysql_select_db($db_name); $result = mysql_unbuffered_query($sql); if ($result) { while ($row = mysql_fetch_assoc($result)) { // 一些处理 } }
这个和样例的区别在于mysql_unbuffered_query这个函数,计算的内存占用为27392 byte。测试
代码2:fetch
$pdo = new PDO("mysql:host={$host};dbname={$db_name}", "{$user}", "{$pwd}"); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $result = $pdo->query($sql); if ($result) { while ($row = $result->fetch(PDO::FETCH_ASSOC)) { // 一些处理的代码 } }
代码2使用了pdo,计算出来的内存占用为 33672 byte
代码3:
$mysqli = new mysqli("{$host}", "{$user}", "{$pwd}", "{$db_name}"); $result = $mysqli->query("{$sql}", MYSQLI_USE_RESULT); if ($result) { while ($row = $result->fetch_assoc()) { // 一些操做的代码 } }
代码3使用的mysqli,内存的占用是9008 byte
附:测试内存占用使用的方法
$start = memory_get_usage(); // 操做代码 $end = memory_get_usage(); $used = $end - $limit; echo $used;