laravel12.laravel_103
R e i - D r e a m
for Laravel
TOP > Laravel Ver.12 > その他中間モジュール(ファイル操作)
Guest
login

最終投稿日:2026年3月17日

ファイル操作
Storageクラス
『Storage』クラスを使用する事で『~\storage\app』内のファイルを簡単に制御できます。
また、[artisan]コマンドを叩く事で{WebRoot}以下でもないのに公開用のファイルを管理できます。
さっそく叩いてみましょう。
artisan

C:\~\laravel_12>php artisan storage:link
    INFO The [C:\~\laravel_12\laravel_12\storage] link has been connected to [C:\~\storage\app/public].

C:\~\laravel_12>

まぁ単純にシンボリックリンクを作成するだけなんですけどね。。
これで『~\storage\app\public』で管理するファイルは、『localhost/laravel_12/storage』で公開されます。
公開したくないファイルは「~\storage\app\private」で管理しましょう。
メモ

Laravel ver.12から「Storage」クラスが参照するルートディレクトリが変更となりました。

【Ver.12以前】~\storage\app
【Ver.12以降】~\storage\app\private
                               ~\storage\app\public
コード『Storage::disk('local')->path('')』をダンプすると確認できます。
※ ルートを変更したい場合は「\config\filesystems.php」で、連想配列《local》を編集します。

それでは簡単な例として『~\storage\app\private\files\hoge.txt』を読み込んで『~\storage\app\private\hoge』へ別名で保存してみましょう。
では任意のコントローラに以下を追記してみましょう。
任意のコントローラ

use Illuminate\Support\Facades\Storage;
~ 省略 ~
    public function index(Request $request) {

        $content = Storage::get('files\hoge.txt');
        Storage::put('hoge/foo.txt', $content);

たったこれだけです。
この処理で『~\storage\app\private\files\hoge.txt』のコピーが『~\storage\app\private\hoge\foo.txt』に作成されました。
その他色々な処理が可能です。
○ ファイルを削除する
Storage::delete('hoge/foo.txt');
Storage::delete(['hoge/foo.txt', 'files/hoge.txt']);
○ ディレクトリ含め削除する
Storage::deleteDirectory('files');
○ ファイルの存在確認
Storage::exists('files/hoge.txt');
Storage::disk('local')->exists('files/hoge.txt');
○ ファイル作成
Storage::put('files/foo.txt', 'ほげ');
○ ファイルのダウンロード
$mimeType = Storage::mimeType('text/plain');
return Storage::download('files/hoge.txt', 'bar.txt', ['Content-Type' => $mimeType]);
《任意のディレクトリにあるファイルをダウンロードする方法》
$mimeType = Storage::mimeType('text/plain');
$path = resource_path();
$full_path = $path . '/sql/users_name.sql';
return response()->download($full_path, 'hoge.sql', ['Content-Type' => $mimeType]);
Fileクラス
ファイル情報を扱うクラスとなります。 また、注意点としてLaravelには『File』クラスは2つあります。
① use Illuminate\Http\File;
② use Illuminate\Support\Facades\File;
①はファイル情報を管理するクラスです。
②はファイル操作を制御するクラスです。
非常に紛らわしので以下の様にエイリアス名を付けて区別します。
・use Illuminate\Http\File as FileInfo;
・use Illuminate\Support\Facades\File;
○ ファイル情報を取得する
例えば『~\resources\sql\users_name.sql』にあるファイルを操作してみましょう。
任意のコントローラ

use Illuminate\Http\File as FileInfo;
~ 省略 ~
    // 対象ファイルのフルパス設定;
    $path = resource_path();
    $full_path = $path . '/sql/users_name.sql';
    // ファイル存在確認
    if (file_exists($full_path)) {
        // ファイル情報取得
        $file = new FileInfo($full_path);
        // フルパス取得
        $hoge = $file->getPathname();
        // ファイル名(拡張子含む)取得
        $hoge = $file->getFilename();
        // 拡張子取得
        $hoge = $file->getExtension();
        // MIMEタイプ取得
        $hoge = $file->getMimeType();
        // ファイルサイズ(バイト)取得
        $hoge = $file->getSize();
        // 実際の絶対パス取得
        $hoge = $file->getRealPath();
    }

○ ファイル操作
例えば『~\resources\sql』に『hoge.txt』を作成しましょう。
任意のコントローラ

use Illuminate\Support\Facades\File;
~ 省略 ~
    // 対象ファイルのフルパス設定
    $path = resource_path();
    $full_path = $path . '/sql/hoge.txt';
    // ファイルを書き出す
    File::put($full_path, '内容');
    // ファイルを存在確認して削除する
    if (File::exists($full_path)) {
        File::delete($full_path);
    }
    // コピー
    File::copy($full_path, $path . '/sql/new.txt');
    // 移動
    File::move($full_path, $path . '/sql/new.txt');
    // 追記
    File::append($full_path, '追記内容');

○ ファイルのアップロード
まずはアップロード画面を作成するためルート設定をします。
以下の様に[GET][POST]遷移用を作成します。
Route::get('/hoge/upload', [App\Http\Controllers\HogeController::class, 'upload'])->name('hoge.upload');
Route::post('/hoge/upload', [App\Http\Controllers\HogeController::class, 'upload'])->name('hoge.upload');
次にコントローラですが、とりあえず以下な感じで。
任意のコントローラ

public function upload(Request $request) {
    if ($request->method() == 'GET') {
        return view('hoge/upload', []);
    } elseif($request->method() == 'POST') {
        //
    }
}

次に画面『~\resources\views\hoge\upload.blade.php』を作成します。
任意のビュー

<html>
    <head>
        <title>アップロード画面</title>
    </head>
    <body>
        {{-- バリデーションエラー表示 --}}
        @if ($errors->any())
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        @endif
        
        <form method="POST" action="upload" enctype="multipart/form-data">
            @csrf
            <input type="file" name="file">
            <BR>
            <button type="submit">アップロード</button>
        </form>
        
    </body>
</html>

画面が表示できる様になりました。
これでサブミットできる様になりましたが、肝心のPOST遷移用ロジックを記述していないため追記します。
任意のコントローラ

public function upload(Request $request) {
    if ($request->method() == 'GET') {
        return view('hoge/upload', []);
    } elseif($request->method() == 'POST') {

        // バリデーション
        $request->validate([
            'file' => 'required|max:2048',
        ]);
        // ファイルオブジェクト取得
        $file_info = $request->file('file');
    }
}

さて、ファイルオブジェクトを取得できましたが、このオブジェクトから以下の様な内容が参照できます。
$file_info->getClientOriginalName() アップロードしたファイル名
$file_info->getClientOriginalExtension() アップロードしたファイルの拡張子
$file_info->getMimeType() アップロードしたファイルMIMEタイプ(例:image/jpeg)
$file_info->getSize() アップロードしたファイルサイズ(byte)
$file_info->getPathname() アップロードしたファイルのテンポラリーパス
$file_info->getError() エラーコード(正常 = 0)
拡張子やファイルサイズ等も参照できるので、バリデーションも詳細に設定が可能です。
さて肝心のアップロードですがお手軽なのは以下の3種類となります。
① $file_info->store($path);
② $file_info->storeAs($path, $name);
③ $file_info->move($full_path, 'hoge.jpg');
① デフォルトディスクに保存(何も設定をしていなければ「~\storage\app\private」となる)
引数はファイル名ではなく保存場所(もっと深い場所に保存したい場合)です。
ファイル名はまさかの自動命名されます。
② 名前を自由に決めたい場合はこちらを使います。
③ 「storage」ディレクトリ外で自由なパスに保存できます。
[disk]指定で明示的に保存場所を指定

「$file_info->store($path)」の指定だとデフォルトディスクへ保存となりイマイチ何処に保存されるか視認性が悪い。
なので同じ[storage]ディレクトリへ保存するなら、「Storage」クラスの方が便利です。
例えば以下の様に記述できます。
    Storage::disk('local')->putFileAs('hoge', $request->file('file'), 'hoge.jpg');
これは「~\storage\app\private\hoge\hoge.jpg」へ保存する事を意味します。

○ ついでにZIP化
任意のコントローラ

public function upload(Request $request) {
    if ($request->method() == 'GET') {
        return view('hoge/upload', []);
    } elseif($request->method() == 'POST') {
        // バリデーション
        $request->validate([
            'file' => 'required|max:2048',
        ]);
        $file_info = $request->file('file');
        $file_name = 'hoge.jpg';
        // 保存
        $file_info->move(resource_path(), $file_name);
        // ZIPパス(ファイル名付き)作成
        $zipPath = resource_path() . '/hoge.zip';
        // クラス初期化
        $zip = new \ZipArchive();
        if ($zip->open($zipPath, \ZipArchive::CREATE) === TRUE) {
            $zip->addFile(resource_path() . '/' . $file_name, $file_name);
            $zip->close();
        }
    }
}

CSV出力
○ CSVファイルを作成してディレクトリへ保存する
任意のコントローラ

use Illuminate\Support\Facades\Storage;
~ 省略 ~
    public function index(Request $request) {
        $datas = [];
        $datas[] = ['hoge' => 'ほげ1', 'foo' => 'ふ~1', 'bar' => 'ばぁ1'];
        $datas[] = ['hoge' => 'ほげ2', 'foo' => 'ふ~2', 'bar' => 'ばぁ2'];
        $datas[] = ['hoge' => 'ほげ3', 'foo' => 'ふ~3', 'bar' => 'ばぁ3'];
        $file_name = '/hoge.csv';
        $path = Storage::disk('local')->path('csv');
        $fp = fopen($path . $file_name, 'w');
        foreach ($datas as $data) {
            $line = implode(',', $this->addDoubleQuote($data));
            $line = mb_convert_encoding($line, "SJIS-win", "UTF-8");
            fwrite($fp, $line . "\n");
        }
        fclose($fp);
    }
    // 値を「"」で囲う
    private function addDoubleQuote($arr = []) {
        $quoted = array_map(function($value) {
            return '"' . $value . '"';
        }, $arr);
        return $quoted;
    }

超簡単かつLaravelの機能はパスの設定くらいしか使ってないです。
○ CSVファイルを作成してダウンロードする
任意のコントローラ

public function index(Request $request) {
    $datas = [];
    $datas[] = ['hoge' => 'ほげ1', 'foo' => 'ふ~1', 'bar' => 'ばぁ1'];
    $datas[] = ['hoge' => 'ほげ2', 'foo' => 'ふ~2', 'bar' => 'ばぁ2'];
    $datas[] = ['hoge' => 'ほげ3', 'foo' => 'ふ~3', 'bar' => 'ばぁ3'];
    $file_name = 'hoge.csv';
    $handle = fopen('php://output', 'w');
    // UTF-8からShift-JIS変換(日本語対応)
    stream_filter_prepend($handle, 'convert.iconv.utf-8/cp932//TRANSLIT');
    foreach ($datas as $data) {
        fputcsv($handle, $data);
    }
    fclose($handle);
    return response()->streamDownload(function () {
        }, $file_name, [
            'Content-Type' => 'application/octet-stream',
        ]
    );
}

こちらは便利ですが問題があり『fputcsv』で出力すると『"』がエスケープされて『"""』となってします。 なので、この方法はお勧めできない。。。
レンズモード 【新規購入限定用】
ログインしてコメントを残そう!!


きっぷる
きっぷる