Laravel 8.x ファイルストレージ

イントロダクション

Laravelは、Frankde Jongeによる素晴らしいFlysystem PHPパッケージのおかげで、ファイルシステムの強力な抽象化を提供しています。Laravel Flysystem統合は、ローカルファイルシステム、SFTP、およびAmazonS3を操作するためのシンプルなドライバを提供します。さらに良いことに、APIは各システムで同じままであるため、ローカル開発マシンと本番サーバの間でこれらのストレージオプションを切り替えるのは驚くほど簡単です。

設定

Laravelのファイルシステム設定ファイルはconfig/filesystems.phpにあります。このファイル内で、すべてのファイルシステム「ディスク」を設定できます。各ディスクは、特定のストレージドライバーとストレージの場所を表します。サポートしている各ドライバーの設定例を設定ファイルに用意しているので、ストレージ設定と資格情報を反映するように設定を変更してください。

localドライバーは、Laravelアプリケーションを実行しているサーバでローカルに保存されているファイルを操作し、s3ドライバーはAmazonのS3クラウドストレージサービスへの書き込みに使用します。

Tip!! 必要な数のディスクを構成でき、同じドライバーを使用する複数のディスクを使用することもできます。

ローカルドライバ

localドライバーを使用する場合、すべてのファイル操作は、filesystems設定ファイルで定義したrootディレクトリからの相対位置です。デフォルトでは、この値はstorage/appディレクトリに設定されています。したがって、次のメソッドはstorage/app/example.txtに書き込みます。

use Illuminate\Support\Facades\Storage;

Storage::disk('local')->put('example.txt', 'Contents');

公開ディスク

アプリケーションのfilesystems設定ファイルに含まれているpublicディスクは、パブリックに公開してアクセスできるようにするファイルを対象としています。デフォルトでは、publicディスクはlocalドライバーを使用し、そのファイルをstorage/app/publicに保存します。

これらのファイルにWebからアクセスできるようにするには、public/storageからstorage/app/publicへのシンボリックリンクを作成する必要があります。このフォルダ規約を利用すると、Envoyerのようなダウンタイムゼロのデプロイメントシステムを使用する場合に、パブリックにアクセス可能なファイルを1つのディレクトリに保持し、デプロイメント間で簡単に共有できます。

シンボリックリンクを作成するには、storage:link Artisanコマンドを使用できます。

php artisan storage:link

ファイルを保存し、シンボリックリンクを作成したら、assetヘルパを使用してファイルへのURLを作成できます。

echo asset('storage/file.txt');

filesystems設定ファイルで追加のシンボリックリンクを設定できます。storage:linkコマンドを実行すると、設定された各リンクが作成されます。

'links' => [
    public_path('storage') => storage_path('app/public'),
    public_path('images') => storage_path('app/images'),
],

ドライバの動作要件

Composerパッケージ

S3やSFTPドライバーを使用するときは、事前にComposerパッケージマネージャーを介して適切なパッケージをインストールする必要があります。

パフォーマンスを向上させるために、メタデータをキャッシュするアダプタを追加インストールすることもできます。

S3ドライバー設定

S3ドライバーの設定情報は、config/filesystems.php設定ファイルにあります。このファイルには、S3ドライバーの設定配列の例が含まれています。この配列は、皆さんのS3設定と認証情報を使用するため自由に変更できます。利便性のため、これらの環境変数はAWS CLIが使用する命名規則と一致させています。

FTPドライバーの設定

LaravelのFlysystem統合はFTPでもうまく機能します。ただし、サンプル設定がフレームワークのデフォルトのfilesystems.php設定ファイルに含まれていません。FTPファイルシステムを設定する必要がある場合は、以下の設定例を参照してください。

'ftp' => [
    'driver' => 'ftp',
    'host' => env('FTP_HOST'),
    'username' => env('FTP_USERNAME'),
    'password' => env('FTP_PASSWORD'),

    // オプションのFTP設定
    // 'port' => env('FTP_PORT', 21),
    // 'root' => env('FTP_ROOT'),
    // 'passive' => true,
    // 'ssl' => true,
    // 'timeout' => 30,
],

SFTPドライバーの設定

LaravelのFlysystem統合はSFTPでも最適に機能します。ただし、サンプル設定がフレームワークのデフォルトのfileSystems.php設定ファイルに含まれていません。SFTPファイルシステムを設定する必要がある場合は、以下の設定例を参照してください。

'sftp' => [
    'driver' => 'sftp',
    'host' => env('SFTP_HOST'),

    // 基本認証の設定
    'username' => env('SFTP_USERNAME'),
    'password' => env('SFTP_PASSWORD'),

    // 暗号化パスワードを使用するSSHキーベースの認証の設定
    'privateKey' => env('SFTP_PRIVATE_KEY'),
    'password' => env('SFTP_PASSWORD'),

    // オプションのSFTP設定
    // 'port' => env('SFTP_PORT', 22),
    // 'root' => env('SFTP_ROOT'),
    // 'timeout' => 30,
],

Amazon S3コンパチファイルシステム

アプリケーションのfilesystems設定ファイルはデフォルトで、s3ディスクのディスク設定を含んでいます。このディスクはAmazon S3の操作に加え、MinIODigitalOcean Spacesなど、S3と互換性のあるファイルストレージサービスの操作にも使用できます。

通常、ディスクの認証情報を使用予定のサービス認証情報へ合わせて更新した後に、url設定オプションの値を更新するだけで済みます。このオプションの値は通常、AWS_ENDPOINT環境変数で定義されています。

'endpoint' => env('AWS_ENDPOINT', 'https://minio:9000'),

キャッシュ

特定のディスクのキャッシュを有効にするには、ディスクの設定オプションにcacheディレクティブを追加します。cacheオプションは、disk名、秒単位のexpire時間、およびキャッシュprefixを含むキャッシュオプションの配列である必要があります。

's3' => [
    'driver' => 's3',

    // その他のディスクオプション

    'cache' => [
        'store' => 'memcached',
        'expire' => 600,
        'prefix' => 'cache-prefix',
    ],
],

ディスクインスタンスの取得

Storageファサードは、設定済みのディスクと対話するために使用できます。たとえば、ファサードでputメソッドを使用して、アバターをデフォルトのディスクに保存できます。最初にdiskメソッドを呼び出さずにStorageファサードのメソッドを呼び出すと、メソッドは自動的にデフォルトのディスクに渡されます。

use Illuminate\Support\Facades\Storage;

Storage::put('avatars/1', $content);

アプリケーションが複数のディスクを操作する場合は、Storageファサードでdiskメソッドを使用し、特定のディスク上のファイルを操作できます。

Storage::disk('s3')->put('avatars/1', $content);

オンデマンドディスク

時には、アプリケーションのfilesystems設定ファイルに実際にその構成が存在しなくても、指定する構成を使用して実行時にディスクを作成したい場合があります。これを実現するため、Storageファサードのbuildメソッドへ設定配列を渡せます。

use Illuminate\Support\Facades\Storage;

$disk = Storage::build([
    'driver' => 'local',
    'root' => '/path/to/root',
]);

$disk->put('image.jpg', $content);

ファイルの取得

getメソッドを使用して、ファイルの内容を取得できます。ファイルの素の文字列の内容は、メソッドによって返されます。すべてのファイルパスは、ディスクの「ルート」の場所を基準にして指定する必要があることに注意してください。

$contents = Storage::get('file.jpg');

existsメソッドを使用して、ファイルがディスクに存在するかどうかを判定できます。

if (Storage::disk('s3')->exists('file.jpg')) {
    // ...
}

missingメソッドを使用して、ファイルがディスク存在していないことを判定できます。

if (Storage::disk('s3')->missing('file.jpg')) {
    // ...
}

ファイルのダウンロード

downloadメソッドを使用して、ユーザーのブラウザに指定したパスでファイルをダウンロードするように強制するレスポンスを生成できます。downloadメソッドは、メソッドの2番目の引数としてファイル名を受け入れます。これにより、ユーザーがファイルをダウンロードするときに表示されるファイル名が決まります。最後に、HTTPヘッダの配列をメソッドの3番目の引数として渡すことができます。

return Storage::download('file.jpg');

return Storage::download('file.jpg', $name, $headers);

ファイルのURL

urlメソッドを使用し、特定のファイルのURLを取得できます。localドライバーを使用している場合、これは通常、指定されたパスの前に/storageを追加し、ファイルへの相対URLを返します。s3ドライバーを使用している場合は、完全修飾リモートURLが返されます。

use Illuminate\Support\Facades\Storage;

$url = Storage::url('file.jpg');

localドライバーを使用する場合、パブリックにアクセス可能である必要があるすべてのファイルは、storage/app/publicディレクトリに配置する必要があります。さらに、storage/app/publicディレクトリを指すpublic/storageシンボリックリンクを作成する必要があります。

Note: localドライバーを使用する場合、urlの戻り値はURLエンコードされません。このため、常に有効なURLを作成する名前を使用してファイルを保存することをお勧めします。

一時的なURL

temporaryUrlメソッドを使用すると、s3ドライバーを使用して保存されたファイルへの一時URLを作成できます。このメソッドは、パスと、URLの有効期限を指定するDateTimeインスタンスを受け入れます。

use Illuminate\Support\Facades\Storage;

$url = Storage::temporaryUrl(
    'file.jpg', now()->addMinutes(5)
);

追加のS3リクエストパラメーターを指定する必要がある場合は、リクエストパラメーターの配列をtemporaryUrlメソッドの引数の3番目として渡すことができます。

$url = Storage::temporaryUrl(
    'file.jpg',
    now()->addMinutes(5),
    [
        'ResponseContentType' => 'application/octet-stream',
        'ResponseContentDisposition' => 'attachment; filename=file2.jpg',
    ]
);

特定するストレージディスクに対する一時的なURLの生成方法をカスタマイズする必要がある場合、 buildTemporaryUrlsUsing メソッドを使用してください。例えば、一時的なURLを通常サポートしていないディスクに保存されているファイルをダウンロードできるコントローラがある場合、これは便利です。通常、このメソッドはサービスプロバイダのbootメソッドから呼び出します。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの初期起動処理
     *
     * @return void
     */
    public function boot()
    {
        Storage::disk('local')->buildTemporaryUrlsUsing(function ($path, $expiration, $options) {
            return URL::temporarySignedRoute(
                'files.download',
                $expiration,
                array_merge($options, ['path' => $path])
            );
        });
    }
}

URLホストのカスタマイズ

Storageファサードを使用して生成するURLのホストを事前に定義したい場合は、ディスクの設定配列にurlオプションを追加できます。

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

ファイルメタデータ

Laravelは、ファイルの読み取りと書き込みに加えて、ファイル自体に関する情報も提供できます。たとえば、sizeメソッドを使用して、ファイルのサイズをバイト単位で取得できます。

use Illuminate\Support\Facades\Storage;

$size = Storage::size('file.jpg');

lastModifiedメソッドは、ファイルが最後に変更されたときのUNIXタイムスタンプを返します。

$time = Storage::lastModified('file.jpg');

ファイルパス

pathメソッドを使用して、特定のファイルのパスを取得できます。localドライバーを使用している場合、これはファイルへの絶対パスを返します。s3ドライバーを使用している場合、このメソッドはS3バケット内のファイルへの相対パスを返します。

use Illuminate\Support\Facades\Storage;

$path = Storage::path('file.jpg');

ファイルの保存

putメソッドは、ファイルの内容をディスクに保存するために使用します。PHPのresourceputメソッドに渡すこともできます。このメソッドは、Flysystemの基盤となるストリームサポートを使用します。すべてのファイルパスは、ディスク用に設定された「ルート」の場所を基準にして指定する必要があることに注意してください。

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents);

Storage::put('file.jpg', $resource);

自動ストリーミング

ファイルをストレージにストリーミングすると、メモリ使用量が大幅に削減されます。Laravelが特定のファイルの保存場所へのストリーミングを自動的に管理するようにしたい場合は、putFileまたはputFileAsメソッドを使用できます。このメソッドは、Illuminate\Http\FileまたはIlluminate\Http\UploadedFileインスタンスのいずれかを受け入れ、ファイルを目的の場所に自動的にストリーミングします。

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// ファイル名の一意のIDを自動的に生成
$path = Storage::putFile('photos', new File('/path/to/photo'));

// ファイル名を手動で指定します
$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

putFileメソッドには注意すべき重要な点がいくつかあります。ファイル名ではなく、ディレクトリ名のみを指定することに注意してください。デフォルトでは、putFileメソッドはファイル名として機能する一意のIDを生成します。ファイルの拡張子は、ファイルのMIMEタイプを調べることによって決定されます。ファイルへのパスはputFileメソッドによって返されるため、生成されたファイル名を含むパスをデータベースに保存できます。

putFileメソッドとputFileAsメソッドは、保存するファイルの「可視性」を指定する引数も取ります。これは、AmazonS3などのクラウドディスクにファイルを保存していて、生成されたURLを介してファイルにパブリックアクセスできるようにする場合に特に便利です。

Storage::putFile('photos', new File('/path/to/photo'), 'public');

ファイルの先頭追加と後方追加

prependおよびappendメソッドを使用すると、ファイルの最初または最後に書き込むことができます。

Storage::prepend('file.log', 'Prepended Text');

Storage::append('file.log', 'Appended Text');

ファイルのコピーと移動

copyメソッドを使用して、既存のファイルをディスク上の新しい場所にコピーできます。また、moveメソッドを使用して、既存のファイルの名前を変更したり、新しい場所に移動したりできます。

Storage::copy('old/file.jpg', 'new/file.jpg');

Storage::move('old/file.jpg', 'new/file.jpg');

ファイルのアップロード

Webアプリケーションでは、ファイルを保存するための最も一般的な使用例の1つは、写真やドキュメントなどのユーザーがアップロードしたファイルを保存することです。Laravelを使用すると、アップロードされたファイルインスタンスにstoreメソッドを使用し、ファイルを非常に簡単に保存できます。アップロード済みファイルを保存するパスを指定してstoreメソッドを呼び出します。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class UserAvatarController extends Controller
{
    /**
     * ユーザーのアバターを更新
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request)
    {
        $path = $request->file('avatar')->store('avatars');

        return $path;
    }
}

この例で注意すべき重要なことがあります。ファイル名ではなく、ディレクトリ名のみを指定したことに注意してください。デフォルトでは、storeメソッドはファイル名として機能する一意のIDを生成します。ファイルの拡張子は、ファイルのMIMEタイプを調べることによって決定されます。ファイルへのパスはstoreメソッドによって返されるため、生成されたファイル名を含むパスをデータベースに保存できます。

StorageファサードでputFileメソッドを呼び出して、上記の例と同じファイルストレージ操作を実行することもできます。

$path = Storage::putFile('avatars', $request->file('avatar'));

ファイル名の指定

保存されたファイルにファイル名を自動的に割り当てたくない場合は、引数としてパス、ファイル名、および(オプションの)ディスクを受け取るstoreAsメソッドを使用します。

$path = $request->file('avatar')->storeAs(
    'avatars', $request->user()->id
);

StorageファサードでputFileAsメソッドを使用することもできます。これにより、上記の例と同じファイルストレージ操作が実行されます。

$path = Storage::putFileAs(
    'avatars', $request->file('avatar'), $request->user()->id
);

Note: 印刷できない無効なUnicode文字はファイルパスから自動的に削除されます。したがって、Laravelのファイルストレージメソッドに渡す前に、ファイルパスをサニタイズすることをお勧めします。ファイルパスは、League\Flysystem\Util::normalizePathメソッドを使用して正規化されます。

ディスクの指定

デフォルトでは、このアップロード済みファイルのstoreメソッドはデフォルトのディスクを使用します。別のディスクを指定する場合は、ディスク名を2番目の引数としてstoreメソッドに渡します。

$path = $request->file('avatar')->store(
    'avatars/'.$request->user()->id, 's3'
);

storeAsメソッドを使用している場合は、ディスク名を3番目の引数としてメソッドに渡すことができます。

$path = $request->file('avatar')->storeAs(
    'avatars',
    $request->user()->id,
    's3'
);

アップロード済みファイルのその他の情報

アップロードされたファイルの元の名前と拡張子を取得したい場合は、getClientOriginalNamegetClientOriginalExtensionメソッドを使って取得します。

$file = $request->file('avatar');

$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();

ただし,悪意のあるユーザーによりファイル名や拡張子が改竄される可能性があるため,getClientOriginalNamegetClientOriginalExtensionメソッドは安全であると考えられないことに注意してください。そのため,アップロードされたファイルの名前と拡張子を取得するには,通常,hashNameメソッドとextensionメソッドを使用するべきです。

$file = $request->file('avatar');

$name = $file->hashName(); // ユニークでランダムな名前を生成する
$extension = $file->extension(); // ファイルのMIMEタイプに基づき拡張子を決める

ファイルの可視性

LaravelのFlysystem統合では、「可視性」は複数のプラットフォームにわたるファイル権限の抽象化です。ファイルはpublicまたはprivateとして宣言できます。ファイルがpublicと宣言されている場合、そのファイルは一般的に他のユーザーがアクセスできる必要があることを示しています。たとえば、S3ドライバーを使用する場合、publicファイルのURLを取得できます。

putメソッドを介してファイルを書き込むとき、可視性を設定できます。

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents, 'public');

ファイルがすでに保存されている場合、その可視性は、getVisibilityおよびsetVisibilityメソッドにより取得および設定できます。

$visibility = Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public');

アップロード済みファイルを操作するときは、storePubliclyメソッドとstorePubliclyAsメソッドを使用して、アップロード済みファイルをpublicの可視性で保存できます。

$path = $request->file('avatar')->storePublicly('avatars', 's3');

$path = $request->file('avatar')->storePubliclyAs(
    'avatars',
    $request->user()->id,
    's3'
);

ローカルファイルと可視性

localドライバーを使用する場合、public可視性は、ディレクトリの0755パーミッションとファイルの0644パーミッションに変換されます。アプリケーションのfilesystems設定ファイルでパーミッションマッピングを変更できます。

'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
    'permissions' => [
        'file' => [
            'public' => 0644,
            'private' => 0600,
        ],
        'dir' => [
            'public' => 0755,
            'private' => 0700,
        ],
    ],
],

ファイルの削除

deleteメソッドは、削除する単一のファイル名またはファイルの配列を受け入れます。

use Illuminate\Support\Facades\Storage;

Storage::delete('file.jpg');

Storage::delete(['file.jpg', 'file2.jpg']);

必要に応じて、ファイルを削除するディスクを指定できます。

use Illuminate\Support\Facades\Storage;

Storage::disk('s3')->delete('path/file.jpg');

ディレクトリ

ディレクトリ内のすべてのファイルを取得

filesメソッドは、指定されたディレクトリ内のすべてのファイルの配列を返します。すべてのサブディレクトリを含む、特定のディレクトリ内のすべてのファイルのリストを取得する場合は、allFilesメソッドを使用できます。

use Illuminate\Support\Facades\Storage;

$files = Storage::files($directory);

$files = Storage::allFiles($directory);

ディレクトリ内のすべてのディレクトリを取得

directoriesメソッドは、指定されたディレクトリ内のすべてのディレクトリの配列を返します。さらに、allDirectoriesメソッドを使用して、特定のディレクトリ内のすべてのディレクトリとそのすべてのサブディレクトリのリストを取得できます。

$directories = Storage::directories($directory);

$directories = Storage::allDirectories($directory);

ディレクトリを作成する

makeDirectoryメソッドは、必要なサブディレクトリを含む、指定したディレクトリを作成します。

Storage::makeDirectory($directory);

ディレクトリを削除する

最後に、deleteDirectoryメソッドを使用して、ディレクトリとそのすべてのファイルを削除できます。

Storage::deleteDirectory($directory);

カスタムファイルシステム

LaravelのFlysystem統合は、最初からすぐに使える「ドライバ」をいくつかサポートしています。ただし、Flysystemはこれらに限定されず、他の多くのストレージシステム用のアダプターを備えています。Laravelアプリケーションでこれらの追加アダプターの1つを使用する場合は、カスタムドライバーを作成できます。

カスタムファイルシステムを定義するには、Flysystemアダプターが必要です。コミュニティが管理するDropboxアダプターをプロジェクトに追加してみましょう。

composer require spatie/flysystem-dropbox

次に、アプリケーションのサービスプロバイダの1つのbootメソッド内にドライバーを登録します。これには、Storageファサードのextendメソッドを使用します。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * 全アプリケーションサービスの初期起動処理
     *
     * @return void
     */
    public function boot()
    {
        Storage::extend('dropbox', function ($app, $config) {
            $client = new DropboxClient(
                $config['authorization_token']
            );

            return new Filesystem(new DropboxAdapter($client));
        });
    }
}

extendメソッドの最初の引数はドライバーの名前であり、2番目の引数は$app変数と$config変数を受け取るクロージャです。クロージャはLeague\Flysystem\Filesystemのインスタンスを返す必要があります。$config変数には、config/filesystems.phpで定義した指定ディスクの値が含まれます。

拡張機能のサービスプロバイダを作成・登録したら、config/filesystems.php設定ファイルでdropboxドライバーを使用できます。

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる