storage/appディレクトリに保存されたファイルのダウンロードを行う方法は1つではなくいくつかの方法があります。その方法について記述しています。

ダウンロードするための準備

ダウンロードするファイルはstorage/app/private/profile.pngファイルです。ブラウザから/profileにアクセスするとダウンロードできるように設定を行います。

web.phpのルーティングとDownloadController.phpファイルの作成を行います。


Route::get('/download', 'DownloadController@index');

php artisan make:controllerコマンドを利用してコントローラーの作成を行います。


$ php artisan make:controller DownloadController
Controller created successfully.

書き換える内容はindexメソッドの中のみになります。Storageを使用する場合は、useを使ってIlluminate\Support\Facades\Storageを読み込みます。


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Storage;

class DownloadController extends Controller
{
    public function index(){

      //ここにコードを記述していく

    }
}

Storageを使う方法

Storageに使用するドライバはデフォルトのlocalを使用します。使用するドライバによってStorageを使った場合のファイルパスの設定が変わるので、注意してください。本文書ではStorageのメソッドがいくつか登場します。使わなくてもLaravelの開発は行なえますが、便利な機能なのでわからない人は下記を参考にしてください。

Storage::download()を使った方法

Storageを使用した場合は、ルートパスがappになるのでstorage/app/private/profile.pngへのパスはprivate/profile.pngになります。

mimeTypeはStorage::mimeType()を使って取得しています。

localドライバのルートパスの設定はfilesystems.phpで設定されています
fukidashi

$filePath = 'private/profile.png';

$fileName = 'profile.png';

$mimeType = Storage::mimeType($filePath);

$headers = [['Content-Type' => $mimeType]];

return Storage::download($filePath, $fileName, $headers);

Storage::response()を使った方法

Storage::download()とほとんど同じですが、引数に$dispositonを設定することができます。デフォルトではinlineに設定されており、デフォルトのままだとファイルのダウンロードではなく画像がそのままブラウザに表示されます。$dispositionの値をattachmentに変更するダウンロードを行うことができます。


$filePath = 'private/profile.png';

$fileName = 'profile.png';

$mimeType = Storage::mimeType($filePath);

$headers = [['Content-Type' => $mimeType]];

$disposition = 'attachment';

return Storage::response($filePath, $fileName, $headers, $disposition);

response()->download()を使った方法

response()関数のdownloadメソッドを使ってファイルのダウンロードを行うことができます。

Storageを使う場合と異なり、ファイルパスの指定場所が異なります。ファイルのパスはStorage::path()もしくはstorage_path()を利用して取得します。

storage_path(),Storage::path()の結果は環境により異なるので、わからない場合はdd(storage_path())等で確認を行ってください。
fukidashi

$filePath = Storage::path('private/profile.png');

$fileName = 'profile.png';

$mimeType = Storage::mimeType('private/profile.png');

$headers = [['Content-Type' => $mimeType]];

return response()->download($filePath, $fileName, $headers);

response()->make()を使った方法

response()関数のmakeメソッドを使ってファイルのダウンロードを行うことができます。

これまではファイルのパスを使っていましたが、makeではファイルのコンテンツを指定します。

ファイルのコンテンツの取得は、Storage::get()を利用します。ヘッダーのContent-Dispositionはattachmentを設定します。


$fileName = 'profile.png';

$mimeType = Storage::mimeType('private/profile.png');

$file = Storage::get('private/profile.png');

$headers = [
    'Content-Type' => $mimeType,
    'Content-Disposition' => 'attachment; filename="'.$fileName .'"'
];

return response()->make($file, 200, $headers);

response()->stream()を使った方法

response()関数のstreamメソッドを使ってファイルのダウンロードを行うことができます。

これまではファイルのパスとコンテンツを指定しましたが、今回はcallback関数を指定する必要があります。


$filePath = 'private/profile.png';

$fileName = 'profile.png';

$mimeType = Storage::mimeType($filePath);

$callback = function(){
	return Storage::get($filePath);
};

$headers = [
    'Content-Type' => $mimeType,
    'Content-Disposition' => 'attachment; filename="'.$fileName .'"'
];

return response()->stream($callback, 200, $headers);