Laravel 5-如何在视图中访问上传到存储器中的图像?

Laravel 5-如何在视图中访问上传到存储器中的图像?,laravel,Laravel,我已经将用户的头像上传到了Laravel存储中。如何访问它们并在视图中渲染它们 服务器将所有请求指向/public,因此如何显示它们是否在/storage文件夹中?最好的方法是创建一个符号链接,如中所指出的@SlateEntropy。为了帮助实现这一点,从5.3版开始,Laravel使这一点变得非常容易: php artisan storage:link 这为您创建了一个从public/storage到storage/app/public的符号链接,仅此而已。现在可以通过以下链接访问/stor

我已经将用户的头像上传到了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}',函数($filename)
{
$path=存储路径('public/'。$filename);
如果(!File::exists($path)){
中止(404);
}
$file=file::get($path);
$type=File::mimeType($path);
$response=response::make($file,200);
$response->header(“内容类型”,$Type);
返回$response;
});
现在,您可以像使用符号链接一样访问文件:

http://somedomain.com/storage/image.jpg
如果您使用的是,您可以使用其内置的
response
方法使内容更加简洁:

Route::get('storage/{filename}',函数($filename)
{
返回图像::make(存储路径('public/'.$filename))->response();
});

警告

请记住,通过手动提供文件,您将遭受性能损失,因为您要通过整个Laravel请求生命周期来读取和发送文件内容,这比让HTTP服务器处理要慢得多


一个选项是在存储目录和公共目录中的子文件夹之间创建符号链接

比如说

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

这也是Laravel开发人员Taylor Otwell构建的部署管理器所使用的方法。

如果您在windows上,则可以在cmd上运行此命令:

mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars 
发件人:

根据Laravel 5.2文档,您可以公开访问的文件应该放在目录中

storage/app/public
要从web访问它们,您应该创建一个从
public/storage
storage/app/public
的符号链接

ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage
现在,您可以使用资产帮助器在视图中创建指向文件的URL:

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

如果您使用的是php,请使用php符号链接函数,如下所示:

symlink('/home/username/projectname/storage/app/public','/home/username/public\u html/storage')


将用户名和项目名称更改为正确的名称。

最好将所有私有图像和文档保存在存储目录中,这样您就可以完全控制文件。您可以允许特定类型的用户访问文件或限制

制作路线/文档并指向任何控制器方法:

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
上测试的。首先,您需要使用artisan命令为存储目录创建符号链接

php artisan storage:link
然后,在任何视图中,您都可以通过url帮助器访问图像,如下所示

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

如果您想加载少量的私有图像,您可以将图像编码到base64并直接将其回显到

$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;
我提到了private,因为只有当您不想存储可通过url公开访问的图像时,才应该使用这些方法,而必须始终使用标准方法 (链接存储/公用文件夹并使用HTTP服务器提供图像)

注意编码到
base64()
有两个重要的缺点:

  • 这将使图像大小增加约30%
  • 您可以在一个请求中组合所有图像大小,而不是并行加载它们,对于一些小缩略图来说这应该不是问题,但对于许多图像,请避免使用此方法

  • 如果你像我一样,不知何故拥有完整的文件路径(我对所需的照片进行了一些glob()模式匹配,因此我几乎最终得到了完整的文件路径),并且你的存储设置链接良好(即,你的路径具有字符串
    storage/app/public/
    ),那么你可以使用我下面的小技巧:p)

    没有站点名称

    {{Storage::url($photoLink)}}
    
    如果要向其中添加站点名称 要附加到api JSON felids上的示例

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

    如果磁盘“本地”不适合您,请尝试以下操作:

  • 'default'=>env('FILESYSTEM\u DRIVER','public'),
    project\u folder/config/FILESYSTEM.php
  • 清除配置缓存
    php artisan配置:清除
  • 然后创建sym link
    php artisan存储:link

  • 要获取上传图像的url,您可以使用这个
    Storage::url('iamge_name.jpg')

    您可以在控制台中运行此命令以创建链接:

    php artisan storage:link
    

    参考资料

    看起来不错。我想再问一个问题。是否建议将头像、拇指等文件(用户上传的文件)存储在存储器中?您可以将它们存储在任何您喜欢的地方,但除非这些是私人文件,否则我认为您最好将它们存储在
    public
    目录中。通过这种方式,您将避免编写HTTP服务器可以更快处理的映像响应的开销。就我个人而言,我不会将用户文件存储在公用文件夹中,我发现当
    php artisan storage:link