У меня есть аватары пользователей, загруженные в хранилище Laravel. Как я могу получить к ним доступ и отобразить их в представлении?
Сервер указывает все запросы на /public
, поэтому как их показать, если они находятся в папке /storage
?
У меня есть аватары пользователей, загруженные в хранилище Laravel. Как я могу получить к ним доступ и отобразить их в представлении?
Сервер указывает все запросы на /public
, поэтому как их показать, если они находятся в папке /storage
?
Подход лучший заключается в создании символической ссылки , такой как @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 обрабатывает его.
Один из вариантов - создать символическую ссылку между вложенной папкой в вашем каталоге хранилища и общедоступной директории.
Например
ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars
Это также метод, используемый Envoyer, менеджером развертывания, созданным Тейлором Отуэлом, разработчиком Laravel.
В соответствии с документами 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');
Если вы находитесь в окнах, вы можете запустить эту команду на cmd:
mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars
от: http://www.sevenforums.com/tutorials/278262-mklink-create-use-links-windows.html
Прежде всего вам необходимо создать символическую ссылку для каталога хранилища с помощью команды artisan
php artisan storage:link
Тогда в любом представлении вы можете получить доступ к своему изображению через url helper, как это.
url('storage/avatars/image.png');
Хорошо сохранить все личные изображения и документы в директории хранения, тогда у вас будет полный контроль над файловым эфиром, который вы можете разрешить определенному типу пользователей для доступа к файлу или ограничить.
Создайте маршрут/документацию и укажите любой метод контроллера:
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
.
Если вы хотите загрузить небольшое количество личных изображений, вы можете закодировать изображения в 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()
имеет две важные недостатки:
Если вы используете php, просто воспользуйтесь функцией php symlink, например:
symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')
измените имя пользователя и имя проекта на правильные имена.
Если вы похожи на меня и у вас каким-то образом есть полные пути к файлам (я выполнил некоторое сопоставление с шаблоном 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 '';
}
без названия сайта
{{Storage::url($photoLink)}}
если вы хотите добавить имя сайта к нему, пример добавить в API JSON FELIDs
public function getPhotoFullLinkAttribute()
{
return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}