DBテーブルやファイルからの読み込みの際、対象データが少ない時はいいのですが、データ量が多くなるとmemory_limitエラーとなったりします。そんなときの最低限度の対応方法について。
DB編
バッファしない
ここによると、クエリは基本バッファされるようなので、明示的に非バッファクエリを実行します。
fetchAll()を呼ばない
いろいろなサンプルはfetchAll()をするものが多いのですが、これはその名の通り、全部取ってくるようなので、ただのfetchを使うほうがいいようです(もしくは、単に($stmt as $row)などとする)。
融合すると下記のような感じ。
<?php
$dbh = new PDO('mysql:host=localhost;dbname=testdb','user','pass');
//非バッファクエリの設定
$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,false);
$stmt = $dbh->prepare('select * from members');
$stmt->execute();
//fetchAllしない
foreach($stmt as $row)
{
echo $row['name']."<br>";
}
ループ部を、
while($row = $stmt->fetch())
{
echo $row['name']."<br>";
}
としてもよい。
Laravel
Laravelでは、QueryLogの記憶をdisableにする。
DB::connection()->disableQueryLog();
ファイル編
ファイルの読み取り事も対応はいろいろあるようですが、5.5以降であれば、ジェネレーターを利用するのが教科書通りなのかなと。
こんな感じ。
<?php
function readRows($filename)
{
//対象ファイルオープン
$fp = fopen($filename,'r');
//最初の1行を読む
$row = fgets($fp);
//最後のlineまでループ
while($row !== false)
{
//値を戻す
yield $row;
//次の行を読む
$row = fgets($fp);
}
//ファイルクローズ
fclose($fp);
}
//
$rows = readRows('input.txt');
foreach($rows as $row)
{
echo $row."<br>";
}