Vad gör jag för fel i detta PHP download-script?

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1

Jaha, så har man börjat lära sig PHP också, och jag håller då på att följa en tutorial för hur man skapar en download-länk, dvs en länk där filen laddas ner till användarens disk, istället för att öppnas i Browsern.

Filen laddas ner alright, men problemet är att den på något sätt blir skadad och sen inte kan öppnas. Filstorleken blir riktigt satt så det verkar inte vara det heller

Såhär ser scriptet ut

<?php
// block any attempt to explore the filesystem
if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file']) {
$getfile = $_GET['file'];
}
else {  $getfile = NULL;
}
// define error handling
$nogo = 'Sorry, download unavailable. <a href="prompt.php">Back</a>.';

if (!$getfile) {
  // go no further if filename not set
  echo $nogo;
  }
else {
  // define the pathname to the file
  $filepath = '/'.$getfile;
  // check that it exists and is readable
  if (file_exists($filepath) && is_readable($filepath)) {
    // get the file's size and send the appropriate headers
    $size = filesize($filepath);
    echo $size;
    header('Content-Type: "application/force-download"');
    header('Content-Length: '.$size);
    header('Content-Disposition: attachment; filename='.$getfile);
    header('Content-Transfer-Encoding: binary');
	// open the file in binary read-only mode
	// suppress error messages if the file can't be opened
    $file = @ fopen($filepath, 'rb');
    if ($file) {
	  // stream the file and exit the script when complete
      fpassthru($file);
      exit;
      }
	else {
	  echo $nogo;
	  }
	}
  else {
    echo $nogo;
	}
  }
?>

Get-parametern "file" innehåller filnamnet och den är placerad direkt på root-nivån på disken, alltså, filen hittas osv, men ändå blir något fel - vad kan det vara?

  • Medlem
  • Mölndal
  • 2007-04-12 18:22

Vad är det där för konstig content type!? application/force-download?

Är det en binärfil kan du använda "application/octet-stream"

Att filen ska sparas ner avgörs istället mha Content-Disposition, som mycket riktigt är satt till 'attachment'. Det andra möjliga värdet är 'inline'.

Content-Transfer-Encoding har jag aldrig sett/användas i såna här sammanhang (däremot i mail). Plocka bort den.

Hmm... den där content-typen hittade jag när jag googlade och försökte hitta liknande lösningar, men det är inte den som gör det för det var application/octet-stream från början

Content transfer encoding påverkar inte heller resultatet - det funkar ändå inte

  • Medlem
  • 2007-04-12 19:23

Hm, har en gammal kodsnutt som gör ungefär samma sak enligt nedan;

header('Content-type: application/octet-stream');
header("Content-Disposition: inline; filename=\"".$filename."\"");
header('Content-length: ' . (string)(filesize($filepath)));

Anledningen till "inline" är att någon webbläsare kraschade med "attachment"... Den ska dock laddas ner ändå.

Tack för förslagen, men tyvärr hjälper de inte. Jag har hittat ett snarlikt script, på

http://www.zubrag.com/downloads/download.zip

som funkar alldeles utmärkt, men det kräver att mime-type anges för varje filtyp, och saken är den att som jag hade tänkt använda den så kan det röra sig om vilken filtyp som helst.

  • Medlem
  • Mölndal
  • 2007-04-12 20:31

En content type som signalerar binärfil brukar ju funka för de allra flesta filtyper (det finns ju inte så himla många sätt att överföra datat).

Vad är det för fil du provar med att skicka? Om du hittar en content type som funkar för den, fungerar den då inte även för övriga filtyper?

Jag hittade felet, på sätt och vis, till slut. Medan jag felsökte hade jag infogat en massa echo - och det får man absolut inte göra, det blir då en del av filen som överförs - vilket gör den obrukbar.

Men det var något annat fel, vad vet jag inte, så det slutade med att jag fick skriva om den från grunden, enligt samma princip, men bara för att få bort felen. Såhär blev det till slut:

<?php
if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file']) {
$myFileName = $_GET['file'];
}
else {  $myFileName = NULL;
}

$myErrorMsg = 'Sorry, download unavailable. <a href="prompt.php">Back</a>.';

if (!$myFileName) {
  echo $myErrorMsg;
  }
else {
	$myBaseFolder="/";
	$myCompleteFilePath = $myBaseFolder.$myFileName;
 
	if (file_exists($myCompleteFilePath) && is_readable($myCompleteFilePath)) {

		$myFileObject = fopen($myCompleteFilePath, 'rb');
		// send the right headers
		header("Content-Type: application/octet-stream");
		header("Content-Length: " . filesize($myCompleteFilePath));
		header('Content-Disposition: attachment; filename='.$myFileName);
		header('Content-Transfer-Encoding: binary');
		fpassthru($myFileObject);
		exit;
		}
	else {
	  echo $myErrorMsg;
	  }
}
?>
1
Bevaka tråden