21273
よろしくお願いします。

ディレクトリをまるごとzipでダウンロードしたいです。

Windows8.1  
php 5.4.39  
Apache 2.2.14  
localでの実行です。

mysite  
|  
|-image  
| |-image1.png  
|  
|-file1.php  
|-file2.php

上記のような状態のものを、zipで圧縮してダウンロードすることが目標です。

コードは以下の通りです。

```

    <php
    
    //Zipクラスロード
    $zip = new ZipArchive();
    
    //Zipファイル名指定
    $zipFileName = 'mysite.zip';
    
    //Zipファイル一時保存ディレクトリ取得
    $zipTmpDir = '/phpdocs/nonprothemes';
    
    //Zipファイルオープン
    $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
    
    if ($result !== true) {
        return false;
    }
    
    //処理制限時間を外す
    set_time_limit(0);
    
    
    /* ファイルパスを指定する処理 */
    
    //mysite内のファイル一覧取得
    //ディクトリパス格納用変数
    $dir = null;
    $dir = 'mysite/';
    
    //ハンドル取得用変数
    $handle = null;
    //ファイル情報取得用変数
    $file = null;
    //ファイルパス指定用配列
    $fpath_array = array();
    
    //ディレクトリの存在確認、ハンドル取得
    if(is_dir($dir) && $handle = opendir($dir))
    {
        //ディレクトリ内のファイルを取得
        while(($file = readdir($handle)) !== false)
        {
            //'.','..'を取り除く処理
            if($file != "." && $file != "..")
            {
                //ファイルパス指定
                $fpath_array[] = 'mysite/'.$file;
            }
        }
    }
    
    //ファイルパス指定
    //$fpath_array = array('mysite/style.css','mysite/index.php');
    /* ここまで */
    
    //Zip追加処理
    foreach ($fpath_array as $filepath) {
        //filename取得
        $filename = basename($filepath);
    
        //取得ファイルをZipに追加
        $zip->addFromString($filename,file_get_contents($filepath));
        $zip->addFile($filepath);
    }
    
    $zip->close();
    
    // ストリームに出力
    header('Content-Type: application/zip; name="' . $zipFileName . '"');
    header('Content-Disposition: attachment; filename="' . $zipFileName . '"');
    header('Content-Length: '.filesize($zipTmpDir.$zipFileName));
    echo file_get_contents($zipTmpDir.$zipFileName);
    
    // 一時ファイルを削除しておく
    unlink($zipTmpDir.$zipFileName);
    ?>
    
```

現在、

> Warning: file_get_contents(mysite/images): failed to open stream:  
>  Permission denied in C:\phpdocs\nonprothemes\file_dw.php on line 62
>
> Warning: Cannot modify header information - headers already sent by  
>  (output started at C:\phpdocs\nonprothemes\file_dw.php:62) in  
>  C:\phpdocs\nonprothemes\file_dw.php on line 69
>
> Warning: Cannot modify header information - headers already sent by  
>  (output started at C:\phpdocs\nonprothemes\file_dw.php:62) in  
>  C:\phpdocs\nonprothemes\file_dw.php on line 70
>
> Warning: filesize(): stat failed for /phpdocs/nonprothemesmysite.zip  
>  in C:\phpdocs\nonprothemes\file_dw.php on line 71
>
> Warning: Cannot modify header information - headers already sent by  
>  (output started at C:\phpdocs\nonprothemes\file_dw.php:62) in  
>  C:\phpdocs\nonprothemes\file_dw.php on line 71
>
> Warning: file_get_contents(/phpdocs/nonprothemesmysite.zip): failed to  
>  open stream: No such file or directory in  
>  C:\phpdocs\nonprothemes\file_dw.php on line 72
>
> Warning: unlink(/phpdocs/nonprothemesmysite.zip): No such file or  
>  directory in C:\phpdocs\nonprothemes\file_dw.php on line 75

これらのエラーが出ています。

apacheの権限の問題なのかと思ったのですが、ネットで調べてみてもhttpd.confのどこにどう記述すればいいのかが分かりませんでした。

参考になるサイトなどありましたら教えていただきたいです。

XAMPPで動かしているときには正常に動いていましたが、XAMPPを消してApacheを入れなおしたら今回のようなことになってしまいました。

どのようにして解決したら良いでしょうか？  
よろしくお願いします。

/********* 追記 ***********/  
mysite/image(imageフォルダ)を消した場合、

(以下、パターン1)  
mysite.zip  
|  
|-mysite  
| |-file1.php  
| |-file2.php  
|  
|-file1.php  
|-file2.php

このような形でzipが出来上がりました。

ちなみに、

> $zip->addFromString($filename,file_get_contents($filepath));

こちらをコメントアウトした状態で実行すると、  
(以下、パターン2)  
mysite.zip  
|  
|-mysite  
| |-file1.php  
| |-file2.php

このような形でzipで出来上がります。

/********* 追記 ***********/

コードを修正した結果、  
中身の無い(?)8KBのzipフォルダが作成されました。  
ファイルを追加する所で代わりにファイルパスを表示した所、問題なくパスが来ていました。

以下コードです。

```

    $dist = 'mysite.zip'; // 生成する圧縮ファイル名
    $path = './mysite'; // 圧縮するパス
    $zipTmpDir = '/phpdocs/nonprothemes'; // 一時パス
    
    
    $zip = new ZipArchive();
    $zip->open($zipTmpDir.$dist, ZipArchive::CREATE | ZipArchive::OVERWRITE);
    addZip($zip, $path);
    $zip->close();
    
    function addZip($zip, $path) {
      if (is_dir($path)) {
        $files = array_diff(scandir($path), ['.', '..']);
        foreach ($files as $file) addZip($zip, "$path/$file");
      } else {
        $zip->addFile($path);
      }
    }
    
    // ストリームに出力
    header('Content-Type: application/zip; name="' . $dist . '"');
    header('Content-Disposition: attachment; filename="' . $dist . '"');
    header('Content-Length: '.filesize($zipTmpDir.$dist));
    echo file_get_contents($zipTmpDir.$dist);
    
    // 一時ファイルを削除しておく
    unlink($zipTmpDir.$dist);
    
```
CC BY-SA 3.0
2016-01-13T16:02:44.527
20891
2016-01-24T22:03:20.427
2016-01-18T04:38:08.137
13454
13454
question
php
ディレクトリを丸ごとzipでダウンロードしたい
自己解決することが出来ました。  
皆様コメントありがとうございました。

全てのファイルパスを、

> 圧縮したいフォルダ名/(サブフォルダ名)/ファイル名

このように統一して1つの配列にまとめ、addFileでzipに追加、圧縮という形になっています。  
サブフォルダはいくつあっても問題ありませんでした。  
空のサブフォルダが存在していてもエラーは出ません。  
しかし、圧縮したzipには空のサブフォルダは作られません。  
以下がコードです。

```

    <?php
    
    //Zipクラスロード
    $zip = new ZipArchive();
    
    //Zipファイル名指定
    $zipFileName = 'mysite.zip';
    
    //Zipファイル一時保存ディレクトリ取得
    $zipTmpDir = '/phpdocs/nonprothemes';
    $path = './mysite';
    $path2 = 'mysite';
    
    //Zipファイルオープン
    $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
    
    if ($result !== true) {
      return false;
    }
    
    //処理制限時間を外す
    set_time_limit(0);
    
    //パス取得
    $fpath_array_beta = array_diff(scandir($path), ['.', '..']);
    
    // zip追加する本命のパスを格納する配列
    $fpath_array = array();
    
    // ディレクトリ判別
    foreach ($fpath_array_beta as $key => $value) {
      if(is_dir("$path/$value")){
        // パス指定
        $path_sub = "$path/$value";
        // サブフォルダ内のファイル名取得
        $array_beta = array_diff(scandir($path_sub), ['.', '..']);
        // パスとして取得(元配列に追加)
        foreach ($array_beta as $key2 => $value2) {
          array_push($fpath_array,"$path2/$value/$value2"); 
        }
      }else{
        // ファイルの場合はそのまま追加
        array_push($fpath_array,"$path2/$value");
      }
    }
    
    // print "<pre />"; var_dump($fpath_array); print "<pre />";
    
    //Zip追加処理
    foreach ($fpath_array as $filepath) {
      $zip->addFile($filepath);
    }
    
    $zip->close();
    
    // ストリームに出力
    header('Content-Type: application/zip; name="' . $zipFileName . '"');
    header('Content-Disposition: attachment; filename="' . $zipFileName . '"');
    header('Content-Length: '.filesize($zipTmpDir.$zipFileName));
    echo file_get_contents($zipTmpDir.$zipFileName);
    
    // 一時ファイルを削除しておく
    unlink($zipTmpDir.$zipFileName);
    
```
CC BY-SA 3.0
2016-01-24T22:03:20.427
21273
2016-01-24T22:03:20.427
13454
20891
answer