Laravel 5.6でファイルのアップロードとダウンロード

Laravel 5.6でファイルのアップロードとダウンロードを行うプログラムを作成します。Laravel 5.6は「Laravel 5.6のインストール」でインストールしたLaravel を使用します。

フォームの作成

ファイルアップロード/ダウンロードするフォームをDashboard画面に追加するために、次のコードを「home.blade.php」に追加します。

resources\views\home.blade.php

        ・・・
{!! Form::open(['url' => '/upload', 'method' => 'post', 'files' => true]) !!}
    {{--成功時のメッセージ--}}
    @if (session('success'))
    <div class="alert alert-success">{{ session('success') }}</div>
    @endif
    {{-- エラーメッセージ --}}
    @if ($errors->any())
        <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
        </div>
    @endif
    <div class="form-group">
        {!! Form::label('file', 'ファイルアップロード', ['class' => 'control-label']) !!}
        {!! Form::file('file') !!}
    </div>
    <div class="form-group">
        {!! Form::submit('アップロード', ['class' => 'btn btn-default']) !!}
    </div>
{!! Form::close() !!}

{!! Form::open(['url' => '/download', 'method' => 'post', 'files' => true]) !!}
    <div class="form-group">
        <input type="hidden" name="userid" value="12345">
        <input name="loadfile" type="hidden" value="tomosoft.vi">
        {!! Form::submit('ダウンロード', ['class' => 'btn btn-default']) !!}
    </div>
{!! Form::close() !!}
        ・・・

次のようなファイルのアップロードとダウンロード可能なフォームになります。

フォームヘルパー「Form」のインストール

Laravel 5.6のビューでフォームヘルパー「Form」を使用する場合、composerを使用してFormクラスをインストールします。

プロジェクトのcomposer.jsonに次のように「laravelcollective/html」を一行追加します。

composer.json

    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "5.6.*",
        "laravel/tinker": "^1.0",
        "laravelcollective/html": "~5.0" ←追加
    },

つぎのコマンドを実行してフォームヘルパー「Form」をインストールします。

> composer update

Routeの追加

Routeを追加するために、ファイル「web.php」の末尾につぎのスクリプトを追加します。

routes\web.php

        ・・・
Route::post('/upload', 'HomeController@upload');
Route::post('/download', 'HomeController@download');

Controllerの実装

ファイルをアップロード/ダウンロードするために、コントローラ「HomeController.php」に次の構文を追加します。

app\Http\Controllers\HomeController.php

        ・・・
/**
 * ファイルアップロード処理
 */
public function upload(Request $request)
{
    // ① フォームの入力値を取得
    $inputs = \Request::all();

    // ② デバッグ: $inputs の内容確認
    //    dd($inputs);
    
    $this->validate($request, [
        'file' => [
            // 必須
            'required',
            // アップロードされたファイルであること
            'file',
            // ファイルであること
            'image',
            // MIMEタイプを指定
            'mimes:jpeg,png',
            // 最小縦横120px 最大縦横400px
            'dimensions:min_width=120,min_height=120,max_width=400,max_height=400',
        ]
    ]);

    if ($request->file('file')->isValid([])) {
        $mes = $request->file('file')->getClientOriginalName();
        $filename = $request->file->storeAs(
            'public/files', $mes
        );
        $user = User::find(auth()->id());
        $user->avatar_filename = basename($filename);
        $user->save();

        return redirect('/home')->with('success', '保存しました。'.$mes);
    } else {
        return redirect()
            ->back()
            ->withInput()
            ->withErrors(['file' => 'アップロードされていないか不正なデータです。']);
    }
}    
    
/**
* ファイルダウンロード処理
*/
public function download(Request $request)
{
    // ① フォームの入力値を取得
    $inputs = \Request::all();

    // ② デバッグ: $inputs の内容確認
    //dd($inputs);

    $pathToFile = '\AnimalflyUpdate\htdocs\upload\storage\app\public\files\file.csv';
    $filename =  $inputs['loadfile'];
    $headers = ['Content-Type' => 'text/csv'];
    return response()->download($pathToFile, $filename, $headers);
  
}
        ・・・

usersテーブルにカラムの追加

usersテーブルにカラムを追加してファイル名を保存します。次のコマンドで、Migrationファイルを作成します。

> php artisan make:migration add_avater_filename --table=users

「database\migrations」に作成されたファイル「xxxxx_2018_11_04_081432_add_avater_filename.php」に次のようにカラム「avatar_filename」を追加します。

database\migrations\xxxxx_2018_11_04_081432_add_avater_filename.php

        ・・・
 public function up()
 {
     Schema::table('users', function (Blueprint $table) {
         $table->string('avatar_filename', 100);
     });
 }
        ・・・

 public function down()
 {
     Schema::table('users', function (Blueprint $table) {
          $table->dropColumn('avatar_filename');
     });
 }
        ・・・

次のコマンドを実行します。

> php artisan migrate

phpMyAdminでusersテーブルを確認すると、次のようにカラム「avatar_filename」が追加されています。

シンボリックリンク作成

storageを公開するために次のコマンドでシンボリックリンクを作成します。

この操作は特に行わなくてもブラウザに表示されます。

> php artisan storage:link

作成したプログラムの実行

ブラウザから次のURLを入力すると、フォームの画面が表示されます。

http://localhost/upload/public/

(a)アップロード

「ファイルを選択」ボタンを押してファイルを選択し、「アップロード」ボタンを押します。アップロードが完了すると、次に示す画面のように、「保存しました」メッセージが表示され、その横にアップロードされたファイル名が表示されます。
ファイルのアップロード

アップロードされたファイルは、次のようにフォルダ「storage\app\public\files」に保存されます。
ファイルのアップロード結果

(b)ダウンロード

あらかじめ「storage\app\public\files」にファイル「file.csv」を作成しておきます。
「ダウンロード」ボタンを押すと、次のようにファイル名「tomosoft.vi」のファイルがダウンロードされます。
ファイルのダウンロード結果

フォームから渡されたデータの視覚化

次のスクリプトを使用することにより、Controllerに渡されたデータを可視化できます。なお、DD関数が実行されると以降の処理は実行されません。

    // ① フォームの入力値を取得
    $inputs = \Request::all();
 
    // ② デバッグ: $inputs の内容確認
    dd($inputs);

(a)「アップロード」ボタンを押したとき

「アップロード」ボタンが押されると、「HomeController@upload」に制御が移ります。ここで渡されるデータは次のようになります。

アップロード時のデータ表示

(b)「ダウンロード」ボタンを押したとき

「ダウンロード」ボタンが押されると、「HomeController@download」に制御が移ります。ここで渡されるデータは次のようになります。

ダウンロード時のデータ表示