Display database blog field as pdf in browser

Can you create a pdf file & then "save" it as a blob type in a MySQL database?

I use FPDF; one output option is a string, which I could then save as the blob.

But then (later) when a user clicks a button (now it's a submit, could be ahref=), how can I read the blob & open it in a new window where the blob is just the pdf)
Richard KortsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Chris StanyonWebDevCommented:
Technically, yes you can but personally, I'd store the PDF in a folder on your server, and then just store the path to the file in the DB. Much easier to manage
0
Richard KortsAuthor Commented:
Chris,

Glad you chimed in.

That is exactly what we do now.

See this question.

https://www.experts-exchange.com/questions/29116773/Delete-pdf-file-after-opening-using-Javascript-in-another-window.html#a42674686

The essence of the problem is we are trying to NOT display that message shown near the the beginning; it will confuse our users.

I also thought of saving the PDF as a string (one of the options), encode that string & store in the a new differently named folder.

Then when the user clicks "Print", read that file, decodes & open in a new browser window.

Will that work?

Richard
0
Chris StanyonWebDevCommented:
OK. Just to clarify a couple of points. The reason you want to do this is to protect the files from unauthorized access (currently a password protected folder). You also want to prevent Google from indexing the files?

If that's correct, there are better ways to do this.

Basically, you'd store the files outside of your web root (i.e. above the public_html folder). This would protect them from access and indexing. You could then deliver the relevant PDF file with a simple PHP script. This would give you controlled access to the files, there would only be one copy of the file (so no delete /clean up) and your DB would remain clear of the extra overhead that a BLOB fileld would bring.
0
10 Tips to Protect Your Business from Ransomware

Did you know that ransomware is the most widespread, destructive malware in the world today? It accounts for 39% of all security breaches, with ransomware gangsters projected to make $11.5B in profits from online extortion by 2019.

Richard KortsAuthor Commented:
When you say "Google  from indexing the files", the customer's concern is he put in a search of a specific text string that was in one of the files. Will this prevent that?

So I put a folder on the same level as public_html. How do I write to / read from that folder? I think I have done that before, I can't remember how. Can you advise? Don't I give it a relative path or ??

Thanks,

Richard
0
Chris StanyonWebDevCommented:
Will this prevent that?

Yes. Basically, instead of the address to the pdf being www.youdomain.com/somefile.pdf, you would code a simple PHP script to retrieve that file, so you access it with something like www.yourdomain.com/getpdf.php?fileid=1. You can then add various levels of protection inside this script (such as session variables). Anyone accessing the url without the correct session (such as Googlebot / unauthorised users etc) could simply get a message or a redirect instead of the file

It's only the front-end (website etc that is limited to the public folder (the web root). Server scripts generally have access to the users home folder, so you can access any folder under that (normally public is a sub folder of home ). When reading and writing files, you can either use relative (to your script) paths or absolute (to your home folder) paths.

RELATIVE
./myfile.pdf => same folder as your script
../myfile.pdf => one folder up from your script
../../myfile.pdf => two folders up from your script

ABSOLUTE
/myfile.pdf => root folder of the user
/pds/myfile.pdf => stored in the pdfs subfolder
0
Richard KortsAuthor Commented:
So if I created a folder at the same level as public_html, say called summsp, I would reference a file from php as ../summsp/myfile.pdf.

Either to read from or write to.

Correct?

PS - if this solves the problem, I want to award you the points for both this AND the original one that you did not respond to. Not sure how to do that.

Richard
0
Chris StanyonWebDevCommented:
Correct :)

Assume a file structure like this:

/
    summsp/
        myfile.pdf
    public_html/
        index.php
        myscript.php      

In myscript.php, you can read and write to ../summsp/myfile.pdf

To the outside world (web users / googlebot etc), the highest level they can see and access is public_html, but your myscript.php can see all the way up to the root - /

If you don't get any joy on the other question, ping me a message and I'll comment on that. That question was pretty much answered here ... and we kind of side-stepped this questions original topic completely ;)
0
Richard KortsAuthor Commented:
I don't think we side stepped it, the others that answered basically did not see the problem in it's true depth.

Richard
0
Richard KortsAuthor Commented:
Filezilla will not allow me to create a directory on the server at the same level as they (the host) may have blocked that.

I emailed them asking them to do that (about an hour ago), they have not yet responded, they are normally VERY quickly responsive, that's ONE of the reasons I use them. It's https://www.chihost.com/.

Can you think of why they might disallow that?

Thanks,

Richard
0
Richard KortsAuthor Commented:
Never mind, they just created it.

Richard
0
Richard KortsAuthor Commented:
There is still a problem. When I tried to read the file, I get a 404 error. I put in "../summsp/filename.pdf". The 404 error showed the url of https://www.mysite.com/summsp/filename.pdf.

I emailed the host, their response:

It has to be in public_html to read in a browser.

So I'm back to square zero.

Your thoughts?

Richard
0
Chris StanyonWebDevCommented:
OK. The idea is that the files you want to display (the PDFs) live in a folder outside of public_html, so they are not directly accessible in the browser. In order for the user to get at those files, they will need to access them through a script. For example, let's assume the script is called file.php. Because the file info is stored in a database (id / filename), the user will need to pass in the id of the file (1,2,3 etc) and to access the file, they would type something like the the following:

www.yourdomain.com/file.php?id=1

Now, the file.php script would query the DB to retrieve the filename of the record with an ID of 1. Once it's got the filename (myfile.pdf) for example, it would read that file in from the ../summsp/ folder (the server-side script can read from this folder), and deliver it to the user by using the header() function. Effectively the file.php script is acting as a delivery mechanism for the file - the user asks for a file by id and the script retrieves it and delivers it. At no point does the user have direct access to the file, or even know the filename on the server.

Here's an example of the file.php script using PDO for DB access.

<?php
// Define the file storage location
define('STORAGE', '../summsp/');

// We're gonna need an ID
$fileId = isset($_GET['id']) ? $_GET['id'] : 0;

// Connect to the DB
require_once 'db.php';

try {

    // Query the DB
    $files = $db->prepare('SELECT filename FROM yourTable WHERE id = :id LIMIT 1');
    $files->execute(array('id' => $fileId));

    // Check if we have a record
    if ( ! $file = $files->fetchColumn() ) {
        http_response_code(404);
        die('Nope!');
    }

    // Get the file location
    $source = STORAGE . $file;

    // Check if the file exists
    if ( ! file_exists($source) ) {
        http_response_code(404);
        die('Nope!');
    }

    // Load the file into memory
    $content = file_get_contents($source);

    // Setup the headers
    header('Content-Type: application/pdf');
    header('Content-Disposition: inline; filename="summary.pdf"');
    header('Cache-Control: private, max-age=0, must-revalidate');

    // Send it to the browser
    die($content);

} catch (Exception $e) {
    die($e->getMessage());
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Richard KortsAuthor Commented:
Oh, I see. So I store the ID in the database & the file name. Fortunately, every file already has a unique ID (each "visit" is assigned a new ID). The ID is also part of the file, I think I see how this can work.

EXCEPT for one thing. I want the pdf to open in a NEW browser window and the existing window (called summary,php), remains in a browser tab.

Richard
0
Chris StanyonWebDevCommented:
Hey Richard. I don't know how you already have things set up, or how the users currently interact with your site, but hopefully you can adapt the ideas here to your current setup. For all your existing files, you can probably just loop through them all (do a directoy loop in PHP) and insert the name into the database.

The general principle is that when a file is generated (I'm guessing by some user interaction), the PDF file is created and stored in the new high-level folder. A record is inserted into the database containing the filename you've given it, and an auto-increment ID value is retreived from the INSERT. The user can then view that file by visiting a link to file.php?id=xx where xx is the auto ID. You can at this point set a SESSION variable so that only the current user can view the file.

If you give the user the link to click on, then you can open a new tab by adding target="_blank" to the anchor.

<a href="file.php?id=123" target="_blank">Click here to view your file</a>

If you want to open the file in a new tab with Javascript, then just use:

window.open('file.php?id=123', '_blank');
0
Richard KortsAuthor Commented:
Yes, I think anchor with target="_blank" will work.

I'll try it out.

Thanks for ALL your help.

Richard
0
Richard KortsAuthor Commented:
Works like a charm!!

There is really no need for the database, it just saves it there if we need it for future reference. But it's also in the summsp directory not under public_html, I can copy new ones at any time.

Richard

How can I award you the points for the other one too?
0
Chris StanyonWebDevCommented:
Hey Richard,

That's great.

If your files are always named in a given way and you can extract the ID out to match the GET['id'], then you could do it without the DB. With a DB it would be easier to tie a file to a user, but that'll depend on your application.

Don't forget to implement some kind of session check, otherwise anyone can see a file by simply visiting file.php?id=xx. How you implement it will depend largely on how you currently give access to a user.

You can't award me points on the other question because I haven't made any contribution (directly) to it!
0
Richard KortsAuthor Commented:
Good point (about the security). I will check a session var there to ensure user is logged in.

Richard

But on the other question, in my opinion, the others did not understand the issue thoroughly. So no points. but EE tries to force me to close, I can choose found my own solution, then they make me explain now.

If it wasn't for EXCELLENT people like you and a lot of others, EE is becoming too full of rules & bureaucracy. I understand some of their intent, but to be honest, I do not yet know if I am awarding points correctly. Did you get full points for this question? I have no way of knowing. Which is absurd!!

The prior method was MUCH simpler & more intuitive.
0
Chris StanyonWebDevCommented:
Regarding security, you will need to limit the files a user can access otherwise any logged in user can access any file (maybe that's OK!).

You're not the first to comment on the new points system. EE is constantly evolving, and it doesn't always feel like the right direction. I don't tend to ask questions these days so I don't actually know how the system works regarding accepting answers and awarding points, but it does seem to be more complicated that it used to be.

I did get the points for this questions ... thanks :)

I've commented on your other question as well.
0
Richard KortsAuthor Commented:
I complained to EE about the new system (maybe 4  week ago), they basically poo-pooed me off.

I told them change is good if it makes it a better experience in some way from the CUSTOMER's perspective. Change just for change, not so much. That is of course the mantra of many businesses, restaurants, for example.

Richard
0
Richard KortsAuthor Commented:
I uses $_SESSION variables, for the user for one thing. Only the user logged in into THIS session will have access.

Richard
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PDF

From novice to tech pro — start learning today.