0

そのため、データベースからレコードを読み取り、ユーザーがダウンロードするテキスト ファイルに保存するという簡単な解決策でなんとかやり遂げたいと考えていました。私はこれをオンザフライで実行しており、20,000 レコード未満の場合、これはうまく機能します。20,000 を超えるレコードとメモリにロードするデータが多すぎて、PHP で致命的なエラーが発生します。

私の考えは、すべてをチャンクで取得することでした。したがって、XX 行を取得してファイルにエコーし、完了するまでループして次の XX 行を取得します。

ただし、ファイルをビルドしてからダウンロード用に送信するのではなく、現在結果をエコーし​​ています。これは、実行する必要があると推測しています。

この時点での問題は、簡潔に言うと、最大 20,000 行で、ファイルが完全にビルドおよびダウンロードされることです。それ以上の場合、空のファイルが得られます。

コード:

header('Content-type: application/txt');
header('Content-Disposition: attachment; filename="export.'.$file_type.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');

// I do other things to check for records before, hence the do-while loop
$this->items = $model->getItems();

do {
    foreach ($this->items as $k => $item) {
        $i=0;
        $tables = count($this->data['column']);
        foreach ($this->data['column'] as $table => $fields) {
            $columns = count($fields);
            $j = 0;
            foreach ($fields as $field => $junk) {
                if ($quote_output) {
                    echo '"'.ucwords(str_replace(array('"'), array('\"'), $item->$field)).'"';
                } else {
                    echo ''.$item->$field.'';
                }
                $j++;
                if ($j<$columns) {
                    echo $delim;
                }
            }
            $i++;
            if ($i<$tables) {
                echo $delim;
            }
        }
        echo "\n";
    }
} while($this->items = $this->_model->getItems());
4

3 に答える 3

1

非常に大きなテーブルはそのようには機能しません。

データベースから読み取ったデータを出力する必要があります。並べ替える必要がある場合は、データベース ORDER BY を使用してください。

だから多かれ少なかれ

// assuming you use a var such as $query to handle the DB
while(!$query->eof())
{
  $fields = $query->read_next();
  echo $fields; // with your formatting, maybe call a function...
}

空の結果は正常です。エコーが発生する前にメモリが使い果たされた場合、ブラウザには何も送信されませんでした。

PHP には時間制限 (ウォッチドッグ) があり、調整が必要な場合があることにも注意してください。デフォルトは php.ini で定義されています。テーブルが非常に大きくなると予想される場合は、ゼロに設定できます。

于 2013-06-27T02:38:34.127 に答える
0

実際、これは簡単な修正かもしれません。PHP のメモリが不足している場合は、ファイルが送信される前に出力バッファがいっぱいになっている可能性があります。もしそうなら、単にflush()定期的に。

これは各行の後にフラッシュされます:

do {
    foreach(...) {
       // assemble your output line here
    }
      echo "\n";
      flush();
    }
} while($this->items = $this->_model->getItems());

各行の後にフラッシュすると遅すぎることが判明する可能性があります。その場合は、カウンターを追加して 100 行ごとにフラッシュするか、最善の方法を選択してください。

于 2013-06-27T02:47:56.440 に答える
0

の str_replace を変更する必要がありますaddslashes()。これにより、おそらくいくらかのメモリが解放されます。

次に、ファイルを保存し、php ファイル関数を使用して保存することをお勧めします:fopen()またはfile_put_contents().

それがあなたの助けになることを願っています!

于 2013-06-27T02:38:23.770 に答える