【问题标题】:File upload using foreach in Laravel [duplicate]在Laravel中使用foreach上传文件[重复]
【发布时间】:2019-12-13 12:57:26
【问题描述】:

解决这个问题 2 天,仍然无法解决。我正在尝试将多个文件上传到我的 Laravel 项目中的存储中。我知道我的代码在我用 dd 测试时可以运行到 foreach。

我的控制器:

$files = $request->file('current_plan_year_claims_data_file_1');
$folder = public_path(). "\storage\\$id";

if (!File::exists($folder)) {
    File::makeDirectory($folder, 0775, true, true);
}

if (!empty($files)) {
    foreach($files as $file) {
        Storage::disk(['driver' => 'local', 'root' => $folder])->put($file->getClientOriginalName(), file_get_contents($file));
    }
}

【问题讨论】:

  • 这能回答你的问题吗? Laravel 5.3 multiple file uploads
  • 不,但谢谢。我确实看到了这一点,并认为这是处理我无法理解的问题的一种完全不同的方式。
  • 有什么问题??
  • 我有一个表单,其中包含多个要从表单上传的文件(即当前计划文件、先前计划文件等)。当用户上传部分或全部这些文件时,我希望我的控制器创建一个带有 $id 的文件夹(如果它不存在)。我的这部分代码有效。之后,它应该将所有这些文件放在该文件夹中。这部分不起作用。
  • 我没有收到任何错误消息,但文件永远不会被保存

标签: laravel


【解决方案1】:

我看到你是想把文件直接存到public文件夹里,但是为什么不使用Laravel的Storage API并使用公共磁盘呢?您可以执行以下操作将文件上传到公共目录:

$id = 123;
$files = $request->file();
$folder = $id;
if (count($files) > 0) {
    foreach ($files as $file) {
        $file->store($folder, ['disk' => 'public']);
    }
}

并确保您已将存储路径链接到公共:

php artisan storage:link

关注$files = $request->file(); 行。当您不将参数传递给file() 方法时,将返回所有上传的文件实例。现在,当您遍历 $files 数组时,您将可以访问各个上传的文件。

然后您可以使用您的逻辑存储文件,即您可以使用原始名称或其他任何名称。甚至可以使用Storage 门面来处理文件实例。

即如果您想使用原始名称存储文件,我发现这是一种更简洁的方式,而不是您正在做的事情:

$id = 123;
$files = $request->file();
$folder = $id;
if (count($files) > 0) {
    foreach ($files as $file) {
        Storage::disk('public')->putFileAs(
            $folder,
            $file,
            $file->getClientOriginalName()
        );
    }
}

正如@cbaconnier 所建议的,您也可以使用更具描述性的allFiles() 方法:

$files = $request->allFiles();

我希望这会有所帮助。

【讨论】:

  • 这里的根本问题仍然是尝试循环遍历单个 UploadedFile 实例。
  • @ZacharyCraig _1 很有倾向性,但在确认current_plan_year_claims_data_file_1 不是文件数组之前,我们应该先看一下表格。
  • @ZacharyCraig 请检查更新的答案。 $request->file() 返回所有上传文件的数组,即使它们具有不同的字段名称。
  • 旁注:你也可以使用->allFiles(),这样更容易混淆
  • @cbaconnier 谢谢,我已经更新了答案。
【解决方案2】:

您正在尝试遍历文件,而 file 只是对 request->file() 的引用,它是一个单一的UploadedFile 对象。

正如您的评论所指出的,您有多个具有不同名称属性的文件输入,因此您不能用一个语句轻松地循环它们,例如:如果您有多个文件全部上传为“附件 []”作为输入name 属性,您可以使用$request->allFiles('attachments') 获取它们,但是,如果您想保持输入名称不变,这应该接近您想要的。

public function foo(Request $request, $id){
    $folder = public_path(). "\storage\\$id";

    if (!File::exists($folder)) {
        File::makeDirectory($folder, 0775, true, true);
    }

    $files = array();
    $files[] = $request->file('current_plan_year_claims_data_file_1');
    $files[] = $request->file('prior_plan_year_claims_data_file_1');
    $files[] = $request->file('etc_file_whatever');

    foreach($files as $file) {
        Storage::disk(['driver' => 'local', 'root' => $folder])->put($file->getClientOriginalName(), file_get_contents($file));
    }
}

旁注,我不确定你在用 File 和 public_path 做什么,但如果你的目标只是在你的应用存储中放一些东西,这样的东西应该可以正常工作

public function foo(Request $request, $id){
    if(!\Storage::exists($id)){
        \Storage::makeDirectory($id);
    }

    $files = array();
    $files[] = $request->file('current_plan_year_claims_data_file_1');
    $files[] = $request->file('prior_plan_year_claims_data_file_1');
    $files[] = $request->file('etc_file_whatever');

    foreach($files as $file) {
        \Storage::put("$id/" . $file->getClientOriginalFileName(), $file);
    }
}

【讨论】:

  • 谢谢,我尝试了第二个版本,它确实正确创建了文件夹,但我收到一条错误消息,我似乎无法修复:调用成员函数 getClientOriginalName() on null When I dd($文件)在foreach中,它表明它有文件。
  • 您可能必须将 $request->file 调用包装在检查中,以确保这些文件首先存在于请求中
  • 我能够使用 $id 在 public\storage 中创建正确的文件夹,并且确实保存了文件。但是,现在在我看来,我得到一个 tmp 文件名而不是原始文件名,并且无法弄清楚如何以动态方式显示原始文件名。这是我目前的看法:{{ $plansubmission ->current_plan_year_claims_data_file_1 }}
猜你喜欢
  • 2020-01-01
  • 2019-04-30
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 2013-12-15
相关资源
最近更新 更多