Laravel 5 - Как получить доступ к изображению, загруженному в хранилище в представлении?

У меня есть аватары пользователей, загруженные в хранилище Laravel. Как я могу получить к ним доступ и отобразить их в представлении?

Сервер указывает все запросы на /public, поэтому как их показать, если они находятся в папке /storage?

Ответ 1

Подход лучший заключается в создании символической ссылки , такой как @SlateEntropy, которая очень хорошо указана в ниже.. Чтобы помочь в этом, начиная с версии 5.3, Laravel включает в себя команду, которая делает это невероятно легко:

php artisan storage:link

Это создает символическую ссылку от public/storage до storage/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

Если вы используете Intervention Image Library, вы можете использовать встроенный метод response, чтобы сделать вещи более краткими:

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

Внимание

Имейте в виду, что вручную обслуживает файлы, в которых вы несете производительность, потому что вы просматриваете весь жизненный цикл запроса Laravel, чтобы читать и отправьте содержимое файла, значительно медленнее, чем сервер HTTP обрабатывает его.

Ответ 2

Один из вариантов - создать символическую ссылку между вложенной папкой в ​​вашем каталоге хранилища и общедоступной директории.

Например

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

Это также метод, используемый Envoyer, менеджером развертывания, созданным Тейлором Отуэлом, разработчиком Laravel.

Ответ 3

В соответствии с документами 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');

Ответ 5

Прежде всего вам необходимо создать символическую ссылку для каталога хранилища с помощью команды artisan

php artisan storage:link

Тогда в любом представлении вы можете получить доступ к своему изображению через url helper, как это.

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

Ответ 6

Хорошо сохранить все личные изображения и документы в директории хранения, тогда у вас будет полный контроль над файловым эфиром, который вы можете разрешить определенному типу пользователей для доступа к файлу или ограничить.

Создайте маршрут/документацию и укажите любой метод контроллера:

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 файл localhost:8000/docs будет загружен, если таковой существует.

Файл должен находиться в каталоге root/storage/app/users/documents соответствии с приведенным выше кодом, это было протестировано на Laravel 5.4.

Ответ 7

Если вы хотите загрузить небольшое количество личных изображений, вы можете закодировать изображения в base64 и напрямую <img src="{{$image_data}}"> их в <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, вместо этого вы должны всегда использовать стандартный способ (связать хранилище/общую папку и обслуживать изображения с HTTP-сервером).

Осторожно, кодировка base64() имеет две важные недостатки:

  1. Это увеличит размер изображения на ~ 30%.
  2. Вы объединяете все размеры изображений в одном запросе, вместо того, чтобы загружать их параллельно, это не должно быть проблемой для некоторых маленьких миниатюр, но для многих изображений избегайте использования этого метода.

Ответ 8

Если вы используете php, просто воспользуйтесь функцией php symlink, например:

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

измените имя пользователя и имя проекта на правильные имена.

Ответ 9

Если вы похожи на меня и у вас каким-то образом есть полные пути к файлам (я выполнил некоторое сопоставление с шаблоном 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 '';
    }

Ответ 10

без названия сайта

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

если вы хотите добавить имя сайта к нему, пример добавить в API JSON FELIDs

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