簡介 (Introduction)
Laravel 提供了強大的檔案系統抽象,感謝 Frank de Jonge 的出色 Flysystem PHP 套件。Laravel Flysystem 整合提供了簡單的驅動程式來處理本地檔案系統、SFTP 和 Amazon S3。更好的是,在本地開發機器和生產伺服器之間切換這些儲存選項非常簡單,因為每個系統的 API 保持一致。
設定 (Configuration)
Laravel 的檔案系統設定檔位於 config/filesystems.php。在此檔案中,你可以設定所有檔案系統「磁碟」。每個磁碟代表一個特定的儲存驅動程式和儲存位置。設定檔中包含了每個支援的驅動程式的範例設定,因此你可以修改設定以反映你的儲存喜好和憑證。
local 驅動程式與儲存在執行 Laravel 應用程式的伺服器上的檔案互動,而 sftp 儲存驅動程式用於基於 SSH 鍵的 FTP。s3 驅動程式用於寫入 Amazon 的 S3 雲端儲存服務。
[!NOTE] 你可以設定任意數量的磁碟,甚至可以有多個使用相同驅動程式的磁碟。
Local 驅動程式 (The Local Driver)
當使用 local 驅動程式時,所有檔案操作都是相對於你的 filesystems 設定檔中定義的 root 目錄。預設情況下,此值設定為 storage/app/private 目錄。因此,以下方法將寫入 storage/app/private/example.txt:
use Illuminate\Support\Facades\Storage;
Storage::disk('local')->put('example.txt', 'Contents');
Public 磁碟 (The Public Disk)
應用程式的 filesystems 設定檔中包含的 public 磁碟用於將公開可存取的檔案。預設情況下,public 磁碟使用 local 驅動程式並將其檔案儲存在 storage/app/public 中。
如果你的 public 磁碟使用 local 驅動程式並且你想讓這些檔案從 Web 可存取,你應該從來源目錄 storage/app/public 到目標目錄 public/storage 建立一個符號連結:
要建立符號連結,你可以使用 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'),
],
storage:unlink 指令可用於銀毀你設定的符號連結:
php artisan storage:unlink
驅動程式先決條件 (Driver Prerequisites)
S3 驅動程式設定 (S3 Driver Configuration)
在使用 S3 驅動程式之前,你需要透過 Composer 套件管理器安裝 Flysystem S3 套件:
composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies
S3 磁碟設定陣列位於你的 config/filesystems.php 設定檔中。通常,你應該使用以下環境變數來設定你的 S3 資訊和憑證,這些環境變數由 config/filesystems.php 設定檔引用:
AWS_ACCESS_KEY_ID=<your-key-id>
AWS_SECRET_ACCESS_KEY=<your-secret-access-key>
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=<your-bucket-name>
AWS_USE_PATH_STYLE_ENDPOINT=false
為了方便起見,這些環境變數與 AWS CLI 使用的命名慣例相匹配。
FTP 驅動程式設定 (Ftp Driver Configuration)
在使用 FTP 驅動程式之前,你需要透過 Composer 套件管理器安裝 Flysystem FTP 套件:
composer require league/flysystem-ftp "^3.0"
Laravel 的 Flysystem 整合與 FTP 配合得很好;但是,框架的預設 config/filesystems.php 設定檔中不包含範例設定。如果你需要設定 FTP 檔案系統,你可以使用以下設定範例:
'ftp' => [
'driver' => 'ftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USERNAME'),
'password' => env('FTP_PASSWORD'),
// Optional FTP Settings...
// 'port' => env('FTP_PORT', 21),
// 'root' => env('FTP_ROOT'),
// 'passive' => true,
// 'ssl' => true,
// 'timeout' => 30,
],
SFTP 驅動程式設定 (Sftp Driver Configuration)
在使用 SFTP 驅動程式之前,你需要透過 Composer 套件管理器安裝 Flysystem SFTP 套件:
composer require league/flysystem-sftp-v3 "^3.0"
Laravel 的 Flysystem 整合與 SFTP 配合得很好;但是,框架的預設 config/filesystems.php 設定檔中不包含範例設定。如果你需要設定 SFTP 檔案系統,你可以使用以下設定範例:
'sftp' => [
'driver' => 'sftp',
'host' => env('SFTP_HOST'),
// Settings for basic authentication...
'username' => env('SFTP_USERNAME'),
'password' => env('SFTP_PASSWORD'),
// Settings for SSH key-based authentication with encryption password...
'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
// Optional SFTP Settings...
// 'hostFingerprint' => env('SFTP_HOST_FINGERPRINT'),
// 'maxTries' => 4,
// 'passphrase' => env('SFTP_PASSPHRASE'),
// 'port' => env('SFTP_PORT', 22),
// 'root' => env('SFTP_ROOT', ''),
// 'timeout' => 30,
// 'useAgent' => true,
],
作用域和唯讀檔案系統 (Scoped and Read-Only Filesystems)
作用域磁碟允許你定義一個檔案系統,其中所有路徑都會自動以給定的路徑前綴為前綴。在建立作用域檔案系統磁碟之前,你需要透過 Composer 套件管理器安裝額外的 Flysystem 套件:
composer require league/flysystem-path-prefixing "^3.0"
你可以透過定義使用 scoped 驅動程式的磁碟來建立任何現有檔案系統磁碟的路徑作用域實例。例如,你可以建立一個磁碟,將你現有的 s3 磁碟的作用域限定到特定的路徑前綴,然後使用作用域磁碟的每個檔案操作都將使用指定的前綴:
's3-videos' => [
'driver' => 'scoped',
'disk' => 's3',
'prefix' => 'path/to/videos',
],
「唯讀」磁碟允許你建立不允許寫入操作的檔案系統磁碟。在使用 read-only 設定選項之前,你需要透過 Composer 套件管理器安裝額外的 Flysystem 套件:
composer require league/flysystem-read-only "^3.0"
接下來,你可以在一個或多個磁碟的設定陣列中包含 read-only 設定選項:
's3-videos' => [
'driver' => 's3',
// ...
'read-only' => true,
],
Amazon S3 相容檔案系統 (Amazon S3 Compatible Filesystems)
預設情況下,你的應用程式的 filesystems 設定檔包含 s3 磁碟的磁碟設定。除了使用此磁碟與 Amazon S3 互動外,你還可以使用它與任何 S3 相容檔案儲存服務互動,例如 MinIO、DigitalOcean Spaces、Vultr Object Storage、Cloudflare R2 或 Hetzner Cloud Storage。
通常,在更新磁碟的憑證以匹配你計劃使用的服務的憑證後,你只需要更新 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 時,如果
endpoint無法被客戶端存取,透過temporaryUrl方法產生臨時儲存 URL 可能無法工作。
取得磁碟實例 (Obtaining Disk Instances)
Storage facade 可用於與你的任何設定磁碟互動。例如,你可以在 facade 上使用 put 方法將頭像儲存到預設磁碟。如果你在 Storage facade 上呼叫方法而不先呼叫 disk 方法,該方法將自動傳遞給預設磁碟:
use Illuminate\Support\Facades\Storage;
Storage::put('avatars/1', $content);
如果你的應用程式與多個磁碟互動,你可以在 Storage facade 上使用 disk 方法來處理特定磁碟上的檔案:
Storage::disk('s3')->put('avatars/1', $content);
隨選磁碟 (On-Demand Disks)
有時你可能希望在執行時期使用給定的設定建立磁碟,而不需要該設定實際存在於你的應用程式的 filesystems 設定檔中。要完成此操作,你可以將設定陣列傳遞給 Storage facade 的 build 方法:
use Illuminate\Support\Facades\Storage;
$disk = Storage::build([
'driver' => 'local',
'root' => '/path/to/root',
]);
$disk->put('image.jpg', $content);
檢索檔案 (Retrieving Files)
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')) {
// ...
}
下載檔案 (Downloading Files)
download 方法可用於產生強制使用者瀏覽器下載給定路徑檔案的回應。download 方法接受檔案名稱作為方法的第二個參數,這將決定下載檔案的使用者看到的檔案名稱。最後,你可以將 HTTP 標頭陣列作為方法的第三個參數傳遞:
return Storage::download('file.jpg');
return Storage::download('file.jpg', $name, $headers);
檔案 URL (File URLs)
你可以使用 url 方法來取得給定檔案的 URL。如果你使用 local 驅動程式,這通常只會在給定路徑前面加上 /storage 並返回檔案的相對 URL。如果你使用 s3 驅動程式,將返回完全限定的遠端 URL:
use Illuminate\Support\Facades\Storage;
$url = Storage::url('file.jpg');
使用 local 驅動程式時,所有應該公開可存取的檔案都應該放在 storage/app/public 目錄中。此外,你應該在 public/storage 建立符號連結,指向 storage/app/public 目錄。
[!WARNING] 使用
local驅動程式時,url的返回值不是 URL 編碼的。因此,我們建議始終使用會建立有效 URL 的名稱來儲存檔案。
URL 主機自訂 (Url Host Customization)
如果你想修改使用 Storage facade 產生的 URL 的主機,你可以在磁碟的設定陣列中新增或更改 url 選項:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'throw' => false,
],
臨時 URL (Temporary URLs)
使用 temporaryUrl 方法,你可以為使用 local 和 s3 驅動程式儲存的檔案建立臨時 URL。此方法接受路徑和 DateTime 實例,指定 URL 應該何時過期:
use Illuminate\Support\Facades\Storage;
$url = Storage::temporaryUrl(
'file.jpg', now()->addMinutes(5)
);
啟用本地臨時 URL (Enabling Local Temporary Urls)
如果你在 local 驅動程式引入臨時 URL 支援之前就開始開發應用程式,你可能需要啟用本地臨時 URL。要這樣做,請在 config/filesystems.php 設定檔中將 serve 選項新增到你的 local 磁碟的設定陣列:
'local' => [
'driver' => 'local',
'root' => storage_path('app/private'),
'serve' => true, // [tl! add]
'throw' => false,
],
S3 請求參數 (S3 Request Parameters)
如果你需要指定額外的 S3 請求參數,你可以將請求參數陣列作為第三個參數傳遞給 temporaryUrl 方法:
$url = Storage::temporaryUrl(
'file.jpg',
now()->addMinutes(5),
[
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename=file2.jpg',
]
);
自訂臨時 URL (Customizing Temporary Urls)
如果你需要自訂特定儲存磁碟的臨時 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
{
/**
* Bootstrap any application services.
*/
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 (Temporary Upload Urls)
[!WARNING] 產生臨時上傳 URL 的能力僅由
s3驅動程式支援。
如果你需要產生一個可用於從客戶端應用程式直接上傳檔案的臨時 URL,你可以使用 temporaryUploadUrl 方法。此方法接受路徑和 DateTime 實例,指定 URL 應該何時過期。temporaryUploadUrl 方法返回一個關聯陣列,可以解構為上傳 URL 和應與上傳請求一起包含的標頭:
use Illuminate\Support\Facades\Storage;
['url' => $url, 'headers' => $headers] = Storage::temporaryUploadUrl(
'file.jpg', now()->addMinutes(5)
);
此方法主要用於無伺服器環境,需要客戶端應用程式直接上傳檔案到雲端儲存系統(如 Amazon S3)。
檔案元資料 (File Metadata)
除了讀取和寫入檔案外,Laravel 還可以提供有關檔案本身的資訊。例如,size 方法可用於取得檔案的大小(以位元組為單位):
use Illuminate\Support\Facades\Storage;
$size = Storage::size('file.jpg');
lastModified 方法返回檔案上次修改時間的 UNIX 時間戳:
$time = Storage::lastModified('file.jpg');
可以透過 mimeType 方法取得給定檔案的 MIME 類型:
$mime = Storage::mimeType('file.jpg');
檔案路徑 (File Paths)
你可以使用 path 方法來取得給定檔案的路徑。如果你使用 local 驅動程式,這將返回檔案的絕對路徑。如果你使用 s3 驅動程式,此方法將返回 S3 儲存桶中檔案的相對路徑:
use Illuminate\Support\Facades\Storage;
$path = Storage::path('file.jpg');
儲存檔案 (Storing Files)
put 方法可用於將檔案內容儲存到磁碟。你也可以將 PHP resource 傳遞給 put 方法,它將使用 Flysystem 的底層串流支援。請記住,所有檔案路徑都應相對於為磁碟設定的「根」位置指定:
use Illuminate\Support\Facades\Storage;
Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);
寫入失敗 (Failed Writes)
如果 put 方法(或其他「寫入」操作)無法將檔案寫入磁碟,將返回 false:
if (! Storage::put('file.jpg', $contents)) {
// The file could not be written to disk...
}
如果你願意,你可以在檔案系統磁碟的設定陣列中定義 throw 選項。當此選項定義為 true 時,「寫入」方法(如 put)將在寫入操作失敗時拋出 League\Flysystem\UnableToWriteFile 實例:
'public' => [
'driver' => 'local',
// ...
'throw' => true,
],
在檔案前面和後面新增內容 (Prepending and Appending To Files)
prepend 和 append 方法允許你寫入檔案的開頭或結尾:
Storage::prepend('file.log', 'Prepended Text');
Storage::append('file.log', 'Appended Text');
複製和移動檔案 (Copying and Moving Files)
copy 方法可用於將現有檔案複製到磁碟上的新位置,而 move 方法可用於重新命名或將現有檔案移動到新位置:
Storage::copy('old/file.jpg', 'new/file.jpg');
Storage::move('old/file.jpg', 'new/file.jpg');
自動串流 (Automatic Streaming)
將檔案串流到儲存可顯著減少記憶體使用。如果你希望 Laravel 自動管理將給定檔案串流到你的儲存位置,你可以使用 putFile 或 putFileAs 方法。此方法接受 Illuminate\Http\File 或 Illuminate\Http\UploadedFile 實例,並將自動將檔案串流到你所需的位置:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// Automatically generate a unique ID for filename...
$path = Storage::putFile('photos', new File('/path/to/photo'));
// Manually specify a filename...
$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
關於 putFile 方法有幾個重要的事項要注意。請注意,我們只指定了目錄名稱,而不是檔案名稱。預設情況下,putFile 方法將產生一個唯一 ID 作為檔案名稱。檔案的擴展名將透過檢查檔案的 MIME 類型來確定。檔案的路徑將由 putFile 方法返回,因此你可以將路徑(包括產生的檔案名稱)儲存在資料庫中。
putFile 和 putFileAs 方法也接受一個參數來指定儲存檔案的「可見性」。如果你將檔案儲存在雲端磁碟(如 Amazon S3)上,並希望檔案透過產生的 URL 公開可存取,這特別有用:
Storage::putFile('photos', new File('/path/to/photo'), 'public');
File Uploads (File Uploads)
In web applications, one of the most common use-cases for storing files is storing user uploaded files such as photos and documents. Laravel makes it very easy to store uploaded files using the store method on an uploaded file instance. Call the store method with the path at which you wish to store the uploaded file:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserAvatarController extends Controller
{
/**
* Update the avatar for the user.
*/
public function update(Request $request): string
{
$path = $request->file('avatar')->store('avatars');
return $path;
}
}
There are a few important things to note about this example. Note that we only specified a directory name, not a filename. By default, the store method will generate a unique ID to serve as the filename. The file's extension will be determined by examining the file's MIME type. The path to the file will be returned by the store method so you can store the path, including the generated filename, in your database.
You may also call the putFile method on the Storage facade to perform the same file storage operation as the example above:
$path = Storage::putFile('avatars', $request->file('avatar'));
Specifying a File Name
If you do not want a filename to be automatically assigned to your stored file, you may use the storeAs method, which receives the path, the filename, and the (optional) disk as its arguments:
$path = $request->file('avatar')->storeAs(
'avatars', $request->user()->id
);
You may also use the putFileAs method on the Storage facade, which will perform the same file storage operation as the example above:
$path = Storage::putFileAs(
'avatars', $request->file('avatar'), $request->user()->id
);
[!WARNING] Unprintable and invalid unicode characters will automatically be removed from file paths. Therefore, you may wish to sanitize your file paths before passing them to Laravel's file storage methods. File paths are normalized using the
League\Flysystem\WhitespacePathNormalizer::normalizePathmethod.
Specifying a Disk
By default, this uploaded file's store method will use your default disk. If you would like to specify another disk, pass the disk name as the second argument to the store method:
$path = $request->file('avatar')->store(
'avatars/'.$request->user()->id, 's3'
);
If you are using the storeAs method, you may pass the disk name as the third argument to the method:
$path = $request->file('avatar')->storeAs(
'avatars',
$request->user()->id,
's3'
);
Other Uploaded File Information
If you would like to get the original name and extension of the uploaded file, you may do so using the getClientOriginalName and getClientOriginalExtension methods:
$file = $request->file('avatar');
$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
However, keep in mind that the getClientOriginalName and getClientOriginalExtension methods are considered unsafe, as the file name and extension may be tampered with by a malicious user. For this reason, you should typically prefer the hashName and extension methods to get a name and an extension for the given file upload:
$file = $request->file('avatar');
$name = $file->hashName(); // Generate a unique, random name...
$extension = $file->extension(); // Determine the file's extension based on the file's MIME type...
檔案可見性 (File Visibility)
在 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 Files And Visibility)
當使用 local 驅動程式時,public 可見性轉換為目錄的 0755 權限和檔案的 0644 權限。你可以在應用程式的 filesystems 設定檔中修改權限映射:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'permissions' => [
'file' => [
'public' => 0644,
'private' => 0600,
],
'dir' => [
'public' => 0755,
'private' => 0700,
],
],
'throw' => false,
],
刪除檔案 (Deleting Files)
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');
目錄 (Directories)
取得目錄中的所有檔案 (Get All Files Within A Directory)
files 方法返回給定目錄中所有檔案的陣列。如果你想檢索給定目錄中的所有檔案(包括子目錄),你可以使用 allFiles 方法:
use Illuminate\Support\Facades\Storage;
$files = Storage::files($directory);
$files = Storage::allFiles($directory);
取得目錄中的所有子目錄 (Get All Directories Within A Directory)
directories 方法返回給定目錄中所有目錄的陣列。如果你想檢索給定目錄中的所有目錄(包括子目錄),你可以使用 allDirectories 方法:
$directories = Storage::directories($directory);
$directories = Storage::allDirectories($directory);
建立目錄 (Create A Directory)
makeDirectory 方法將建立給定的目錄,包括任何需要的子目錄:
Storage::makeDirectory($directory);
刪除目錄 (Delete A Directory)
最後,deleteDirectory 方法可用於刪除目錄及其所有檔案:
Storage::deleteDirectory($directory);
測試 (Testing)
Storage facade 的 fake 方法允許你輕鬆產生一個僽磁碟,結合 Illuminate\Http\UploadedFile 類別的檔案產生工具,大大簡化了檔案上傳的測試。例如:
<?php
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
test('albums can be uploaded', function () {
Storage::fake('photos');
$response = $this->json('POST', '/photos', [
UploadedFile::fake()->image('photo1.jpg'),
UploadedFile::fake()->image('photo2.jpg')
]);
// Assert one or more files were stored...
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
// Assert one or more files were not stored...
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
// Assert that the number of files in a given directory matches the expected count...
Storage::disk('photos')->assertCount('/wallpapers', 2);
// Assert that a given directory is empty...
Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
});
<?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')
]);
// Assert one or more files were stored...
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
// Assert one or more files were not stored...
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
// Assert that the number of files in a given directory matches the expected count...
Storage::disk('photos')->assertCount('/wallpapers', 2);
// Assert that a given directory is empty...
Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
}
}
預設情況下,fake 方法將刪除其臨時目錄中的所有檔案。如果你想保留這些檔案,你可以使用「persistentFake」方法。有關測試檔案上傳的更多資訊,你可以查閱 HTTP 測試文件中有關檔案上傳的資訊。
[!WARNING] >
image方法需要 GD 擴展。
自訂檔案系統 (Custom Filesystems)
Laravel 的 Flysystem 整合提供了幾個開箱即用的「驅動程式」支援;但是,Flysystem 不僅限於這些,它還有許多其他儲存系統的適配器。如果你想在 Laravel 應用程式中使用這些額外的適配器之一,你可以建立自訂驅動程式。
為了定義自訂檔案系統,你需要一個 Flysystem 適配器。讓我們將社群維護的 Dropbox 適配器新增到我們的專案:
composer require spatie/flysystem-dropbox
接下來,你可以在應用程式的其中一個服務提供者的 boot 方法中註冊驅動程式。要完成此操作,你應該使用 Storage facade 的 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
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
/**
* Bootstrap any application services.
*/
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 方法的第一個參數是驅動程式的名稱,第二個是接收 $app 和 $config 變數的閉包。閉包必須返回 Illuminate\Filesystem\FilesystemAdapter 的實例。$config 變數包含在 config/filesystems.php 中為指定磁碟定義的值。
一旦你建立並註冊了擴展的服務提供者,你就可以在 config/filesystems.php 設定檔中使用 dropbox 驅動程式。