如何将 Laravel 中的文件直接上传到公用文件夹?

Posted

技术标签:

【中文标题】如何将 Laravel 中的文件直接上传到公用文件夹?【英文标题】:How to upload files in Laravel directly into public folder? 【发布时间】:2017-11-18 12:44:06 【问题描述】:

我托管我的网站的服务器不支持links,因此我无法运行php artisan storage:link 将我的存储目录链接到公共目录。我试图重新制作 filesystems.php 中的磁盘配置以直接引用public 文件夹,但它似乎也不起作用。有没有办法使用 Laravel 库将文件直接上传到公共文件夹中,还是我必须使用 php 方法?提前致谢。

【问题讨论】:

【参考方案1】:

您可以在config/filesystems.php创建一个新的存储盘:

'public_uploads' => [
    'driver' => 'local',
    'root'   => public_path() . '/uploads',
],

并像这样存储文件:

if(!Storage::disk('public_uploads')->put($path, $file_content)) 
    return false;

【讨论】:

使用这种方法,我怎样才能将文件命名为wel? $path 当然必须包含文件名,但它也可以包含一个或多个子文件夹。 $path = $request->photo->storeAs('images', 'filename.jpg', 'public_uploads'); 用于上传文件的自定义名称。这是文档。 laravel.com/docs/5.5/requests#storing-uploaded-files @sunomad,正如您所说,创建了另一个存储光盘,但我需要知道文件上传过程将如何进行。您能否更新将文件存储在控制器文件本身中的完整代码。 不要忘记添加'url' => url('uploads'),,否则Storage::disk('public_uploads')->url('filename') 将返回/storage/filename 而不是完全限定的URL。【参考方案2】:

您可以将磁盘传递给\Illuminate\Http\UploadedFile 类的方法:

$file = request()->file('uploadFile');
$file->store('toPath', ['disk' => 'public']);

或者您可以创建新的文件系统磁盘并将其保存到该磁盘。

您可以在config/filesystems.php创建一个新的存储盘:

'my_files' => [
    'driver' => 'local',
    'root'   => public_path() . '/myfiles',
],

在控制器中:

$file = request()->file('uploadFile');
$file->store('toPath', ['disk' => 'my_files']);

【讨论】:

【参考方案3】:

您应该尝试将method="post" enctype="multipart/form-data" 添加到表单中的这种跳跃。请注意,公共路径 (uploadedimages) 将被移动到您项目目录中的公共文件夹,这就是上传的图片所在的位置。

public function store (Request $request) 
  
  $imageName = time().'.'.$request->image->getClientOriginalExtension();
  $request->image->move(public_path('/uploadedimages'), $imageName);

  // then you can save $imageName to the database


【讨论】:

最简单的方法。谢谢【参考方案4】:

我找到了解决这个问题的方法,在 config/filesystem.php 添加这一行 'default' => 'public', 在我的情况下为我修复了。

【讨论】:

这是最准确的答案,我很惊讶他们竟然投了反对票?【参考方案5】:

最灵活的是编辑.env文件:

FILESYSTEM_DRIVER=public

【讨论】:

【参考方案6】:

在 config/filesystem.php 中,添加:

 'public_uploads' => [
        'driver' => 'local',
        'root'   => public_path(),
    ],

在控制器中

$file = $request->file("contract");           
$ext = $file->extension();
$filename = $file->storeAs('/contracts/', $contract->title.'.' . $ext,['disk' => 'public_uploads']);

【讨论】:

该代码不正确。将在合约内创建一个带有合约名称的新文件夹。【参考方案7】:

除了那里的每个答案,我建议添加另一个保护层,因为它是一个公共文件夹。

对于您在公用文件夹中需要保护的每个文件,执行一个验证对它们的访问权限的路由,例如

/files/images/cat.jpg

并且路由看起来像 /files/images/image_name 这样您就可以根据给定文件验证用户。

正确验证后,您只需执行 return response($full_server_filepath, 200)->header('Content-Type', 'image/jpeg');

这让工作更难,但更安全

【讨论】:

如果文件需要保护,为什么要将它存储在公用文件夹中? 如果文件需要保护,为什么要将它存储在存储文件夹中?唯一的区别是公用文件夹中的文件默认在存储位置的对面打开。这意味着无论您选择什么位置,您仍然需要为文件编写访问层。 对我来说听起来像是糟糕的设计实践,比如将模型存储在控制器文件夹中,或者将 javascript 文件存储在 css 文件夹中。公共文件夹用于保存对公众开放的文件,因此得名。【参考方案8】:

推荐的方法是从公共目录符号链接存储。

要使这些文件可以从 Web 访问,您应该创建一个 从 public/storage 到 storage/app/public 的符号链接。利用 此文件夹约定将您的可公开访问的文件保存在一个文件夹中 使用零时可以轻松跨部署共享的目录 像 Envoyer 这样的停机部署系统。

要创建符号链接,您可以使用 storage:link Artisan 命令:

【讨论】:

【参考方案9】:

第 1 步:更改 Filesystems.php 中的设置

'disks' => [

    'local' => [
        'driver' => 'local',
        'root' => storage_path('app'),
    ],

    'public' => [
        'driver' => 'local',
        'root' => public_path('app/public'),
        'url' => env('APP_URL').'/storage',
        'visibility' => 'public',
    ],

第 2 步:在 Controller 中:像这样存储文件:

'indoc_file' => $request->indoc_file->store('app/file'),

第 3 步:转到文件 .ENV 并像这样更改配置:

FILESYSTEM_DRIVER=public

之后,您的文件位置将保存在项目中,如下所示: Project\public\app\public\app\file

如果您想下载文件,请在您的查看页面上执行此操作:

<a href="url('/app/public/'.$item->indoc_file)" class="btn btn-info" title="ດາວໂຫຼດ"><i class="fa fa-download"></i> </a>

【讨论】:

【参考方案10】:

作为替代方案, 让 laravel 设置保存在/storage/app 文件夹中的文件。

如果我们想读取文件,只需使用$publicPath = '../storage/app/'.$path;

【讨论】:

以上是关于如何将 Laravel 中的文件直接上传到公用文件夹?的主要内容,如果未能解决你的问题,请参考以下文章

AWS - CORS 无法将文件直接上传到 S3

使用签名的 url 将文件从 angularjs 直接上传到 amazon s3

如何使用 Node.js 将 base64 编码图像(字符串)直接上传到 Google Cloud Storage 存储桶?

使用Iteratees使用Play Scala将文件直接上传到S3 chunk-by-chunk

Rails 直接上传到 Amazon S3

将图像从 url 直接上传到数据库 blob 字段