Voor een filemanagement heb ik een aantal checkboxen die elk hun eigen value hebben. Deze value is het pad naar het bestand.
Via een anker roep ik de jquery ajax aan die vervolgesn het php script aanroept.



<a href="#download" class="cb_down" title="Download">Download</a>

//  AJAX for Checkbox download		
$(document).on('click' , '.cb_down' , function() { 	
	
          var checkboxes_down = []; 
						
           $('.rafcheckbox').each(function() {   
		if(this.checked) {				
                checkboxes_down.push($(this).val()); 				     	
           }  
        });  
        checkboxes_down = checkboxes_down.toString(); 
		   		   
        $.ajax({  
                url:"", 								
                method:"POST",  
				
                data:{ checkboxes_down:checkboxes_down },  
                success:function(response){ 
														
			// geen response nodig
										
                } 
			
        });  
});


De php:


// Multiple download (checkboxes)
if(isset($_POST["checkboxes_down"])) { 

	// create a tmp folder for the zip file
	$tmpfolder = $MainFolderName.'/tmp';
	if (!is_dir($tmpfolder)) {
		 mkdir($tmpfolder, 0755, true);
	}

	$checkboxfiles = explode("," , $_POST["checkboxes_down"]); 
        $filename = "archive.zip";
	$filepath = $tmpfolder."/";
			
    foreach($checkboxfiles as $checkboxfile) {	
			
	Zip($checkboxfile, $tmpfolder."/archive.zip");	// "Zip" is functie die archive.zip file maakt						
	}

        if(file_exists($tmpfolder.'/archive.zip')){
						
								
		// http headers for zip downloads
		header("Pragma: public");
		header("Expires: 0");
		header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
		header("Cache-Control: public");
		header("Content-Description: File Transfer");
		header("Content-type: application/octet-stream");
			
		header("Content-Disposition: attachment; filename=\"".$filename."\"");
		header("Content-Transfer-Encoding: binary");
		header("Content-Length: ". filesize($filepath.$filename));
						
		while (ob_get_level()) {
			ob_end_clean();
		}
		readfile($filepath.$filename);
		unlink($tmpfolder.'/archive.zip'); // unlink archive.zip			
		rmdir($tmpfolder); // remove tmpdir

		exit;
		
	}
}


Als ik een aantal checkboxen aanvink en op Download klik, wordt de archive.zip gemaakt met alle bestanden erin. Ik heb dit gechecked en dit werkt goed!
Alleen: readfile($filepath.$filename); werkt niet.
Ik heb geen idee waarom ik de .zip niet als download gepresenteerd krijg...
Ik zou niet met base64 gaan lopen klooien (alleen maar overhead). Gewoon een RewriteRule die /prive/plaatjes/whatever.jpg omschrijft naar prive-plaatje.php?id=whatever. Dan kun je inderdaad gewoon rechten controleren, enz. Via een header() geef je dan de juiste Content-Type mee.
Ik heb het nu zo aangepakt:
<?php // Multiple download (checkboxes)
if(isset($_POST["checkboxes_down"])) { 

	// create a tmp folder for the zip file
	$tmpfolder = $MainFolderName.'/tmp';
	if (!is_dir($tmpfolder)) {
		 mkdir($tmpfolder, 0755, true);
	}

	$checkboxfiles = explode("," , $_POST["checkboxes_down"]); 
    $filename = "archive.zip";
	$filepath = $tmpfolder."/";
			
    foreach($checkboxfiles as $checkboxfile) {	
		if( !is_dir($checkboxfile) && count($checkboxfiles)  < 2 )  { // if selected only 1 checkbox and is not folder						
            include('alerts/downloadsingle.php');			
			exit;
		}
		else {		
			Zip($checkboxfile, $tmpfolder."/archive.zip");			
		}
		
	}
	include('alerts/downloadmultiple.php'); 
	exit;
			
}?>


Als 1 checkbox is aangevinkt:(alerts/downloadsingle.php)
<div class="alert alert-success echomessage download" role="alert">
  <span class="closebtn"><i class="fas fa-times echoclose"></i></span>
    <?php echo '<b>' . basename($checkboxfile) . ' </b>ready for download!'; ?> 
	<br />
   <a href="<?php echo $checkboxfile; ?>" class="closebtn downloadsingle btn btn-download" title="Download" download>Download</a>
</div>

Als meerder zijn aangevinkt:(alerts/downloadmultiple.php)
<div class="alert alert-success echomessage download" role="alert">
  <span class="closebtn"><i class="fas fa-times echoclose"></i></span>  
   Multiple files ready for download!
   
   <form  method="post" action="">
		<input type="hidden" name="downloadzip" value="true" />						
		<button type="submit" class="closebtn downloadzip btn btn-download" name="submit_downloadzip">Download</button>
    </form> 
   
</div>

Bij submit multiple gaat ie deze loop in en dan werkt de readfile() wel:

<?php if($_POST['downloadzip']) {
	
		if(file_exists($MainFolderName . '/tmp/archive.zip')){
			$filename = "archive.zip";
			
			// http headers for zip downloads
			header("Pragma: public");
			header("Expires: 0");
			header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
			header("Cache-Control: public");
			header("Content-Description: File Transfer");
			header("Content-type: application/octet-stream");
			header("Content-Disposition: attachment; filename=\"".$filename."\"");
			header("Content-Transfer-Encoding: binary");
			header("Content-Length: ". filesize($MainFolderName . '/tmp/archive.zip'));
						
			while (ob_get_level()) {
				ob_end_clean();
			}
			@readfile($MainFolderName . '/tmp/archive.zip');
			unlink($MainFolderName . '/tmp/archive.zip'); // unlink archive.zip			
			rmdir($MainFolderName . '/tmp'); // remove tmpdir
			exit;
		
		}
		    			    
}?>

Voordeel vind ik van deze wijze: een single download geeft een anker met download, zodat ie ook aangeboden wordt als download.
Bij multiple: ik kan direct na de readfile() de tmp folder leegmaken

Reageren