Laravel 5-View 내 저장소에 업로드 된 이미지에 액세스하는 방법


172

라 라벨 스토리지에 사용자의 아바타를 업로드했습니다. 액세스하여 뷰에서 렌더링하려면 어떻게해야합니까?

서버가 모든 요청을 (으)로 가리키고 /public있으므로 /storage폴더 에있는 경우 어떻게 표시 할 수 있습니까?

답변:


349

가장 좋은 방법은 만드는 것입니다 기호 링크가 잘 지적 @SlateEntropy 같은 아래의 대답을 . 이를 위해 Laravel 버전 5.3부터이 작업을 매우 쉽게 수행 할 수 있는 명령포함합니다 .

php artisan storage:link

그것은 당신 public/storagestorage/app/public위해 심볼릭 링크를 만들고 그게 전부입니다. 이제 다음 /storage/app/public과 같은 링크를 통해 모든 파일에 액세스 할 수 있습니다.

http://somedomain.com/storage/image.jpg

어떤 이유로 든 공유 링크 등에서 심볼릭 링크를 만들 수 없거나 일부 액세스 제어 논리 뒤의 일부 파일을 보호하려는 경우 다음과 같은 특수 경로를 사용할 수 있습니다. 이미지를 제공합니다. 예를 들어 다음과 같은 간단한 폐쇄 경로 :

Route::get('storage/{filename}', function ($filename)
{
    $path = storage_path('public/' . $filename);

    if (!File::exists($path)) {
        abort(404);
    }

    $file = File::get($path);
    $type = File::mimeType($path);

    $response = Response::make($file, 200);
    $response->header("Content-Type", $type);

    return $response;
});

심볼릭 링크가있는 것처럼 파일에 액세스 할 수 있습니다.

http://somedomain.com/storage/image.jpg

당신이 사용하는 경우 개입 이미지 라이브러리 당신은 그것의 내장 사용할 수있는 response메이크업 물건을 더 간결에 방법 :

Route::get('storage/{filename}', function ($filename)
{
    return Image::make(storage_path('public/' . $filename))->response();
});

경고

파일을 수동으로 제공 하면 파일 내용을 읽고 보내기 위해 전체 라 라벨 요청 수명주기를 거치 므로 HTTP 서버가 처리하는 것보다 상당히 느리기 때문에 성능 저하 가 발생 한다는 점에 유의하십시오 .


좋아 보인다. 하나 더 질문하고 싶습니다. 아바타, 엄지 손가락 등과 같은 파일 (사용자가 업로드 한 파일)을 저장소에 저장하는 것이 좋습니다?
Tadeáš Jílek

5
원하는 곳에 저장할 수 있지만 개인 파일이 아니라면 public디렉토리에 저장하는 것이 좋습니다 . 이렇게하면 HTTP 서버가 훨씬 빠르게 처리 할 수있는 이미지 응답을 작성해야하는 오버 헤드를 피할 수 있습니다.
Bogdan

2
개인적으로 나는 공용 폴더에 사용자 파일을 저장하지 않을 것입니다. 스토리지 폴더가 스토리지에 사용될 때 훨씬 깔끔하고 관리하기 쉽습니다.
SlateEntropy

2
Laravel을 다시로드하거나 PHP를 활용하여 각 이미지를 읽는 오버 헤드를 추가하기 때문에이 중 하나를 권장하지 않습니다. CmdSft에서 설명한대로 심볼릭 링크를 사용하면 훨씬 빠릅니다.
user1960364

4
@ user1960364 그렇기 때문에 마지막 단락에서 symlink 접근 방식을 사용하는 것이 좋습니다. 그러나 대답 자체는 성능 관점에서 최상의 솔루션은 아니지만 여전히 유효하며 심볼릭 링크를 설정할 수없는 공유 서버에서 앱을 실행하는 사람들에게 유일한 접근 방법 일 수 있습니다. 또한 이 질문에 나와 있는 것처럼 암호화 된 파일을 제공하기 위해 필요한 경우 프로그래밍 방식으로 파일을 제공 할 수있는 방법을 보여줍니다 .
Bogdan

53

하나의 옵션은 스토리지 디렉토리의 하위 폴더와 공용 디렉토리 사이에 기호 링크를 작성하는 것입니다.

예를 들어

ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars

이것은 Laravel 의 개발자 인 Taylor Otwell이 구축 한 배포 관리자 인 Envoyer 에서 사용하는 방법이기도합니다 .


나는 이것에 조금 익숙하다. 이것을 터미널에서 실행하거나 laravel의 어딘가에 구성 파일에 정의해야합니까?
Gaurav Mehta

예, 명령 행을 통해이를 실행해야합니다. 앱을 배포하는 모든 위치에서 설정해야합니다.
SlateEntropy

Windows 사용자의 경우 CMD를 사용하지 않으려는 경우 다음을위한 독립형 도구가 있습니다. github.com/amd989/Symlinker#downloads
David

3
이 질문은 storage공개적으로 저장된 사용자 아바타를 표시하는 방법을 물었습니다 . 일반적으로 아바타는 어떤 종류의 액세스 제어도 필요하지 않습니다. 어떤 종류의 미들웨어 또는 경로를 사용하여 보안이 필요하지 않은 경우 리소스에 낭비되는 것입니다. 라 라벨 5.2부터 심볼릭 링크를 사용 하는 공용 파일 ( laravel.com/docs/5.2/filesystem )을 위한 별도의 "디스크"파일이 존재한다는 점도 주목할 가치가 있습니다 .
SlateEntropy

6
Laravel 5.3에는 이것을하는 장인 명령이 있습니다 : $ php artisan storage : link
Phil

22

Laravel 5.2 문서에 따르면 공개적으로 액세스 할 수있는 파일은 디렉토리에 저장해야합니다

storage/app/public

웹에서 그들에 액세스 할 수 있도록하려면에서 심볼릭 링크 생성해야 public/storage하는가 storage/app/public.

ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage

이제 자산 도우미를 사용하여보기에서 파일에 대한 URL을 만들 수 있습니다.

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


13

우선 artisan 명령을 사용하여 스토리지 디렉토리에 대한 기호 링크를 작성해야합니다.

php artisan storage:link

그런 다음 모든보기에서 이와 같은 URL 도우미를 통해 이미지에 액세스 할 수 있습니다.

url('storage/avatars/image.png');

4

모든 개인 이미지와 문서를 저장 디렉토리에 저장하는 것이 좋습니다. 그러면 특정 유형의 사용자가 파일에 액세스하거나 제한 할 수있는 파일 에테르를 완전히 제어 할 수 있습니다.

경로 / 문서를 만들고 컨트롤러 방법을 가리 킵니다 :

public function docs() {

    //custom logic

    //check if user is logged in or user have permission to download this file etc

    return response()->download(
        storage_path('app/users/documents/4YPa0bl0L01ey2jO2CTVzlfuBcrNyHE2TV8xakPk.png'), 
        'filename.png',
        ['Content-Type' => 'image/png']
    );
}

적중하면 localhost:8000/docs파일이 있으면 다운로드됩니다.

파일은 root/storage/app/users/documents위 코드에 따라 디렉토리에 있어야합니다.이 파일은에서 테스트되었습니다 Laravel 5.4.


4

적은 수의 개인 이미지 를로드하려는 경우 이미지를 base64로 인코딩하고 <img src="{{$image_data}}">직접 에코 할 수 있습니다.

$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;

url을 통해 공개적으로 액세스 할 수있는 이미지를 저장하지 않으려는 경우에만이 방법을 사용해야하기 때문에 private을 언급했습니다. 대신 항상 표준 방법을 사용해야합니다 (저장소 / 공용 폴더 연결 및 HTTP 서버로 이미지 제공).

주의 할 인코딩 base64()두 가지 중요한 다운면이있다 :

  1. 이미지 크기가 ~ 30 % 증가합니다.
  2. 모든 이미지 크기를 한 번의 요청으로 결합하여 병렬로로드하는 대신 작은 섬네일에는 문제가되지 않지만 많은 이미지의 경우이 방법을 사용하지 마십시오.

2

PHP를 사용하는 경우 다음과 같이 PHP symlink 함수를 사용하십시오.

symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')

사용자 이름과 프로젝트 이름을 올바른 이름으로 변경하십시오.


1

사이트 이름없이

{{Storage::url($photoLink)}}

api JSON felids에 추가하기 위해 사이트 이름을 예제에 추가하려는 경우

 public function getPhotoFullLinkAttribute()
{
    return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}

0

당신이 나와 같고 어떻게 든 전체 파일 경로가있는 경우 (필요한 사진에서 glob () 패턴과 일치하여 전체 파일 경로로 끝납니다) 저장소 설정이 잘 연결되어 있습니다 (예 : 경로) 문자열 storage/app/public/)을 가지고 있다면 아래의 작은 더러운 핵을 사용할 수 있습니다 : p)

 public static function hackoutFileFromStorageFolder($fullfilePath) {
        if (strpos($fullfilePath, 'storage/app/public/')) {
           $fileParts = explode('storage/app/public/', $fullfilePath);
           if( count($fileParts) > 1){
               return $fileParts[1];
           }
        }

        return '';
    }

0

디스크 'local'이 작동하지 않으면 다음을 시도하십시오.

  1. 공공 로컬 변경 'default' => env('FILESYSTEM_DRIVER', 'public'),에서project_folder/config/filesystem.php
  2. 구성 캐시 지우기 php artisan config:clear
  3. 그런 다음 sym 링크를 만드십시오 php artisan storage:link

업로드 된 이미지의 URL을 얻으려면 이것을 사용할 수 있습니다 Storage::url('iamge_name.jpg');

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.