То, что я пытаюсь достичь, – это сделать путь к папке хранилища, чтобы я мог получить к ней доступ, даже если он не находится под public
каталогом.
Например, аватары пользователя расположены в app\storage\user\avatars\avatar.jpg
и я хотел бы сделать маршрут, чтобы я мог получить доступ к этим изображениям из-за чего-то вроде http://localhost/user/avatars/avatar.jpg
,
Как я могу это достичь?
Во-первых, я бы рекомендовал переместить папку аватаров куда-нибудь более общедоступным. Но как его Laravel, вы можете достичь всего, что хотите.
Route::get('user/avatars/{filename}', function($filename) { $filePath = storage_path().'/user/avatars/'.$filename; if ( ! File::exists($filePath) or ( ! $mimeType = getImageContentType($filePath))) { return Response::make("File does not exist.", 404); } $fileContents = File::get($filePath); return Response::make($fileContents, 200, array('Content-Type' => $mimeType)); });
Затем добавьте эту настраиваемую вспомогательную функцию:
function getImageContentType($file) { $mime = exif_imagetype($file); if ($mime === IMAGETYPE_JPEG) $contentType = 'image/jpeg'; elseif ($mime === IMAGETYPE_GIF) $contentType = 'image/gif'; else if ($mime === IMAGETYPE_PNG) $contentType = 'image/png'; else $contentType = false; return $contentType; }
Возможно, стоит отметить, что существуют проблемы безопасности с предлагаемым вами методом и решениями.
Лучший способ сделать это – использовать Response::download()
для работы с файлами вне вашей общей папки:
Создание маршрутизатора:
Route::get('/user/avatars/{avatarName}', 'AvatarServerController@downloadAvatar');
И в этом может быть контроллер контроллера, который вы делаете
class AvatarServerController extends Controller { public function downloadAvatar($avatarName) { $fileName = storage_path()."/user/avatars/$avatarName"; if (File::exists($fileName)) { return Response::download(fileName); } return Redirect::route('home')->withMessage('Avatar file not found.'); } }
Но, все еще предоставляя доступ ко всему остальному, чем общая папка, может быть серьезной угрозой безопасности, поэтому Laravel строит этот путь. Но есть и другие варианты:
1) Создайте символическую ссылку:
ln -s /var/www/site/app/storage/user/avatars /var/www/site/public/user/avatars
И затем используйте их напрямую:
HTML::image('user/avatar/avatar.jpg', 'User avatar');
3) Создайте псевдоним виртуального хоста, указывающий на каталог вашего app/storage/user/avatars
.
Лучший способ добиться этого – использовать псевдоним или переписать на своем веб-сервере.
Если вы используете nginx, добавьте это в свой серверный блок:
# Rewrite for user avatars location /user/ { root /var/www/laravel/app/storage/user; }
Для Apache используйте 'Alias'
Alias /user /var/www/laravel/app/storage/user
Выполнение этого способа выполняется быстрее и лучше, чем при загрузке Laravel для каждого запроса изображения.