Laravel:加载存储在“公共”文件夹之外的图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21133712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:52:38  来源:igfitidea点击:

Laravel: load images stored outside 'public' folder

phpimagelaravel

提问by kablamus

I'm trying to display an image stored outside the 'public' folder in my view. These are simple profile images whose paths are stored in the DB. The path looks like

我正在尝试在我的视图中显示存储在“公共”文件夹之外的图像。这些是简单的个人资料图像,其路径存储在数据库中。路径看起来像

/Users/myuser/Documents/Sites/myapp/app/storage/tenants/user2/images/52d645738fb9d-128-Profile (Color) copy.jpg

Since the image is stored a DB column for each user, my first thought was to create an Accessor in the User model to return the image. I tried:

由于图像为每个用户存储了一个 DB 列,我的第一个想法是在 User 模型中创建一个 Accessor 来返回图像。我试过:

public function getProfileImage()
{   
    if(!empty($this->profile_image))
    {   

        return readfile($this->profile_image);
    }

    return null;
}

That produced unreadable characters in the view. I also tried file_get_contents() in place of read file. Any suggestions about how this might be accomplished?

这在视图中产生了不可读的字符。我也尝试过 file_get_contents() 代替读取文件。关于如何实现这一点的任何建议?

回答by Mattias

How about this (just tested it myself and it works):

这个怎么样(我自己测试过,它有效):

The view:

风景:

<img src="/images/theImage.png">

Routes.php:

路线.php:

Route::get('images/{image}', function($image = null)
{
    $path = storage_path().'/imageFolder/' . $image;
    if (file_exists($path)) { 
        return Response::download($path);
    }
});

回答by kablamus

Here's what I came up with:

这是我想出的:

I'm trying to show the images in the view, not download. Here's what I came up with:

我试图在视图中显示图像,而不是下载。这是我想出的:

  • Note that these images are stored above the public folder, which is why we have to take extra steps to display the image in the view.
  • 请注意,这些图像存储在 public 文件夹上方,这就是为什么我们必须采取额外步骤才能在视图中显示图像。

The view

风景

{{ HTML::image($user->getProfileImage(), '', array('height' => '50px')) }}

The model

该模型

/**
 * Get profile image
 *
 * 
 *
 * @return string
 */
public function getProfileImage()
{   
    if(!empty($this->profile_image) && File::exists($this->profile_image))
    {       

        $subdomain = subdomain();

        // Get the filename from the full path
        $filename = basename($this->profile_image);

        return 'images/image.php?id='.$subdomain.'&imageid='.$filename;
    }

    return 'images/missing.png';
}

public/images/image.php

公共/图像/image.php

<?php

$tenantId = $_GET["id"];
$imageId = $_GET["imageid"];

$path = __DIR__.'/../../app/storage/tenants/' . $tenantId . '/images/profile/' . $imageId; 

 // Prepare content headers
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$mime = finfo_file($finfo, $path);
$length = filesize($path);

header ("content-type: $mime"); 
header ("content-length: $length"); 

// @TODO: Cache images generated from this php file

readfile($path); 
exit;
?> 

If somebody has a better way, please enlighten us!! I'm very interested.

如果有人有更好的方法,请赐教!!我很感兴趣。

回答by khany

Here is a slightly modified version of @Mattias answer. Assume the file is in the storage/app/avatarsfolder which is outside the web root.

这是@Mattias 答案的略微修改版本。假设文件storage/app/avatars位于 Web 根目录之外的文件夹中。

<img src="/avatars/3">

Route::get('/avatars/{userId}', function($image = null)
{
  $path = storage_path().'/app/avatars/' . $image.'.jpg';
  if (file_exists($path)) {
    return response()->file($path);
  }
});

Probably needs and else. Also I have wrapped mine inside the middleware authRoute Group which means you have to be logged in to see (my requirements) but I could do with more control over when it is made visible, perhaps alter the middleware.

可能需要 和else。此外,我已将我的包裹在middleware authRoute Group 中,这意味着您必须登录才能查看(我的要求),但我可以更好地控制它何时可见,也许可以更改中间件。

EDIT Forgot to mention that this is for Laravel 5.3.

编辑忘了提到这是针对 Laravel 5.3 的。