Been working on this problem for 2 days and still cannot figure it out. I am trying to upload multiple files into storage in my Laravel project. I know my code works up to the foreach as I tested this with dd.
My controller:
$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));
}
}
I see that you are trying to store the files directly in public
folder, but why not use the Storage
API of Laravel and use the public disk? You can do something like this to upload the files to the public directory:
$id = 123;
$files = $request->file();
$folder = $id;
if (count($files) > 0) {
foreach ($files as $file) {
$file->store($folder, ['disk' => 'public']);
}
}
And be sure that you have linked the storage path to public:
php artisan storage:link
Focus on $files = $request->file();
line. When you don't pass an argument to file()
method, all uploaded file instances are returned. Now when you will loop over the $files
array, you will get access to individual uploaded files.
And then you can store the file using your logic, i.e. you can use the original name or whatever else. Even you can use the Storage
facade to process the file instance.
i.e. if you want to store the files with their original names, I find this a cleaner way rather than what you are doing:
$id = 123;
$files = $request->file();
$folder = $id;
if (count($files) > 0) {
foreach ($files as $file) {
Storage::disk('public')->putFileAs(
$folder,
$file,
$file->getClientOriginalName()
);
}
}
And as suggested by @cbaconnier, you can use allFiles()
method too that's more descriptive:
$files = $request->allFiles();
I hope this helps.
You're trying to iterate over files, and file is just a reference to request->file(), which is a SINGLE UploadedFile
object.
As indicated by your comment, you have multiple file inputs with different name attributes, so you can't easily loop over them with one statement, eg: if you had multiple files all uploaded as "attachments[]" as the input name attribute, you could get them all with $request->allFiles('attachments')
, however, if you want to keep the input names as they are, this should be close to what you want.
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));
}
}
Side note, i'm not sure what you're doing with File and public_path, but if your goal is just to put something in your app storage, something like this should work fine
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With