skip to Main Content

Using php’s ability to call upon the browser to display a given PDF it doesn’t work on my web host. But it works on my local xamp server with apache.

PHP:

    $title = $_GET['title'];
    $loc = $_GET['loc'];

    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=".$title);
    @readfile($loc);

Expected Output: Supposed to be the PDF document being rendered like it does on my local web server.

Actual but unwanted output:
%PDF-1.6 %���� 1638 0 obj <> endobj xref 1638 44 0000000016 00000 n …

Can be seen here:
http://neilau.me/view.php?title=business-studies-hsc-notes-2006.pdf&loc=pdf/criteria/business-studies/2006/business-studies-hsc-notes-2006.pdf

Is this fixed through changing something on my cpanel? As my code isn’t faulty… It works on my local web server.

2

Answers


  1. Use this code

    <?php
    $file = 'dummy.pdf';
    $filename = 'dummy.pdf';
    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);
    ?>
    
    Login or Signup to reply.
  2. You need to make sure you are not sending any text before writing headers.

    Example of what not to do:

    <!DOCTYPE html>
    <html>
    ...
    <?php
    header("Content-type: application/pdf");
    

    Example of how to fix that:

    <?php
    header("Content-type: application/pdf");    
    ?>   
    <!DOCTYPE html>
    <html>
    ...
    

    In addition your script is very insecure. Here’s what you should do, your entire PHP script should be:

    <?php
    $loc = filter_input(INPUT_GET,"loc");
    $title = filter_input(INPUT_GET,'title')?:basename($loc);
    if (!is_readable($loc)) {
        http_response_code(404);
        echo "Cannot find that file";
        die();
    }
    if (strtolower(pathInfo($loc,PATHINFO_EXTENSION)) != "pdf") {
       http_response_code(403);
        echo "You are not allowed access to that file";
        die();
    }
    
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=".$title);
    header("Content-Length: ".filesize($loc));
    readfile($loc);
    

    If you want to show things like a page title or a frame around it, you should use an iframe in another “wrapper” page:

    <?php 
    $loc = filter_input(INPUT_GET,"loc");
    $title = filter_input(INPUT_GET,'title')?:basename($loc);
    ?>
    <html><head><title>My title</title></head>
    <body>
    <iframe src="/view.php?<?php echo ($loc?"loc=$loc":"").($title?"title=$title":"") ?>">
    </iframe>
    </body>
    <html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search