How to force download of a .php file instead of execute it on server?

Hello,

I have a .php file that I want my website visitors to be able to download. (It’s an example.php file.)

How can I set the link to example.php so it downloads as a file they can “save” instead of executing on the server?

(I hope that makes sense.)

I’ve though about renaming the file to “example.txt”, but that could be complicated, and it still doesn’t allow them to save without first selecting/pasting, etc.

Thanks!


function forceDownLoad($filename)
{

	header("Pragma: public");
	header("Expires: 0"); // set expiration time
	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
	header("Content-Type: application/force-download");
	header("Content-Type: application/octet-stream");
	header("Content-Type: application/download");
	header("Content-Disposition: attachment; filename=".basename($filename).";");
	header("Content-Transfer-Encoding: binary");
	header("Content-Length: ".filesize($filename));
	
	@readfile($filename);
	exit(0);
}

I tried this code, but it is still just outputing the example.php file to the screen. (Server is not executing it, but the download box is not appearing.)

Any ideas?

Whoops… .nevermind. I cleared my browser cache and now it’s working.

Thanks!

if you want to know more about please http://www.php.net/header

just for reference - the function posted above works great. however it does not ask you if you wish to download the file, it just does it. i changed the function a little bit to download vcards, and ask the user what they want to do first.


//grab stuff from url
$filename = "http://www.domain.com/vcards/".$_GET['file'];
forceDownLoad($filename);

function forceDownLoad($filename)

{



    header("Pragma: public");

    header("Expires: 0"); // set expiration time

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
	
	header("Content-Type: application/text/x-vCard");



    header("Content-Disposition: attachment; filename=".basename($filename).";");

    header("Content-Transfer-Encoding: binary");

    header("Content-Length: ".filesize($filename));



    @readfile($filename);

    exit(0);

}

If the filename will be passed via url(or in any way come from the user), you need to make sure you do some strict validation before you use it with any filesystem functions. Otherwise you will introduce a severe security vulnerability(reading of unintended files, sending the server into an endless loop etc…).

You can read more about directory traversal by searching.

Ideally, you have a list of allowed files, and the script will deny any other requests.