1

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.

Roduraz
  • 25
  • 1
  • 8
  • Be careful, your `PhpMyAdmin` is a web administration tool for your mysql/mariadb database and has nothing to do with your question. Do you want to store the fully file or just the path to the file in the database? Than do you want to show the pdf file or an image of the pdf file? – UfguFugullu Apr 29 '20 at 06:41
  • No not the file path. I want to store fully file in the database and i want to get the all files from the database like link they will be clickable and when you click on it i want to display the .pdf file. It's going to be like opening a .pdf file in the browser. Scroll down and read it. – Roduraz Apr 29 '20 at 17:45

3 Answers3

1

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.

UfguFugullu
  • 2,107
  • 13
  • 18
  • OK i got your point. What if the number of these files/images in storage or in public folder will increase a lot like 10.000 files/images, will it affect working speed of system/website or sth? – Roduraz May 01 '20 at 22:09
  • In case you want to store a lot of data, you should check if you have enough free webspace. For the performance side you could also think about a cloud solution. For your own storage you should think about a good system how to find a file quickly (e.g. with subfolder structures). See more here: https://stackoverflow.com/questions/2648664/image-upload-storage-strategies – UfguFugullu May 04 '20 at 05:49
0

There is a way worked with me to solve this problem by change the extension of file from pdf to pdfz or any else extension and use this code

$realPath="path file with pdfz extension";

                 if(file_exists($realPath)){
                   $realPath=str_replace(".pdf",".pdfz",$realPath);
                $file =$realPath;
    $filename = $realPath;
    header('Content-type: application/pdf');
    header('Content-Disposition: inline; filename="' . $filename . '"');
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: ' . filesize($file));
    header('Accept-Ranges: bytes');
    @readfile($file);
    exit;
               }else{
    echo "$realPath:No File Exist";

               }

the goal of changing of extension is to protect from force downloading by IDM

khalid J-A
  • 574
  • 1
  • 7
  • 19
  • 1
    Is the file path an internal path? Like App\folder\file.pdfz. I'm getting the file from database and 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? – Roduraz Apr 29 '20 at 18:40
0
$(function() {
let pdfDoc = null,
    pageNum = 1,
    pageRendering = false,
    pageNumPending = null;

const scale = 5.0,
    canvas = document.getElementById('pdf-canvas'),
    pnum = document.getElementById('page-num')
    ctx = canvas.getContext('2d');

/**
 * Get page info from document, resize canvas accordingly, and render page.
 * @param num Page number.
 */
function renderPage(num) {
pageRendering = true;

// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
    const page_viewport = page.getViewport(scale);
    canvas.height = page_viewport.height;
    canvas.width = page_viewport.width;

    // Render PDF page into canvas context
    const renderContext = {
    canvasContext: ctx,
    viewport: page_viewport
    };
    const renderTask = page.render(renderContext);

    // Wait for rendering to finish
    renderTask.promise.then(function() {
    pageRendering = false;
    if (pageNumPending !== null) {
        // New page rendering is pending
        renderPage(pageNumPending);
        pageNumPending = null;
    }
    });
});

// Update page counters
$(pnum).text(num);
}

/**
 * If another page rendering in progress, waits until the rendering is
 * finised. Otherwise, executes rendering immediately.
 */
function queueRenderPage(num) {
if (pageRendering) {
    pageNumPending = num;
} else {
    renderPage(num);
}
}

/**
 * Displays previous page.
 */
$(".carousel-control-prev").click(function() {
if (pageNum > 1) {
    pageNum--;
    queueRenderPage(pageNum);
}
});

/**
 * Displays next page.
 */
$(".carousel-control-next").click(function() {
if (pageNum < pdfDoc.numPages) {
    pageNum++;
    queueRenderPage(pageNum);
}
});

/**
 * Asynchronously downloads PDF.
 */
(function() {
const url = $(canvas).data("file");
pdfjsLib.getDocument(url).then(function(pdfDoc_) {
    pdfDoc = pdfDoc_;
    $("#page-count").text(pdfDoc.numPages);

    // Initial/first page rendering
    renderPage(pageNum);
});
})();
});
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 18 '22 at 14:00