クラウドサービスのDropboxやOneDriveでは保存したフォルダをダウンロードするとダウンロードされるフォルダは圧縮され、zipファイルとしてダウンロードすることができます。

Laravel上でも同様にダウンロードしたいフォルダ下に保存されている複数のファイルを一括でダウンロードしたい場合にどうやって行うのか本文書で手順を確認します。

LaravelにはZipperパッケージを使ってzipファイルを作成することができます。またPHPにはZipArhiveというクラスを使いzipファイルを作成することができます。Zipperを使った方法とphpが持っているZipArchiveというクラスを使った方法の2つで動作確認を行います。

Zipperパッケージのzip作成処理は内部でZipArchiveを利用しています。そのため実際は、どちらの方法でもZipArhiveを使っていることになります。ZipperパッケージはLaravel上でZipArhiveの実行を簡単に行うために作成されています。

Laravelのバージョン5で動作確認を行っています。Laravelのバージョン6以上でZipperパッケージが利用できない場合はMadzipperパッケージを確認してみてください。
fukidashi

事前準備

zipファイルの作成を行うためにzipファイル化するファイルが存在している必要があります。通常はそれらのファイルはファイルアップロードを使ってそれぞれの環境に合わせて適切な場所に保存されています。今回は動作確認のため事前にファイルの準備を行なっておきます。

Laravelのインストールディレクトリ(/Users/mac/laravel58/)にあるpublic/storageディレクトリとstorage/app/publicディレクトリにシンボリンクリンクを貼っておきます。


$ php artisan storage:link
The [public/storage] directory has been linked.
storage/app/publicディレクトリに保存したファイルはpublic/storageディレクトリからアクセスすることが可能となります。
fukidashi

storage/app/publicディレクトリの下にfilesディレクトリを作成し、以下の2つのファイルを保存しておきます。


$ pwd
/Users/reffect/mac/storage/app/public/files
test $ ls
logotype.min.svg	vapor-screenshot.png

Zipperパッケージを使用する方法

Zipperパッケージのインストール

composerを利用して、chumper/zippkerパッケージのインストールを行います。


$ composer require chumper/zipper
Using version ^1.0 for chumper/zipper

Zipperの設定

zipperのインストールが完了したら、サービスプロバイダーとaliasの設定を行います。

config/app.phpファイルを開いて下記のようにChumper\Zipper\ZipperServiceProvider::classを追加します。


'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    // 中略 

    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
    Chumper\Zipper\ZipperServiceProvider::class, //ここに追加

],

aliasへの追加も行います。


'aliases' => [

    'App' => Illuminate\Support\Facades\App::class,

    //中略

    'View' => Illuminate\Support\Facades\View::class,
    'Zipper' => Chumper\Zipper\Zipper::class, //ここに追加

],

以上で設定は完了です。

Zipファイルの作成

設定が完了したので、storage/app/public/files下に保存しておいたファイルを圧縮してzipファイルにします。

動作確認なので、ルーティングファイルのweb.phpファイル内で処理を行います。


Route::get('/', function () {

   $files = glob(public_path().'/storage/files/*'); //(1)

   Zipper::make('test.zip')->add($files)->close(); //(2)

    return response()->download(public_path().'/test.zip'); //(3)

});

“/”にアクセスするとLaravelのインストールディレクトリの下のpublicディレクトリの中にtest.zipファイルが作成されます。

(1)ではglob関数を利用して配列でfiles下にあるファイル一覧の情報(パス)を取得しています。


array:2 [▼
  0 => "/Users/mac/laravel58/public/storage/files/logotype.min.svg"
  1 => "/Users/mac/laravel58/public/storage/files/vapor-screenshot.png"
]

pulic_path()はLaravelで用意されているヘルパー関数でpublic_path()を実行するとLaravelインストールディレクトリ下のpublicディレクトリまでのフルパスを取得することができます。環境に依存しますが本環境では、”/Users/mac/laravel58/public”です。

Laravelにはpublic_path()以外にもパスを取得するためのヘルパー関数が用意されています。storage_path()など使用することができます。
fukidashi

(2)ではzipファイルを作成しています。デフォルトではLaravelのインストールディレクトリの下にあるpublicフォルダにtest.zipという名前でファイルが作成されます。

addメソッドでファイルの一覧を渡し、closeメソッドでzipファイルを作成は完了です。

(3)で作成したzipファイルをダウンロードすることができます。

ZipArchiveクラスを利用した方法

PHPのZipArchiveクラスを利用してzipファイルを作成します。コードは下記のようになり、”/”にアクセスするとtest2.zipファイルがダウンロードされます。


Route::get('/', function () {

	$files = glob(public_path().'/storage/files/*'); //(1)

	$zip = new ZipArchive(); //(2)

	$zip->open(public_path().'/test2.zip', ZipArchive::CREATE); //(3)

	foreach($files as $file){

		$file_info = pathinfo($file);

		$file_name = $file_info['filename'].'.'.$file_info['extension'];

		$zip->addFile($file, $file_name); //(4)

	}

	$zip->close(); (5)

    return response()->download(public_path().'/test2.zip'); //(6)

});

(1)ではglob関数を利用して配列でfiles下にあるファイル一覧の情報(パス)を取得しています。

(2)ZipArchiveをインスタンス化しています。

(3)test2.zipというファイル名でzipファイルを作成し、オープンしています。ZipArhive::CREATEはzipファイルが存在しなければzipファイルの作成を行います。ファイルが存在せず、ZipArhive::CREATEを指定していない場合はエラーになり処理することができません。

(4)addFileメソッドでzipにファイルを追加しています。第1引数に追加するファイルのパス、第2引数にファイル名を指定しています。

path_infoメソッドを使うことでファイルパスからファイル名、拡張子などを取得することができます。
fukidashi

もし第2引数にファイル名を指定していない場合は、zipフォルダを解答するとファイルがフルパスで保存されてしまいます。

(5)追加が完了したらcloseメソッドで追加を終了します。

(6)作成したzipファイルをダウンロードすることができます。

ZipArhiveクラスを使用しても複数のファイルをまとめてzipファイル化してダウンロードすることができますが、Zipperパッケージを利用したほうがコードも短く簡単に作成することができます。

Laravelに保存されているファイルをzipファイルとして取得したい場合はぜひ上記の方法で実行してみてください。