jordano1's avatar

Download a file from the database

I have a FileController, a file.blade.php and 3 routes.

3 routes:

//this is running a method to store my files that I've uploaded
Route::post('/file-upload/', 'FilesController@store'); 

//this is returning the file-upload page with the files laid out in a foreachloop
Route::get('/file-upload/', 'FilesController@index'); 

//this route will fire when the user clicks to download a file on the file-upload page
Route::get('/file-upload/download/{file}', 'FilesController@download');

uploading a file will trigger this method:

public function store(Request $request)
     {
  
        $files = Files::all();
        if($request->hasFile('file') && $request->file('file')->isValid()){
            //
            //storing the input field with the name "file" in $file.
            $file = $request->file('file');
            //using laravel method to get filename from the inputfield, in case we add a feature to allow the user to provide the name
            $originalName = $file->getClientOriginalName();

            //storing file in public/upload saving as $originalName
            $fileLoc =  $request->file->storeAs('public/upload', $originalName);
            //getting mimetype from the file stored with the class storage using method mimetype of the file above
            $mimeType = Storage::mimeType($fileLoc);

            //creating a new file entry
            $entry = new Files();
            //storing mimetype of file
            $entry->mime = $mimeType;
            //storing filename of file
            $entry->original_filename =  $originalName;
            //storing name as ogname, but may change to allow users to name file
            $entry->name = $originalName;
            //saving and making entry to the DB
            $entry->save();

        }else{
            //if statement checks if file is a file and is valid, otherwise no file to upload
            return "Failed to upload";

        }
        return back(); compact('files');
    }

When a user clicks on a file they uploaded:

public function download($file)
    {
      $url = Storage::url($file);


        $download=DB::table('files')->get();
        return Storage::download($url);
        // view("files.download", compact('$download'));
    }

I have confirmed via sequel pro that this works, the entry is recorded in the database, in the public/upload directory in public/storage/upload/(filesstoredhere), and displayed in the view.

the view file.blade.php (relevance to question, took out elements not applicable to issue):

<form method="POST" action="/file-upload/" >
    <input id="input-fa" name="file" type="file" class="validate" enctype="multipart/form-data">
</form>

<div class="col-sm">
    <a href="file-upload/download/{{$file->name}}" download="{{$file->name}}">
        <button type="button" class="btn btn-primary"><i class="glyphicon glyphicon-download">download</i></button>
        </a>
</div>

I'm not sure if I should be using in the href element the "download" property with the $file->name. This seems to download the file, but it will say that the file "filename.jpg" could not be opened because it is empty.

I tried using the download function but I just get the error:

(1/1) BadMethodCallException
Call to undefined method League\Flysystem\Filesystem::download

Any help would be appreciated, if you need more info let me know.

Thanks!

0 likes
8 replies
bobbybouwmann's avatar

The Filesystem class does not have a download method like the errors suggests. Instead you need to respond with a download response. Something like this

public function download($file)
{
    return response()->download(storage_path('path_to_your_file'));
}
1 like
jordano1's avatar

Hey Bob, thanks for the response. When I put the path into my file it says the file doesn't exist, so I'm wondering if I'm doing this wrong and how to do it correctly

in my download function:

    public function download($file)
    {
        $url = Storage::url($file);


        $download=DB::table('files')->get();
        return response()->download("storage/app/upload$url");
        // view("files.download", compact('$download'));
    }

I'm getting errors that the file doesn't exist, how would I get the path to my file? I tried putting the $url var in but it just gives me another error.

I would assume that means I got the path incorrect, but I'm not sure.

(1/1) FileNotFoundException
The file "/storage/East Coast Defender-loop.jpg" does not exist

I have also done things like:

        return response()->download("$url");

and

        return response()->download("/storage/app/upload/$url");

which the files are in storage/app/upload

1 like
shez1983's avatar

try

return response()->downloadDownload($url)

one thing puzzling me is the PUBLIC folder? is there really a public folder in your STORAGE folder or are you trying to download it to public/folder in root (where all assets go after you run gulp/webpack?)

jordano1's avatar

There is a temporary folder that is storing the files I'm uploading, I may have said in a weird way, it's in the public folder. So in my public folder I have storage/upload directories and in upload is where the files are being stored currently.

Also Shez1983 that code you asked me to try is not working, did you mean just to do:

return response()->Download($url);

That still came back with the same error.

bobbybouwmann's avatar

You need to use the full path of the server. That's why you use storage_path because that will point to something like /var/www/your-projects/storage. If you use that method it will always grab the correct path. So in your case

return response()->download(storage_path('app/upload/' . $url));
1 like
jordano1's avatar
jordano1
OP
Best Answer
Level 2

I don't think I originally understood bobby's response, but he did help me get to an answer, ultimately I simplified my storeAs method in filescontroller to:

            $fileLoc =  $request->file->storeAs('/upload/', $originalName);

and then made sure my download method was properly going to the files path:

    public function download($file)
    {
      return response()->download(storage_path("app/upload/{$file}"));
        // view("files.download", compact('$download'));
    }

Once I did this, I was able to get the files downloaded that were stored.

Thanks.

3 likes
komal27's avatar

The file "D:\xampp\htdocs\ca-laravel-master\storage\app\upload{36}" does not exist I am getting this error why?

Please or to participate in this conversation.