PowerCMS X Q&A

PowerCMS Xを用いてWebサイトを構築する際の技術的なヒントや解決策をご紹介します。

多数のオブジェクトをCSVエクスポートしたいのですが完了しません

CSVエクスポートは単純にデータベースから読み取ったデータをファイルに書き込んでいるだけですが、モデル設計(特にバイナリやリレーション)やミドルウェア(Apache・nginx・php-fpm)の設定状況によってはデータが大きくなり上手くエクスポートできない場合があるようです。以下の点を確認してください。

  • フィルタを使用し、オブジェクトの数を減らしてCSVエクスポートを試してください
  • Webサーバーやphp-fpm等のログでプロセスが途中で終了していないかを確認してください
  • バイナリカラムのデータを含む場合、環境変数export_without_binでバイナリカラムのデータを含めないようにします
  • 環境変数{model}_csv_exclude_colsでエクスポートする必要のないカラムを除外します(ver.3.5以降)

行数がとても多い場合

例えばログやアクティビティ等で10万行のような非常に大きなデータ(テキストデータのみ)をCSVエクスポートしたい場合、プラグインでカスタム・メソッドを用意して下記のようなコードを記述すると軽快にCSV化できる可能性があります。カスタム・メソッドの詳細は「 プラグイン作成の基礎 | PowerCMS X」をご覧ください。

public function download_objects_csv(Prototype $app)
{
    // 適宜設定
    $file_path = $app->temp_dir . DS . 'tmp' . DS . 'mt_log.csv';
    $zip_path = $app->temp_dir . DS . 'mt_log.zip';
    $model = 'log';

    $fp = fopen($file_path, 'w');

    // データ取得
    $terms = [];
    $args = [
        'sort' => 'id',
        'direction' => 'descend',
    ];
    $sth = $app->db->model($model)->load_iter($terms, $args);

    if (!$sth) {
        $app->error('Invalid request.');
    }

    // 各行をCSVに書き込む
    while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
        fputcsv($fp, $row);
    }

    fclose($fp);

    if (file_exists($file_path)) {
        PTUtil::make_zip_archive(dirname($file_path), $zip_path);
        PTUtil::export_data($zip_path);
        unlink($file_path);
        unlink($zip_path);
    }
}

関連するQ&A