質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • PHP

    20302questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHPでディレクトリをZIPファイル化したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 197

Zu_Chan

score 8

実現したいこと

PHPでリンクをクリックすると自動でダウンロードが始まる機能を実装しました。
ローカル環境では動作しますが、グローバルサーバにアップロードするとダウンロードリンクがうまく機能せず、ページが遷移してしまいます。
プログラムの改善点やアドバイスをいただければ幸いです。

追記

Ziparchiveを導入したところページは動作しましたが、できていたZIPファイルの出力ができなくなってしまいました。
・ディレクトリ
download.php
csv(フォルダ)
image(フォルダ)
の位置関係です。

環境

さくらVPS ubuntu

<?php
namespace My;

/**
 * ZipArchiveを拡張して、ディレクトリまるまる扱う機能を追加
 */
class MyZipArchive extends \ZipArchive
{
    /**
     * ディレクトリをまるごとzipファイルにします。
     *
     * @param string $dir              ディレクトリパス
     * @param string $inner_path       zipファイル中のディレクトリパス
     * @param bool   $create_empty_dir 空ディレクトリもディレクトリを作成するか
     * @return bool  処理の成否
     */
    public function addDir($dir, $inner_path, $create_empty_dir=false){
        $items = \array_diff(\scandir($dir), ['.','..']);
        $item_count = \count($items);

        if($create_empty_dir || $item_count > 0){
            $this->addEmptyDir($inner_path);
        }

        // 追加するものがないならここで終了する
        if($item_count === 0) return true;


        foreach($items as $_item){ // forで行うなら$itemsは一旦array_values()を通したほうがいい
            $_path = $dir . DIRECTORY_SEPARATOR . $_item;
            $_item_inner_path = $inner_path . DIRECTORY_SEPARATOR . $_item;

            // ディレクトリの場合は再帰的に処理する
            if(\is_dir($_path)){
                $_r = \call_user_func( // "$this->addDir"より保守的に好ましい
                    [$this, __FUNCTION__], $_path, $_item_inner_path);
                if(!$_r) return false;
            }
            // ファイルの場合でかつ処理に失敗したときはこちら
            else if(!$this->addFile($_path, $_item_inner_path)
                  && !$this->on_recursive_error($dir, $inner_path, $create_empty_dir)){
                return false;
            }
            // ファイルの追加成功時は何も他には行わない
        }

        return true;
    }

    /**
     * 再帰的処理のときにエラーが生じたらどうするかを定義しています。
     *
     * @param string $parent_dir              ディレクトリパス
     * @param string $parent_inner_path       zipファイル中のディレクトリパス
     * @param bool   $create_empty_dir        空ディレクトリもディレクトリを作成するか
     * @return bool Falseならその場で中断
     */
    private function on_recursive_error($parent_dir, $parent_inner_path, $create_empty_dir){
        // 自由に定義してください
        return false;
    }
}


/*
 * 下記は、質問本文のコードをちょっと改造してのテスト
 */

//Zipクラスロード
$zip = new MyZipArchive();

//Zipファイル名指定
$zipFileName = '***.zip';

//Zipファイル一時保存ディレクトリ取得
$zipTmpDir = '../';

// Zipファイルのパス
$zip_file = $zipTmpDir . DIRECTORY_SEPARATOR . $zipFileName;

//Zipファイルオープン
$result = $zip->open($zip_file, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE);

if ($result !== true) {
    return false;
}

//処理制限時間を外す
set_time_limit(0);

// ※今回の肝
$zip->addDir('csv', 'csv', true);
$zip->addDir('images', 'images', true);

$zip->close();


// ストリームに出力
header('Content-Type: application/zip; name="' . $zipFileName . '"');
header('Content-Disposition: attachment; filename="' . $zipFileName . '"');
header('Content-Length: '.filesize($zip_file));
echo file_get_contents($zip_file);

// 一時ファイルを削除しておく
unlink($zip_file);
exit();
?>

参考
https://ja.stackoverflow.com/questions/14416/複数ファイルや-フォルダも含むディレクトリをまるごとzipで圧縮して-ダウンロードさせたい

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yoorwm

    2017/12/12 16:50

    「※今回の肝」の4行下に>がありますが、コピペミスでしょうか?

    キャンセル

  • Zu_Chan

    2017/12/12 16:52

    コピペミスです。修正します。

    キャンセル

回答 1

check解決した方法

0

自己解決しました。
サーバサイドの権限が原因でした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20302questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。