Home › Forums › Back End › php download multiple files problem. › Reply To: php download multiple files problem.
Hi guys and thanks for your help.
Here’s the problem:
My php script will correctly zip and download the image files when the filenames are hard coded (string assigned) in the script. But for some reason when I have my Javascript pass the same filenames to the php script php will only zip compress the files but it won’t do the download.
I guess I’m too new to this stuff to not know what I don’t know.
Checking the values passed from the Javascript seems they are correct.
Ok so here’s my scripts I’m working with:
First is the javascript function, not the full script. I think the javascript function and script are working fine because I’ve checked what it’s sending to the php script and it is the comma delimited picture names such as pic1, pic2.
// I'm pretty sure this javascript function is sending my image names correctly as I've tested it using alert getting the names back from php.
// Format is one string and each image name is comma delimited: pic1,pic2,pic
// selected_Images is a global array which holds the user selected images.
// I've modified some things in this script to post it on the forum.
function downloadImages()
{
var allPicsDownload; allPicsDownload=""; // alert("downloadImages () is running and selected images size is :"+selected_Images.length);
for (var itemCountDownload=0; itemCountDownload < selected_Images.length; itemCountDownload++)
{
if (itemCountDownload < selected_Images.length-1) // length returns the number of items but loop starts at 0 so use -1.
{
allPicsDownload = allPicsDownload+selected_Images[itemCountDownload]+","; // add our delimiter ',' so we can parse in php script.
}
// If itemCountDownload === selected_Images.length then dont add the comma because we're at the last filename.
if (itemCountDownload === selected_Images.length-1) // we are on the last item so dont add the comma.
{ // alert ("counter=last item");
allPicsDownload = allPicsDownload+selected_Images[itemCountDownload];
}
}
var xmlhttpdl;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttpdl=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttpdl=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttpdl.onreadystatechange=function()
{
if (xmlhttpdl.readyState==4 && xmlhttpdl.status==200)
{
// var temp_responsedownload=xmlhttpdl.responseText;
// alert ("php script sent us :"+temp_responsedownload);
}}
}
xmlhttpdl.open("POST","http://www.theZipAndDownloadPhpScriptHere.php",true); // false = wait for reply.
xmlhttpdl.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttpdl.send("files="+allPicsDownload);
}
Script two is the php script which zips then downloads but only when filenames are hard coded into the script. When Javascript passes the filenames to it, the php script only zips with no download.
Why?
<?php
// This script correctly zips then downloads the image files if loaded directly but not when receiving the filenames from my javascript.
$temp_files="pic1.jpg,pic2.jpg"; // Calling the page without the javascript does the zip and download.
// echo "php script received:".$temp_files; // returns correct filenames (no file paths) to the javascript.
if (isset($_POST['files'])) { $temp_files=($_POST['files']); } // If we posted
// json_encode($temp_files); // makes no difference. I think this is only for arrays which I'm not passing. I'm passing a single string.
utf8_encode($temp_files); // makes no difference.
$path="/path/to/images/folder/"; // leave the trailing slash because we will be adding the filename on the end of it to form complete path.
$files_actual=array(); // This array will hold the correct entire file path after we're done building it.
$files_list=explode(",",$temp_files); // now we have our array of filenames but still no paths.
foreach($files_list as $tempfile)
{ // now prepend the path to each filename.
array_push($files_actual,$path.$tempfile); // now the array has the full path and filename.
}
// print_r($files_actual); // correct array of image files paths.
// path to the zip filename we will create.
$zipfile="/path/to/zip/filename/images.zip";
// Call the create zip function and if we're successful download the zipfile named: images.zip.
if (create_zip($files_actual,$zipfile)); // array of files to zip, full path to zip file.
{ // Zip was successfully created so download it now.
$zfiletodownload='images.zip'; //script is located in same directory as zip file, otherwise use full path.
if ($zfiletodownload)
{
// check that it exists and is readable
if (file_exists($zfiletodownload) && is_readable($zfiletodownload))
{
// get the file's size and send the appropriate headers
$size = filesize($zfiletodownload);
header('Content-Type: application/octet-stream');
header('Content-Length: '. $size); // echo "filesize is:".$size;
header('Content-Disposition: attachment; filename=' .$zfiletodownload);
header('Content-Transfer-Encoding: binary');
// open the file in read-only mode
// suppress error messages if the file can't be opened
$dfile = @ fopen($zfiletodownload, 'r');
if ($dfile)
{ fpassthru($dfile);
exit;
}
else
{ header("Location: $error");}
}
else
{ header("Location: $error");
echo "error:dl-1 file does not exist or is not readable!";}
}
}
// creates a compressed zip file
function create_zip($files = array(),$destination = '',$overwrite = true) {
//if the zip file already exists and overwrite is false, return false
if(file_exists($destination) && !$overwrite) { return false; }
//vars
$valid_files = array();
//if files were passed in...
if(is_array($files)) {
//cycle through each file
foreach($files as $file) {
//make sure the file exists
if(file_exists($file)) {
$valid_files[] = $file;
}
}
}
//if we have good files...
if(count($valid_files)) {
//create the archive
$zip = new ZipArchive();
if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}
//add the files
foreach($valid_files as $file) {
$zip->addFile($file,basename($file));
}
//debug
//echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
//close the zip -- done!
$zip->close();
//check to make sure the file exists
return file_exists($destination);
}
else
{
return false;
}
} //END of the create zip function.
?>
What could cause the php script to not work when the filenames are passed from Javascript but the php script does work when hard coded into the script?
Not sure where my bug is yet. Can’t seem to find it or good sources to learn what I’m supposed to be doing.
Would greatly appreciate the solution to this and if you see me doing anything else wrong please point it out!
Thanks.