Search code examples
phplaravelpdfblob

Displaying .pdf file in browser with PHP in Laravel 7 using RESTful Controller


I'm working on a laravel project and inside the project i store .pdf files to my local phpmyadmin and retrieve it back to display in the browser.

I see some applications but they're saving the .pdf files locally while uploading it to DB. And then it becomes so easy to display with <img src=""> but i don't want to use this.

These are my routes;

Route::get('/users/{user}/posts', 'PostController@index');
Route::get('/posts/create', 'PostController@create');
Route::post('/posts', 'PostController@store');

And index function;

public function index(User $user, Post $posts)
    {
        $posts = DB::table('posts')
                        ->where('userId', '=', $user->id)
                        ->get();

        return view('post.index', compact('posts'));
    }

I can upload and store .pdf files that OK but cannot display in the browser. So I want to get the record with index function in PostController(which is done already) and display the .pdf file in index.blade.php file which comes from db. like this: http://localhost/test.pdf When i display it in the browser i can see only it's name. How can i read the file that i get it from db?

Thank you for your answers.


Solution

  • First of all, in my opinion, you should store the files into the storage system of laravel and not in the database.

    But if you want to do it with the database here is an example to output a file which is stored into a blob field of the database (for example in the content field of the files table).

    Another not-so-pretty method is to convert the file into a base64 string and store in a text field, see more here.

    Schema for 'db_files' table

    field     | type
    ----------|-------------
    id        | BIGINT
    name      | VARCHAR(255)
    content   | BLOB
    mime_type | VARCHAR(255)
    

    Routes

    Route::get('/files/{id}', 'FileController@show')->name('file.show');
    

    DbFile Model

    use Illuminate\Database\Eloquent\Model;
    
    class DbFile extends Model {
        // ...
    }
    

    FileController

    public function show($id) {
        $dbFile = DbFile::firstOrFail($id);
    
        // the $dbFile->mime_type should be 'application/pdf' for pdf files
        // the $dbFile->name should be in this schema 'document.pdf'
        return response($dbFile->content)
            ->withHeaders([
                'Content-type: ' . $dbFile->mime_type,
                'Content-Disposition: attachment; filename=' . $dbFile->name
            ]);
    }
    

    View

    <a href="{{ route('file.show', ['id' => 1]) }}" target="_blank">Show Document</a>
    

    I can't test the code right now. Let me know if something goes wrong.