イントロダクション
Laravelは、Frankde Jongeによる素晴らしいFlysystem PHPパッケージのおかげで、ファイルシステムの強力な抽象化を提供しています。Laravel Flysystem統合は、ローカルファイルシステム、SFTP、およびAmazonS3を操作するためのシンプルなドライバを提供します。さらに良いことに、APIは各システムで同じままであるため、ローカル開発マシンと本番サーバの間でこれらのストレージオプションを切り替えるのは驚くほど簡単です。
設定
Laravelのファイルシステム設定ファイルはconfig/filesystems.php
にあります。このファイル内で、すべてのファイルシステム「ディスク」を設定できます。各ディスクは、特定のストレージドライバとストレージの場所を表します。サポートしている各ドライバの設定例を設定ファイルに用意しているので、ストレージ設定と資格情報を反映するように設定を変更してください。
local
ドライバは、Laravelアプリケーションを実行しているサーバでローカルに保存されているファイルを操作し、s3
ドライバはAmazonのS3クラウドストレージサービスへの書き込みに使用します。
Note: 必要な数のディスクを構成でき、同じドライバを使用する複数のディスクを使用することもできます。
ローカルドライバ
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'),
],
ドライバの動作要件
S3ドライバ設定
S3ドライバを使用する前に、Composerパッケージマネージャを使用し、Flysystem S3パッケージをインストールする必要があります。
composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies
S3ドライバの設定情報は、config/filesystems.php
設定ファイルにあります。このファイルには、S3ドライバの設定配列の例が含まれています。この配列は、皆さんのS3設定と認証情報を使用するため自由に変更できます。利便性のため、これらの環境変数はAWS
CLIが使用する命名規則と一致させています。
FTPドライバの設定
FTPドライバを使用する前に、Composerパッケージマネージャを使用し、Flysystem FTPパッケージをインストールする必要があります。
composer require league/flysystem-ftp "^3.0"
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ドライバの設定
SFTPドライバを使用する前に、Composerパッケージマネージャを使用して Flysystem SFTPパッケージをインストールする必要があります。
composer require league/flysystem-sftp-v3 "^3.0"
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'),
'passphrase' => env('SFTP_PASSPHRASE'),
// Settings for file / directory permissions...
'visibility' => 'private', // `private` = 0600, `public` = 0644
'directory_visibility' => 'private', // `private` = 0700, `public` = 0755
// オプションのSFTP設定
// 'hostFingerprint' => env('SFTP_HOST_FINGERPRINT'),
// 'maxTries' => 4,
// 'passphrase' => env('SFTP_PASSPHRASE'),
// 'port' => env('SFTP_PORT', 22),
// 'root' => env('SFTP_ROOT', ''),
// 'timeout' => 30,
// 'useAgent' => true,
],
スコープ付きと読み取り専用ファイルシステム
スコープ付きディスクを使用すると、すべてのパスに自動的に指定したパスプレフィックスが付くファイルシステムを定義できます。スコープ付きファイルシステムディスクを作成する前に、Composerパッケージマネージャを使用して、Flysystemパッケージを追加でインストールする必要があります。
composer require league/flysystem-path-prefixing "^3.0"
scoped
ドライバを利用するディスクを定義し、既存のファイルシステムディスクをパススコープするインスタンスを作成します。例えば、既存のs3
ディスクを特定のパスプレフィックスにスコープするディスクを作成すれば、スコープしたディスクを使用するすべてのファイル操作で、指定したプレフィックスを使用します。
's3-videos' => [
'driver' => 'scoped',
'disk' => 's3',
'prefix' => 'path/to/videos',
],
「読み取り専用(Read-only)」ディスクで、書き込み操作を許可しないファイルシステムディスクを作成できます。read-only
設定オプションを使用する前に、Composerパッケージマネージャ経由で、Flysystemパッケージを追加インストールする必要があります。
composer require league/flysystem-read-only "^3.0"
次に、ディスクの設定配列に、read-only
設定オプションを含めてください。
's3-videos' => [
'driver' => 's3',
// ...
'read-only' => true,
],
Amazon S3コンパチファイルシステム
アプリケーションのfilesystems
設定ファイルはデフォルトで、s3
ディスクのディスク設定を含んでいます。このディスクはAmazon
S3の操作に加え、MinIOやDigitalOcean
Spacesなど、S3と互換性のあるファイルストレージサービスの操作にも使用できます。
通常、ディスクの認証情報を使用予定のサービス認証情報へ合わせて更新した後に、endpoint
設定オプションの値を更新するだけで済みます。このオプションの値は通常、AWS_ENDPOINT
環境変数で定義されています。
'endpoint' => env('AWS_ENDPOINT', 'https://minio:9000'),
MinIO
LaravelのFlysystemインテグレーションでMinIOを使用する際に、適切なURLを生成するには、AWS_URL
環境変数を定義し、アプリケーションのローカルURLと一致させ、URLパスにバケット名を含める必要があります。
AWS_URL=http://localhost:9000/local
Warning!! MinIOを使用する場合、
temporaryUrl
メソッドによる一時保存用URLの生成はサポートしていません。
ディスクインスタンスの取得
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');
取得するファイルがJSONを含んでいる場合、json
メソッドを使用してファイルを取得し、その内容をデコードできます。
$orders = Storage::json('orders.json');
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
にシンボリックリンクを作成する必要があります。
Warning!!
local
ドライバを使用する場合、url
の戻り値はURLエンコードされません。このため、常に有効なURLを作成する名前を使用してファイルを保存することをお勧めします。
URLホストのカスタマイズ
もし、Storage
ファサードを使用して生成する、URLのホストをあらかじめ定義しておきたい場合は、ディスクの設定配列へurl
オプションを追加してください。
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
一時的な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 DateTime;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの初期起動処理
*/
public function boot(): void
{
Storage::disk('local')->buildTemporaryUrlsUsing(
function (string $path, DateTime $expiration, array $options) {
return URL::temporarySignedRoute(
'files.download',
$expiration,
array_merge($options, ['path' => $path])
);
}
);
}
}
一時的なアップロードURL
Warning!! 一時的なアップロードURLの生成機能は、
s3
ドライバのみサポートしています。
クライアントサイドのアプリケーションから、直接ファイルをアップロードするために使用する一時的なURLを生成する必要がある場合は、temporaryUploadUrl
メソッドを使用します。このメソッドには、パスとURLの有効期限を指定するDateTime
インスタンスを指定します。temporaryUploadUrl
メソッドからは、アップロードURLとアップロードリクエストに含めるべきヘッダを連想配列で返します。
use Illuminate\Support\Facades\Storage;
['url' => $url, 'headers' => $headers] = Storage::temporaryUploadUrl(
'file.jpg', now()->addMinutes(5)
);
このメソッドは、主にクライアントサイドのアプリケーションがAmazon S3などのクラウドストレージシステムに直接ファイルをアップロードする必要があるサーバレス環境で役立つでしょう。
ファイルメタデータ
Laravelは、ファイルの読み取りと書き込みに加えて、ファイル自体に関する情報も提供できます。たとえば、size
メソッドを使用して、ファイルのサイズをバイト単位で取得できます。
use Illuminate\Support\Facades\Storage;
$size = Storage::size('file.jpg');
lastModified
メソッドは、ファイルが最後に変更されたときのUNIXタイムスタンプを返します。
$time = Storage::lastModified('file.jpg');
指定ファイルのMIMEタイプは、mimeType
メソッドで取得できます。
$mime = Storage::mimeType('file.jpg')
ファイルパス
path
メソッドを使用して、特定のファイルのパスを取得できます。local
ドライバを使用している場合、これはファイルへの絶対パスを返します。s3
ドライバを使用している場合、このメソッドはS3バケット内のファイルへの相対パスを返します。
use Illuminate\Support\Facades\Storage;
$path = Storage::path('file.jpg');
ファイルの保存
put
メソッドは、ファイルの内容をディスクに保存するために使用します。PHPのresource
をput
メソッドに渡すこともできます。このメソッドは、Flysystemの基盤となるストリームサポートを使用します。すべてのファイルパスは、ディスク用に設定された「ルート」の場所を基準にして指定する必要があることに注意してください。
use Illuminate\Support\Facades\Storage;
Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);
書き込みの失敗
put
メソッド、もしくは他の「書き込み」操作でディスクへファイルを書き込めない場合は、false
が返ります。
if (! Storage::put('file.jpg', $contents)) {
// ファイルがディスクへ書き込めなかった
}
必要であれば、ファイルシステムのディスクの設定配列で、throw
オプションを定義できます。このオプションをtrue
に定義すると、put
のような「書き込み」メソッドの書き込み失敗時に、League\Flysystem\UnableToWriteFile
インスタンスを投げます。
'public' => [
'driver' => 'local',
// ...
'throw' => true,
],
ファイルの前後への追加
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');
自動ストリーミング
ファイルをストレージにストリーミングすると、メモリ使用量が大幅に削減されます。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');
ファイルのアップロード
Webアプリケーションでは、ファイルを保存するための最も一般的な使用例の1つは、写真やドキュメントなどのユーザーがアップロードしたファイルを保存することです。Laravelを使用すると、アップロードされたファイルインスタンスにstore
メソッドを使用し、ファイルを非常に簡単に保存できます。アップロード済みファイルを保存するパスを指定してstore
メソッドを呼び出します。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class UserAvatarController extends Controller
{
/**
* ユーザーのアバターを更新
*/
public function update(Request $request): string
{
$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
);
Warning!! 印刷できない無効なUnicode文字はファイルパスから自動的に削除されます。したがって、Laravelのファイルストレージメソッドに渡す前に、ファイルパスをサニタイズすることをお勧めします。ファイルパスは、
League\Flysystem\WhitespacePathNormalizer::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'
);
アップロード済みファイルのその他の情報
アップロードされたファイルの元の名前と拡張子を取得したい場合は、getClientOriginalName
とgetClientOriginalExtension
メソッドを使って取得します。
$file = $request->file('avatar');
$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
ただし,悪意のあるユーザーによりファイル名や拡張子が改竄される可能性があるため,getClientOriginalName
とgetClientOriginalExtension
メソッドは安全であると考えられないことに注意してください。そのため,アップロードされたファイルの名前と拡張子を取得するには,通常,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);
テスト
Storage
ファサードのfake
メソッドを使うと、簡単に偽のディスクを生成できます。これをIlluminate\Http\UploadedFile
クラスのファイル生成ユーティリティと組み合わせると、ファイルのアップロードのテストが非常に簡単になります。例えば、以下のようにです。
<?php
namespace Tests\Feature;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_albums_can_be_uploaded(): void
{
Storage::fake('photos');
$response = $this->json('POST', '/photos', [
UploadedFile::fake()->image('photo1.jpg'),
UploadedFile::fake()->image('photo2.jpg')
]);
// 1つ以上のファイルが保存されたことをアサート
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
// 1つ以上のファイルが保存されないことをアサート
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
// 指定ディレクトリが空であることをアサート
Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
}
}
fake
メソッドはデフォルトで、テンポラリディレクトリのファイルをすべて削除します。もしこれらのファイルを残しておきたい場合は、代わりに"persistentFake"メソッドを使用してください。ファイルアップロードのテストに関するより詳しい情報は、ファイルアップロードに関するHTTPテストのドキュメントを参照してください。
Warning!!
image
メソッドには、GD拡張が必要です。
カスタムファイルシステム
LaravelのFlysystem統合は、最初からすぐに使える「ドライバ」をいくつかサポートしています。ただし、Flysystemはこれらに限定されず、他の多くのストレージシステム用のアダプターを備えています。Laravelアプリケーションでこれらの追加アダプターの1つを使用する場合は、カスタムドライバを作成できます。
カスタムファイルシステムを定義するには、Flysystemアダプターが必要です。コミュニティが管理するDropboxアダプターをプロジェクトに追加してみましょう。
composer require spatie/flysystem-dropbox
次に、アプリケーションのサービスプロバイダの1つのboot
メソッド内にドライバを登録します。これには、Storage
ファサードのextend
メソッドを使用します。
<?php
namespace App\Providers;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Filesystem\FilesystemAdapter;
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
{
/**
* 全アプリケーションサービスの登録
*/
public function register(): void
{
// ...
}
/**
* 全アプリケーションサービスの初期起動処理
*/
public function boot(): void
{
Storage::extend('dropbox', function (Application $app, array $config) {
$adapter = new DropboxAdapter(new DropboxClient(
$config['authorization_token']
));
return new FilesystemAdapter(
new Filesystem($adapter, $config),
$adapter,
$config
);
});
}
}
extend
メソッドの第1引数はドライバ名前で、第2引数は変数$app
と$config
を受け取るクロージャです。このクロージャはIlluminate\Filesystem\FilesystemAdapter
のインスタンスを返さなければなりません。変数$config
には、指定したディスクのconfig/filesystems.php
で定義している値が格納されます。
拡張機能のサービスプロバイダを作成・登録したら、config/filesystems.php
設定ファイルでdropbox
ドライバを使用できます。