AlexanderKim's avatar

File delete not actually deleting a file

I am trying to delete a file via Ajax post request:

    public function ajaxDeleteImage(Request $request) {
        if ($request->ajax()) {
            $path = $request->input('imgUrl');
            $id = $request->input('id');

            $currency = Currency::findOrFail($id);
            $currency->cur_icon = '';
            \File::delete($path);
            $currency->save();

            return 'Deleted image!';
        }

        return \App::abort(404);
    }

However file is not being delete, but path to the image are deleted successfully. What might the problem? Laravel 5.2

1 like
15 replies
AlexanderKim's avatar

Same, nothing happens, file remains under public/uploads. Why everything is so damn hard in laravel lol. Simple tasks become impossible.

Tried now using php artisan tinker:

>>> File::delete('/uploads/dogecoin_ava-581d6b2231e9a.png');
PHP warning:  unlink(/uploads/dogecoin_ava-581d6b2231e9a.png): No such file or directory in /srv/www/sc/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php on line 156

Looks like it can't see the file, how come?

Lars-Janssen's avatar

@heihachi88 why not store it in storage? It's safer. In the public folder anybody can acces it.

And Laravel makes it a lot easier.

ejdelmonico's avatar

As @lars64 mentioned, Laravel is setup for you to use storage for your files and run php artisan storage:link to mirror in your public folder. Also, when you utilize the local storage folder, Laravel stores the file in storage/app. Then to delete, you would Storage::disk('local')->delete('file.jpg');. If you can't see the file, make sure the visibility is set to "public". You can set it by Storage::setVisibility('file.jpg', 'public'); Or, you can check it by Storage::getVisibility('file.jpg');.

1 like
icyAdel's avatar

@ejdelmonico in my case i tried in tinker

Storage::delete('storage/images/ndx9CXdHD1oqeQJLhmGeAqosLz6utzEUutIR3WIX.jpg');
= true

It was returning true but the file was still there untouched!

However when i tried to specify the disk, which was set to public, the image got deleted right away:

> Storage::disk('public')->delete('images/ndx9CXdHD1oqeQJLhmGeAqosLz6utzEUutIR3WIX.jpg');
= true

This time it is returning true but with a real result.

AlexanderKim's avatar

@ejdelmonico what's the case for Laravel 5.2?

ln -s storage/app/public public/storage

@lindstrom

my $path var contains = /uploads/image.png. Uploads folder located in public folder.

lindstrom's avatar
Level 15

@heihachi88

Then you would need:

\File::delete(public_path($path));

Forgot about the public_path() helper. At any rate, you need to use the absolute path.

2 likes
ejdelmonico's avatar

@heihachi88 Did you check to make sure the visibility is public? If it is not, everything you try will fail.

1 like
AlexanderKim's avatar

@lindstrom

That worked, bro, thank you. I came from Laravel 4, tried to reuse my code, but that's not the case in L 5.2

@ejdelmonico

Next project i will try to use Storage, looks like a convenient thing.

1 like
lindstrom's avatar

@heihachi88 Cool! Someone suggested using the Storage facade instead. I think it's fine either way. Storage uses the 'local' disk by default and assumes your path is storage_path('app'). You'll also see a public disk with the default path storage_path('app/public') and the docs explain why storing your publicly accessible files here can be a good idea: https://laravel.com/docs/5.2/filesystem#configuration

The tl;dr is that you'll end up wishing you had done it that way to begin with if you start using Envoyer or something similar for deployments.

lindstrom's avatar

@heihachi88 Zero downtime deployments in this case. Specifically, the way Envoyer deals with maintains the files in storage. Check out the link above: "The Public Disk" and see: https://laracasts.com/series/envoyer/episodes/2 as well as what was mentioned up thread about it.

You store everything created or uploaded on your server in storage/app/public and use php artisan storage:link to create a symbolic link from storage/app/public to public/storage. In fact, that would be a web hook you'd run during your deployment.

Envoyer takes the hassle out of managing the symlinking and rotating new deployments. Plus, you can fall back to a previous deployment with a click. If you are doing it manually, the $100/year is worth it for the time it saves you alone.

In terms of maintaining those files across deployments, the only way I see it working out is if you are just syncing over SSH or something. And, that's FINE if this is just a hobby or you're just getting started, but only crazy people do that with apps that make money for them or for the business for which they work.

Anyway, check it out. I use both Forge and Laravel at work. Love them both to pieces.

Please or to participate in this conversation.