Laravel $request->hasFile() using an array

This took me a while to figure out as its not well documented and I had to refer to a number of sources to work it out.

Laravel has a method hasFiles() which can be used to determine if any files have been uploaded and then action them accordingly.


What do I need it for?


Typically, you would use this method to allow you to lazily use the same name for multiple fields and action them in the same way.

Lets get some code out!

So this is a typical example of a singe file upload:

<form action="someurl" method="post" enctype="multipart/form-data">
    <input type='file' name='photo'>
</form>

Lets turn it into an array and add some more inputs, note that this is not necessarily the best method for this particular example but shows the process.

<form action="someurl" method="post" enctype="multipart/form-data">
    <input type='text' name='orcs[name][]'>
    <input type='file' name='orcs[avatar][]'> 
    <input type='text' name='orcs[name][]'>
    <input type='file' name='orcs[avatar][]'> 
    <input type='text' name='orcs[name][]'>
    <input type='file' name='orcs[avatar][]'>
</form>

So we now have a lazy way of getting relatable data from a form without necessarily putting it on another page!

You could access each item like so from a regular non Laravel POST request:

$_POST['orcs']['name'][0]
$_POST['orcs']['name'][1]

and something similar with files too.

But this blog is about hasFile() so lets move on to a controller!

How to use hasFile() method with array

First things first, as long as your routes are setup, your ready to code. I am not going to go into that here right now.

So lets get a controller method up and running

public function submit(Request $request)
{
    return;
}

Next we can create a loop to extract our data. We need to iterate over it so we can keep keys together

public function submit(Request $request)
{
    foreach($request->orcs as $key => $value)
    {
   
    }
    return;
}

Now we can check to see if there are any files on each iteration and at that point we can work out what to do! Bear in mind at this point, you should not be doing this within the same loop

public function submit(Request $request)
{
    $i = 0;
    foreach($request->orcs as $key => $value)
    {
        // run actions with orcs content (not files)
    }
    if($request->hasFile('orcs.avatar'))
    {
        //run actions with files
    }
    return;
}

That's pretty much it! You now have a blank canvas for the next step. I'll add a little more code to demo this part however with iteration over the files

public function submit(Request $request)
{
    $i = 0; // You can use this if you want to keep track of anything within loops
    foreach($request->orcs as $key => $value)
    {
        // run actions with orcs content (not files)
    }
    if($request->hasFile('orcs.avatar'))
    {
        //run actions with files
        $files = $request->file('orcs.avatar');
       
        foreach($files as $key => $file)
        {
            //Action your file thing here!
           
            $path = "/images/avatars/orcs/";
            $file->storeAs($path, "orc.jpg"); // You can use the original filename or whatever you want here
        }
    }
    return;
}

Note that the key on the first loop CORRELATES to the same key on the second loop. You can save a model for example on the first loop and use that ID on the second loop potentially to keep track but that's dependant on what your building!

Comments