我想要实现的目标是建立一个到存储文件夹的路径,这样即使它不在public
目录下也可以访问它。
例如,用户的头像位于app\storage\user\avatars\avatar.jpg
,我想制作一条路线,以便我可以通过http://localhost/user/avatars/avatar.jpg
等方式访问这些图片。
我怎样才能做到这一点?
答案 0 :(得分:3)
执行此类操作的最佳方法是使用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
目录的虚拟主机别名。
答案 1 :(得分:2)
首先,我建议将头像文件夹移动到更公开的位置。但作为它的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;
}
值得注意的是,您提出的方法和解决方案存在安全问题。
答案 2 :(得分:0)
实现此目标的更好方法是在Web服务器上使用别名或重写。
如果您使用的是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更快更好的性能。