MrRobot993's avatar

Laravel strange behavior with images upload on windows

Hi, I have this method that save images:

    public function update(ProfileUpdateRequest $request)
    {
        $request->user()->fill($request->validated());

        if ($request->user()->isDirty('email')) {
            $request->user()->email_verified_at = null;
        }

        if ($request->hasFile('avatar')) {
            $avatar = $request->file('avatar');
            $filename = time() . '_' . $avatar->getClientOriginalName() . $avatar->getExtension();
            $request->user()->avatar = $filename;
            Storage::putFileAs('public/avatars', $avatar, $filename);
        }

        $request->user()->save();

        return Redirect::route('profile.edit');
    }

On Mac it works well but on Windows it save the image in this way: nameoffile.jpgtmp It append tmp after extension.

How it's possible?

0 likes
5 replies
martinbean's avatar

How it’s possible?

@mrrobot993 Because you’re just sticking the extension (tmp) on the end of the original filename (foo.jpg):

$filename = time() . '_' . $avatar->getClientOriginalName() . $avatar->getExtension();

Read the docs on how you should be storing uploaded files: https://laravel.com/docs/9.x/requests#storing-uploaded-files

You should not be manually creating filenames and manually put files like you are. All you need to do is:

$path = $request->file('avatar')->store('avatars');

That will store the file in your application’s storage/app/avatars directory. You shouldn’t be just putting anything user-uploaded in your public directory, because if a user uploads an 8 MB image then your app is just going to keep serving that same 8 MB image back, which isn’t performant at all. Or even worse, if a user manages to upload a malicious file then congratulations, because it’s publicly-accessible the user can now access the file and now potentially hack your server.

Store files somewhere that isn’t publicly-accessible. Then use something like Glide to serve appropriately-sized thumbnails instead.

2 likes
jlrdw's avatar

Use $file_ext = $file->getClientOriginalExtension();

I've never had a problem using that.

1 like
MrRobot993's avatar

@jlrdw after this it save te image: image.pngpng but only on windows environment

Randy_Johnson's avatar
        if ($request->hasFile('image')) {
            $path = $request->file('image')->store('public/images');
            $new_path = str_replace('public', 'storage', $path);
            $art = new Art;
            $art->student_id = $validated['student'];
            $art->title = $validated['title'];
            $art->location = $new_path;
            $art->save();
        }

Have a fiddle with this.

Please or to participate in this conversation.