Back to Blog

File Uploads in Laravel Tutorial

Apr 29, 2023 Updated: Apr 29, 2023

Simple upload with managing extension, filename & folders

Make sure to add enctype="multipart/form-data" to the form so it can upload files. Add a file input with “name” attribute which will be used to pick file from the request.

<form enctype="multipart/form-data" method="POST" action="{{ route('register') }}">
    <!-- other form fields -->
    <input type="file" name="avatar" />
    <!-- other form fields -->
</form>

In controller use hasFile to check if there is a file with the name avatar. Then store it in the avatars folder with full path as /storage/app/avatars. The path stored in the database will be avatars/g7bMjJt3qPQNSvROBdtVS3BdYvqIhyi5Z6vujU79.png. Which is random file name with the folder name.

// other functions
    public function store(Request $request){
        // save file to logged in $user
        if($request->hasFile('avatar')){
            $user->update([
                'avatar' => $request->file('avatar')->store('avatars'),
            ]);
        }
        return view('profile.edit');
    }
// other functions

Custom filename

Use the storeAs instead of store, the second parameter will be the filename. With custom filename you also need to pick the file extension.

if($request->hasFile('avatar')){
    $file = $request->file('avatar');
    $extension = $file->extension();
    $user->update([
        'avatar' => $file->storeAs('avatars', $user->id . '.' . $extension),
    ]);
}

Original filename by user

if($request->hasFile('avatar')){
    $file = $request->file('avatar');
    $filename = $file->getClientOriginalName();
    $file->storeAs('avatars', $filename);
    $user->update([
        'avatar' => $filename,
    ]);
}

Original filename with unique separate folder

Here we are using the ID of the user as unique folder name so even if two users upload the files with the same name then it will not overwrite each others’ files.

if($request->hasFile('avatar')){
    $file = $request->file('avatar');
    $filename = $file->getClientOriginalName();
    $file->storeAs('avatars/' . $user->id, $filename);
    $user->update([
        'avatar' => $filename,
    ]);
}

Storage folder and public/private files

Store files in public folder with full path as /storage/app/public.

// third parameter in `storeAs`
$file->storeAs('avatars', $filename, 'public');
// second parameter in `store`
$file->store('avatars', 'public');

These files are not inside root level public folder and still inside the storage folder. So to make the public folder accessible, use the artisan command to make this folder public. Then file will be available as localhost:8000/storage/avatars/filename.png.

php artisan storage:link

if you want to remove the storage from the url, then change the value of public array in file /config/filesystems.php. You can also specify the folder in public_path(). Now file will be available directly as localhost:8080/uploads/avatars/filename.jpg.

'disks' => [

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

    'public' => [
        'driver' => 'local',
        'root' => public_path('uploads'),
        'visibility' => 'public',
        'throw' => false,
    ],

File Validation

$request->validate([
    'name' => ['required', 'string', 'max:255'],
    'avatar' => ['file', 'image', 'mimes:jpg', 'size:30', 'dimensions:min_width=2000,min_height:2000'],
]);
/**
 * 'file' only accept files
 * 'image' only accept image (pdf etc. not allowed)
 * 'mimes' only accept specific mime types
 * 'size' specify size in KB
 * 'dimensions:min_width=2000,min_height:2000' specify min width and height
 * 'dimensions:ratio=3/2' specify acceptable dimension in ratio
 */
Contact

Got A Question For Me?

Feel free to ask anything directly on call or fill the form and I will contact back within few hours.