在寫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;