Php force download zip file corrupted

Hello everyone.
I’m trying to force a zip-file’s download after some checks ( hash , expiration date, download’s number ) .
The link of the page contains the id ( hash ) to validate the download.
For example:
www.example.com/download.php?id=505fbeabfd97c0ab15a016d68512d8df5acdedd6e6cc6

Everything works, but the file is corrupted.
If I try to eliminate all checks and the connection to the database, the zip downloaded is ok.
Here’s the code:

 <?php
    $maxdownloads = "80";
    // Set the key's viable duration in seconds (86400 seconds = 24 hours)
    $maxtime = "2592000";

    require ('connect.php');

	if(get_magic_quotes_gpc()) {
        $id = stripslashes($_GET['id']);
	}else{
		$id = $_GET['id'];
	}
	echo $id;
	// Get the key, timestamp, and number of downloads from the database
	$query = sprintf("SELECT * FROM digital_orders WHERE hash= '%s'",
	mysqli_real_escape_string($conn,$id));
	$result = $conn->query($query);
	
	$row = $result->fetch_assoc();
	if (!$row) { 
		echo "The download key you are using is invalid.";
	}else{
		$timecheck = date('U') - $row['date'];
		echo $timecheck;
		
		if ($timecheck >= $maxtime) {
			echo "This key has expired (exceeded time allotted).<br />";
		}else{
			$downloads = $row['download'];
			echo $downloads;
			$downloads += 1;
			if ($downloads > $maxdownloads) {
				echo "This key has expired (exceeded allowed downloads<br/>";
			}else{
			$sql = sprintf("UPDATE digital_orders SET download .$downloads."' WHERE hash= '%s'",
	 mysqli_real_escape_string($conn,$id));
				
				$incrementdownloads = $conn->query($sql);
				$result->close();
				
				// chiusura della connessione
				$conn->close();
    // Debug		echo "Key validated.";

    // Force the browser to start the download automatically

    /*
	Variables: 
		$file = real name of actual download file on the server
		$filename = new name of local download file - this is what the   visitor's file will actually be called when he/she saves it
    */

      // Get parameters
  	
      $file = "dante.zip"; // Decode URL-encoded string
      $filename = "foto.zip";	
      $filepath = "digital_orders/Dante/" . $file;
  
	  
      // Process download

     if(file_exists($filepath)) {
          ob_start();

	  header('Content-Description: File Transfer');	
	  header('Content-Type: application/octet-stream');	
	  header('Content-Disposition: attachment; filename="'.$filename.'"');	
	  header('Expires: 0');	
	  header('Cache-Control: must-revalidate');	
	  header('Pragma: public');	
	  header('Content-Length: ' . filesize($filepath));	
	  flush(); // Flush system output buffer
	  ob_end_clean();
	  readfile($filepath);

	  exit;	
      }
			}
		}
	}
    ?>

If I try to open the zip file that works with note-pad there is :

PK
     ûe‹L            	   dante.txtPK 
     ûe‹L            	 $               dante.txt
         CdÔ‹‚ÑÓCdÔ‹‚ÑÓÆ‹‚ÑÓPK      [  

 '     

If I try to open the corrupted zip file there is:

 505fbeabfd97c0ab15a016d68512d8df5acdedd6e6cc61226822PK
     ûe‹L            	   dante.txtPK 
     ûe‹L            	 $               dante.txt
         CdÔ‹‚ÑÓCdÔ‹‚ÑÓÆ‹‚ÑÓPK      [ 

Any suggestion?

The issue suggests something in the headers is incorrect - rather like when you download a binary file from an FTP server in ASCII mode and it does CR/LF translation when you didn’t want it to. A quick google suggests that these headers might be appropriate:

header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($file));

Ty , but it doesn’t work.

SOLVED
I’m not sure to understand everything, anyway putting together tips from different discussion I was able to work it out.
I added:

ob_start();

at the beginning and :

           $strFile = file_get_contents($filepath);			

	  header("Content-type: application/force-download");
	  header('Content-Disposition: attachment; filename="'.$filename.'"');	
	  
	  header('Content-Length: ' . filesize($filepath));	
	  echo $strFile;
	  while (ob_get_level()) {
		ob_end_clean();
	  }
	  readfile($filepath);	 
		exit;

at the end.

2 Likes

thanks very much I try every code thats forcefully download the files but none of them work but your code is perfect an work great thankyou for your piece of code.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.