我已经在 Laravel 存储中上传了用户的头像。如何访问它们并将它们呈现在视图中?
服务器将所有请求都指向 /public
,那么如果它们在 /storage
文件夹中,我该如何显示它们?
最佳 方法是创建一个符号链接,如the answer below 中很好指出的@SlateEntropy。为了帮助解决这个问题,从 5.3 版开始,Laravel includes a command 让这变得非常容易:
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
这也是 Laravel 的开发者 Taylor Otwell 构建的部署管理器 Envoyer 使用的方法。
storage
中的用户头像,通常头像不需要任何类型的访问控制。如果不需要任何安全性,则使用任何类型的中间件或路由只会浪费您的资源。值得注意的是,从 Laravel 5.2 开始,使用符号链接的公共文件 (laravel.com/docs/5.2/filesystem) 存在一个单独的文件“磁盘”。
根据 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');
如果您在 Windows 上,您可以在 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
文件时,将下载(如果有)。
根据上面的代码,该文件必须在 root/storage/app/users/documents
目录中,这是在 Laravel 5.4
上测试的。
如果您想加载少量 Private 图像,您可以将图像编码为 base64 并直接将它们回显到 <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()
有两个重要的缺点:
这将使图像大小增加约 30%。您将所有图像尺寸组合在一个请求中,而不是并行加载它们,这对于一些小缩略图应该不是问题,但对于许多图像,请避免使用此方法。
如果磁盘“本地”不适合您,请尝试以下操作:
在 'default' => env('FILESYSTEM_DRIVER', 'public') 中将本地更改为公共,从 project_folder/config/filesystem.php 清除配置缓存 php artisan config:clear 然后创建 sym 链接 php artisan storage:link
要获取上传图片的网址,您可以使用此 Storage::url('image_name.jpg');
没有站点名称
{{Storage::url($photoLink)}}
如果您想将站点名称添加到它的示例以附加到 api JSON felids
public function getPhotoFullLinkAttribute()
{
Storage::url($this->attributes['avatar']) ;
}
如果您使用的是 php,那么请使用 php 符号链接功能,如下所示:
symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')
将用户名和项目名称更改为正确的名称。
您可以在控制台中运行此命令以建立链接:
php artisan storage:link
如果您像我一样拥有完整的文件路径(我对所需的照片进行了一些 glob() 模式匹配,所以我最终得到了完整的文件路径),并且您的存储设置链接得很好 (即你的路径有字符串 storage/app/public/
),那么你可以使用我下面的小脏 hack :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 '';
}
对我来说,它与子文件夹路线一起使用
Route::get('/storage/{folder}/{filename}', function ($folder,$filename)
{
$path = storage_path('app/public/' .$folder.'/'. $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;
});
不定期副业成功案例分享
public
目录中。这样,您将避免编写图像响应的开销,该响应可以由 HTTP 服务器更快地处理。