How do I modify this code so it will save a more meaningful name?

I want to enable people to download PDF files from my web site, instead of viewing them, so I found the following code on EE. It works but the file name it wants to save to is the name of the PHP file (force.php) with a file type of php_auto_file instead of the PDF file I want to download. I would like it to try to save the file as a PDF file with the file name that I have given, i.e MyBrochure.pdf. Can anyone help me change it so it works better?

Following is the basic HTML Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
Download <a href="http://www.mywebsite.com/force.php?file=http://www.mywebsite.com/MyBrochure.pdf">PDF</a>
</body>
</html>

Following is the contents of force.php

<?php
 
      $filename       = $_GET['filename'];
      $path               = $_GET['path'];
      $filepath       = $config[$path]."/".$filename;
      $file_type       = filetype($filepath);
      $filesize       = filesize($filepath);
      
        header("Content-type: ". $file_type);
      header("Content-length: $filesize");
      header("Content-Disposition: attachment; filename=$filename");
 
      $handle       = fopen($filepath, "r");
      $contents       = fread($handle, filesize($filepath));
      fclose($handle);
      echo $contents;
?>
 
LVL 1
Rob4077Asked:
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.

mydropzCommented:
in your download link you only have the get parameter file and you never use it.
you link should look like
 <a href="www.mywebsite.com/force.php?filename=MyBrochure.pdf&path=the/path/to/the/file/">Download</a>

Open in new window


But is it safe and neccesary to put the file path in your link i mean if you keep the files that needs to be download in the same file you could set the path in your script not in your link.

your first header
 header("Content-type: ". $file_type);

Open in new window

should be
 header('Content-type: application/pdf'); 

Open in new window

If you use force.php only for the download of pdf you could put it in your script.
when i check the php manual for the filetype function i see it doesn't return a MIME type and that's what is needed in the Content-type header.

instead of
   $handle       = fopen($filepath, "r");
      $contents       = fread($handle, filesize($filepath));
      fclose($handle);
      echo $contents;

Open in new window


you could simply use
 readfile($filepath/$filename);

Open in new window

and the download dialog will be shown

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
Rob4077Author Commented:
Hi mydropz and thanks so much for your detailed explanation. I know nothing about PHP and little about HTML so your comments have been most helpful but I still can't get it to work so I would appreciate a bit more help.

The error messages I am getting are as follows. I guess I am missing a / somewhere or something simple but after over an hour of trying I still can't figure it out. Is this enough info for you to help me figure it out or do I need to give you the actual web address to be of any value to you?

Also you asked " is it safe and neccesary to put the file path in your link?" Why would that be a problem?

Warning: filetype(): Lstat failed for (null) (errno=2 - No such file or directory) in /u/r/robsue38/force.php on line 6

Warning: filesize(): Stat failed for /InsiteBrochure.pdf (errno=2 - No such file or directory) in /u/r/robsue38/force.php on line 7

Warning: Cannot modify header information - headers already sent by (output started at /u/r/robsue38/force.php:6) in /u/r/robsue38/force.php on line 9

Warning: Cannot modify header information - headers already sent by (output started at /u/r/robsue38/force.php:6) in /u/r/robsue38/force.php on line 10

Warning: Cannot modify header information - headers already sent by (output started at /u/r/robsue38/force.php:6) in /u/r/robsue38/force.php on line 11

Warning: Division by zero in /u/r/robsue38/force.php on line 14



Here is the final code that I have used. I have no idea why it is still not working. The messages coming up are:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>

Download <a href="http://www.mywebsite.com/force.php?filename=InsiteBrochure.pdf&path=http://www.mywebstie.com/subfolder">Download</a>

</body>
</html>

AND


<?php
 
      $filename       = $_GET['filename'];
      $path               = $_GET['path'];
      $filepath       = $config[$path]."/".$filename;
      $file_type       = filetype($filepath);
      $filesize       = filesize($filepath);
      
      header('Content-type: application/pdf');
        header("Content-length: $filesize");
      header("Content-Disposition: attachment; filename=$filename");

 
      readfile($filepath/$filename);
 
?>
 
Ray PaseurCommented:
This will force a download of a file that is named in the URL GET string.

The calling sequence would look something like this:

Download <a href="RAY_force_download_GET.php?u=http://www.mywebsite.com/force.php?file=http://www.mywebsite.com/MyBrochure.pdf">PDF</a>

Is there any reason why you do not want to just give the client a link to the PDFs?
<?php // RAY_force_download_GET.php
error_reporting(E_ALL);

// EXAMPLE OF USAGE
// <a target="_blank"
//    href="RAY_force_download_GET.php?u=http://www.google.com/intl/en_ALL/images/logo.gif">Google Logo</a>



// THE NAME OF THE FILE TO DOWNLOAD IS IN THE URL
$url = $_GET["u"];

// USE CASE
force_download($url);




// FUNCTION TO FORCE A DOWNLOAD FROM A FILE
function force_download($filename)
{
    // TRY TO GET THE CONTENTS OF THE FILE
    $filedata = @file_get_contents($filename);

    // SUCCESS
    if ($filedata)
    {
        // GET A NAME FOR THE FILE
        $basename = basename($filename);

        // THESE HEADERS ARE USED ON ALL BROWSERS
        header("Content-Type: application-x/force-download");
        header("Content-Disposition: attachment; filename=\"$basename\"");
        header("Content-length: ".(string)(strlen($filedata)));
        header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
        header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");

        // THIS HEADER MUST BE OMITTED FOR IE 6+
        if (FALSE === strpos($_SERVER["HTTP_USER_AGENT"], 'MSIE '))
        {
            header("Cache-Control: no-cache, must-revalidate");
        }

        // THIS IS THE LAST HEADER
        header("Pragma: no-cache");

        // FLUSH THE HEADERS TO THE BROWSER
        flush();

        // CAPTURE THE FILE IN THE OUTPUT BUFFERS - WILL BE FLUSHED AT SCRIPT END
        ob_start();
        echo $filedata;
    }

    // FAILURE
    else
    {
        die("ERROR: UNABLE TO OPEN $filename");
    }
}

Open in new window

Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

mydropzCommented:
you have a few error in your script find the right script below
<?php 
 
      $filename       = $_GET['filename'];
      $path               = $_GET['path'];
      $filepath       = $path."/".$filename; // $config['path] is never defined so you cant use it
      $file_type       = filetype($filepath);
      $filesize       = filesize($filepath);
      
      header('Content-type: application/pdf');
        header("Content-length: $filesize");
      header("Content-Disposition: attachment; filename=$filename");

 
      readfile($filepath); // you can use this because the file is already included in the path
 
?>

Open in new window


also the path to the file is not the same as the url to the file your path should be /u/r/robsue38/subfolder

this is based on the path provided in the error statements
Rob4077Author Commented:
Hi mydropz, thanks for the correction and the accompanying explanation.

I am still not sure why you said "is it safe and neccesary to put the file path in your link?" Why would that be a problem? If I put the file name in force.php it makes it harder to find, but not impossible. And is there a risk associated with people knowing the location of files?


Hi Ray_Paseur, thank you for the alternative code. It looks like your code does more processing than my original code but since the code mydropz helped me get working is now working, I am not sure why yours would be better.

In answer to your question: "Is there any reason why you do not want to just give the client a link to the PDFs?" If I do that the PDF opens and displays or they need to right click>Save As to save it. I want to use this on a "downloads" page so I would like people to be able to click on the link to save the brochures rather than look at them.
Ray PaseurCommented:
"your code does more processing" -- yes, there are a panoply of reasons for that.  Each line of code matters, but I do not really have time to explain all of the lines of code.  So please, try the code samples posted here, and especially try them the way a hacker might try them - giving bogus and toxic information to your scripts.  I'm sure you will find answers that are suitable for your applications.  Best of luck with your project, ~Ray
mydropzCommented:
the reason why i said don't use your path in the link is because you don't want to give a starting point to hackers
Rob4077Author Commented:
Thanks to both of you for your help. I am going to share the points because both of you provided a workable solution but most points go to mydropz because you provided the solution first and provided more detailed explanations. Thanks again
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
HTML

From novice to tech pro — start learning today.