Skip to content

파일 저장소

소개

Laravel은 Frank de Jonge의 멋진 Flysystem PHP 패키지 덕분에 강력한 파일 시스템 추상화를 제공합니다. Laravel Flysystem 통합은 로컬 파일 시스템, SFTP 및 Amazon S3와 함께 작동하는 간단한 드라이버를 제공합니다. 더 좋은 점은 각 시스템에 대해 API가 동일하게 유지되므로 로컬 개발 머신과 프로덕션 서버 간에 이러한 스토리지 옵션을 매우 쉽게 전환할 수 있다는 것입니다.

구성

Laravel의 파일 시스템 구성 파일은 config/filesystems.php에 있습니다. 이 파일 내에서 모든 파일 시스템 "디스크"를 구성할 수 있습니다. 각 디스크는 특정 스토리지 드라이버 및 스토리지 위치를 나타냅니다. 지원되는 각 드라이버에 대한 예제 구성이 구성 파일에 포함되어 있으므로 스토리지 기본 설정 및 자격 증명을 반영하도록 구성을 수정할 수 있습니다.

local 드라이버는 Laravel 애플리케이션을 실행하는 서버에 로컬로 저장된 파일과 상호 작용하고 s3 드라이버는 Amazon의 S3 클라우드 스토리지 서비스에 기록하는 데 사용됩니다.

lightbulb

원하는 만큼 많은 디스크를 구성할 수 있으며 동일한 드라이버를 사용하는 여러 디스크를 가질 수도 있습니다.

로컬 드라이버

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에 저장합니다.

웹에서 이러한 파일에 액세스할 수 있도록 소스 디렉토리 storage/app/public에서 대상 디렉토리 public/storage로 심볼릭 링크를 만들어야 합니다. 이러한 폴더 규칙을 활용하면 Envoyer와 같은 제로 다운타임 배포 시스템을 사용할 때 배포 전체에서 쉽게 공유할 수 있는 하나의 디렉토리에 공개적으로 액세스할 수 있는 파일을 유지할 수 있습니다.

심볼릭 링크를 만들려면 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

드라이버 사전 요구 사항

S3 드라이버 구성

S3 드라이버를 사용하기 전에 Composer 패키지 관리자를 통해 Flysystem S3 패키지를 설치해야 합니다:

composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies

S3 디스크 구성 배열은 config/filesystems.php 설정 파일에 있습니다. 일반적으로 config/filesystems.php 설정 파일에서 참조하는 다음 환경 변수를 사용하여 S3 정보와 자격 증명을 구성해야 합니다:

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 드라이버를 사용하기 전에 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 드라이버를 사용하기 전에 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,
],

범위가 지정된 읽기 전용 파일 시스템

범위가 지정된 디스크를 사용하면 모든 경로에 지정된 경로 접두사가 자동으로 추가되는 파일 시스템을 정의할 수 있습니다. 범위가 지정된 파일 시스템 디스크를 만들기 전에 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 호환 파일 시스템

기본적으로 애플리케이션의 filesystems 구성 파일에는 s3 디스크에 대한 디스크 구성이 포함되어 있습니다. 이 디스크를 Amazon S3와 상호 작용하는 데 사용하는 것 외에도 MinIO 또는 DigitalOcean Spaces와 같은 S3 호환 파일 스토리지 서비스와 상호 작용하는 데 사용할 수 있습니다.

일반적으로 사용하려는 서비스의 자격 증명과 일치하도록 디스크의 자격 증명을 업데이트한 후에는 endpoint 구성 옵션의 값만 업데이트하면 됩니다. 이 옵션의 값은 일반적으로 AWS_ENDPOINT 환경 변수를 통해 정의됩니다:

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

MinIO

Laravel의 Flysystem 통합이 MinIO를 사용할 때 적절한 URL을 생성하려면, 애플리케이션의 로컬 URL과 일치하고 URL 경로에 버킷 이름을 포함하도록 AWS_URL 환경 변수를 정의해야 합니다:

AWS_URL=http://localhost:9000/local
exclamation

temporaryUrl 메서드를 통해 임시 저장소 URL을 생성하는 것은 endpoint를 클라이언트에서 접근할 수 없는 경우 MinIO를 사용할 때 작동하지 않을 수 있습니다.

디스크 인스턴스 얻기

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 메서드는 메서드의 두 번째 인수로 파일 이름을 받으며, 이 파일 이름은 파일을 다운로드하는 사용자에게 보이는 파일 이름을 결정합니다. 마지막으로 메서드의 세 번째 인수로 HTTP 헤더 배열을 전달할 수 있습니다.

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심볼릭 링크를 생성해야 합니다.

exclamation

local 드라이버를 사용하는 경우 url의 반환 값은 URL 인코딩되지 않습니다. 따라서 유효한 URL을 생성하는 이름을 사용하여 파일을 항상 저장하는 것이 좋습니다.

URL 호스트 사용자 정의

Storage 파사드를 사용하여 생성된 URL의 호스트를 수정하려면 디스크의 구성 배열에서 url 옵션을 추가하거나 변경할 수 있습니다.

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

임시 URL

temporaryUrl 메서드를 사용하면 locals3 드라이버를 사용하여 저장된 파일에 대한 임시 URL을 만들 수 있습니다. 이 메서드는 경로와 URL 만료 시간을 지정하는 DateTime 인스턴스를 받습니다.

use Illuminate\Support\Facades\Storage;
 
$url = Storage::temporaryUrl(
'file.jpg', now()->addMinutes(5)
);

로컬 임시 URL 활성화

임시 URL 지원이 local 드라이버에 도입되기 전에 애플리케이션 개발을 시작한 경우 로컬 임시 URL을 활성화해야 할 수 있습니다. 이렇게 하려면 config/filesystems.php 구성 파일 내에서 local 디스크의 구성 배열에 serve 옵션을 추가하십시오.

'local' => [
'driver' => 'local',
'root' => storage_path('app/private'),
'serve' => true,
'throw' => false,
],

S3 요청 매개변수

추가적인 S3 요청 매개변수를 지정해야 하는 경우, temporaryUrl 메서드의 세 번째 인수로 요청 매개변수 배열을 전달할 수 있습니다:

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

임시 URL 사용자 정의

특정 스토리지 디스크에 대한 임시 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

exclamation

임시 업로드 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 메서드를 사용하여 디스크에 파일 내용을 저장할 수 있습니다. Flysystem의 기본 스트림 지원을 사용하는 put 메서드에 PHP resource를 전달할 수도 있습니다. 모든 파일 경로는 디스크에 구성된 "루트" 위치를 기준으로 지정해야 합니다:

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,
],

파일 앞에 추가 및 파일 뒤에 추가

prependappend 메서드를 사용하면 파일의 시작 부분이나 끝 부분에 쓸 수 있습니다:

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 메서드에서 반환됩니다.

putFileputFileAs 메서드는 저장된 파일의 "가시성"을 지정하는 인수를 허용합니다. 이는 Amazon S3와 같은 클라우드 디스크에 파일을 저장하고 생성된 URL을 통해 파일에 공개적으로 액세스할 수 있도록 하려는 경우에 특히 유용합니다:

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

파일 업로드

웹 애플리케이션에서 파일을 저장하는 가장 일반적인 사용 사례 중 하나는 사진 및 문서와 같은 사용자가 업로드한 파일을 저장하는 것입니다. 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
);
exclamation

인쇄할 수 없는 문자와 유효하지 않은 유니코드 문자는 파일 경로에서 자동으로 제거됩니다. 따라서 Laravel의 파일 저장 메서드에 전달하기 전에 파일 경로를 정리하는 것이 좋습니다. 파일 경로는 League\Flysystem\WhitespacePathNormalizer::normalizePath 메서드를 사용하여 정규화됩니다.

디스크 지정

기본적으로 업로드된 파일의 store 메서드는 기본 디스크를 사용합니다. 다른 디스크를 지정하려면 store 메서드의 두 번째 인수로 디스크 이름을 전달합니다:

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

storeAs 메서드를 사용하는 경우 메서드의 세 번째 인수로 디스크 이름을 전달할 수 있습니다:

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

기타 업로드된 파일 정보

업로드된 파일의 원래 이름과 확장자를 가져오려면 getClientOriginalNamegetClientOriginalExtension 메서드를 사용하여 가져올 수 있습니다:

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

그러나 파일 이름과 확장자는 악의적인 사용자가 조작할 수 있으므로 getClientOriginalNamegetClientOriginalExtension 메서드는 안전하지 않은 것으로 간주됩니다. 이러한 이유로 일반적으로 hashNameextension 메서드를 사용하여 주어진 파일 업로드에 대한 이름과 확장을 가져오는 것이 좋습니다:

$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');

파일이 이미 저장된 경우 getVisibilitysetVisibility 메서드를 통해 해당 가시성을 검색하고 설정할 수 있습니다:

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

업로드된 파일과 상호 작용할 때 storePubliclystorePubliclyAs 메서드를 사용하여 업로드된 파일을 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,
],
],
'throw' => false,
],

파일 삭제

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
 
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
 
test('앨범을 업로드할 수 있습니다', function () {
Storage::fake('photos');
 
$response = $this->json('POST', '/photos', [
UploadedFile::fake()->image('photo1.jpg'),
UploadedFile::fake()->image('photo2.jpg')
]);
 
// 하나 이상의 파일이 저장되었는지 확인합니다...
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
 
// 하나 이상의 파일이 저장되지 않았는지 확인합니다...
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
 
// 주어진 디렉토리의 파일 수가 예상 개수와 일치하는지 확인합니다...
Storage::disk('photos')->assertCount('/wallpapers', 2);
 
// 주어진 디렉토리가 비어있는지 확인합니다...
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')
]);
 
// 하나 이상의 파일이 저장되었는지 확인...
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
 
// 하나 이상의 파일이 저장되지 않았는지 확인...
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
 
// 주어진 디렉토리의 파일 수가 예상된 수와 일치하는지 확인...
Storage::disk('photos')->assertCount('/wallpapers', 2);
 
// 주어진 디렉토리가 비어 있는지 확인...
Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
}
}

기본적으로 fake 메서드는 임시 디렉토리의 모든 파일을 삭제합니다. 이러한 파일을 유지하고 싶다면 대신 "persistentFake" 메서드를 사용할 수 있습니다. 파일 업로드 테스트에 대한 자세한 내용은 파일 업로드에 대한 HTTP 테스트 문서 정보를 참조하십시오.

exclamation

image 메서드는 GD 확장 프로그램이 필요합니다.

사용자 정의 파일 시스템

Laravel의 Flysystem 통합은 기본적으로 여러 "드라이버"에 대한 지원을 제공합니다. 그러나 Flysystem은 이에 국한되지 않으며 다른 많은 스토리지 시스템에 대한 어댑터를 가지고 있습니다. Laravel 애플리케이션에서 이러한 추가 어댑터 중 하나를 사용하려면 사용자 정의 드라이버를 만들 수 있습니다.

사용자 정의 파일 시스템을 정의하려면 Flysystem 어댑터가 필요합니다. 커뮤니티에서 유지 관리하는 Dropbox 어댑터를 프로젝트에 추가해 보겠습니다.

composer require spatie/flysystem-dropbox

다음으로, 애플리케이션의 서비스 제공자 중 하나의 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
{
/**
* 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 드라이버를 사용할 수 있습니다.