I am trying to compress some video files on the fly using php and forcing compressed file to download. Below is the code I have written.
$files_todownload_string = ' movie1.mov movie2.mov '
header('Content-Type: application/x-gzip');
header('Content-Type: application/octet-stream');
header('Content-disposition: attachment; filename="file.zip"');
header( 'Content-Transfer-Encoding: binary' );
$fp = popen('zip -v - ' . $files_todownload_string, 'r');
$bufsize = 8192;
$buff = '';
while( !feof($fp) ) {
$buff = fread($fp, $bufsize);
echo $buff;
print "
";
}
pclose($fp);
The compression is done perfectly and the zip file is downloaded successfully. However, when I am trying to open the zip file in windows os, it won't open. It says that the compressed file is corrupted.
Any helps guys? Thanks in advance.
Remove print "
";
You're adding extra bytes.
I found this solution. The zipped files are working in all OS Linux, Windows and Mac.
Below is code:
$files_array = array();
$files_array[] = 'file1.mov';
$files_array[] = 'file2.mov';
$file = tempnam("tmp", "zip");
$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
foreach($files_array as $k => $v) {
$zip->addFile( $path.$files_available[$v] );
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
header( 'Content-Transfer-Encoding: binary' );
ob_end_clean();
readfile($file);
Thanks everybody for giving the time.
Related
I have this php function:
function get_partij_download_new($dbmi, $partij) {
set_time_limit(0);
$stmt = $dbmi->prepare("CALL spStartPartijDownload(?)");
$stmt->bind_param('i', $partij);
$stmt->execute();
$result = $stmt->get_result();
$headers = array('id', 'zorgverlener', 'zorgverlener_type', 'jaar', 'id_contractpartij', 'contractpartij',
'dc_code', 'dc_oms', 'tt_oms', 'zp_code', 'zp_oms', 'zpg_oms', 'tarief');
$fp = fopen('php://temp/maxmemory:999999999999', 'w');
if ($fp && $result) {
$zipname = 'export_tarvieven_contractpartij.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
fputcsv($fp, $headers, ";");
while($row = $result->fetch_assoc()) {
fputcsv($fp, $row, ";");
}
rewind($fp);
$zip->addFromString('export_tarieven.csv', stream_get_contents($fp) );
fclose($fp);
$zip->close();
}
$stmt->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname);
}
When I run this on my localhost (xampp version 5.6.19) it works OK and gives me a zip that contains the expected csv file. When I run the exact same function on the production server (php version >7) it still creates the zip file but the zip doesn't contain the csv, it's empty..
Any thoughts?
It can be a memory problem. Try to use php://temp without maxmemory:
$fp = fopen('php://temp', 'w');
I have a wav stream(not file) in php that comes from another server. When i want to save the stream as wav file. It does not play, the file is corrupted. Can anybody help me? The code is:
$file = "/var/www/sounds/soundFile.wav";
$handle = fopen($file, 'wb')
or die('Cannot create sound file: ' . $file);
//stream_set_write_buffer($handle, 0);
fwrite($handle, $soundResult );
fclose($handle);
I'm not sure of what you want to do, but ... Here is may-be what you're looking for :
//send file contents
$handle=fopen(dirname(__FILE__) . "/var/www/sounds/soundFile.wav", "rb");
header("Content-type: application/octet-stream");
header('Content-disposition: attachment; filename="test.wav"');
header("Content-transfer-encoding: binary");
header("Content-length: ".filesize(dirname(__FILE__) . "/var/www/sounds/soundFile.wav")." ");
fpassthru($handle);
fclose($handle);
I use this code to create ZIP file from PHP
ZIP is correctly created, but I have a little trouble when download zip.
On browser, ZIP name appear like this
.._.._storage_temp_2013-09-03-1378245354.zip
I'm like to mantain only
2013-09-03-1378245354.zip
Here code I use:
$files = array($frente, $verso);
//$zipname = '../../storage/file.zip';
$zipname = "../../storage/temp/".date('Y-m-d')."-".time().".zip"; // Zip name
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$new_filename = substr($file,strrpos($file,'/') + 1);
$zip->addFile($file,$new_filename);
//$zip->addFromString(basename($file), file_get_contents($file));
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
ob_clean();
flush();
readfile($zipname)
I have solved in this way:
$new_zipname = substr($zipname,strrpos($zipname,'/') + 1);
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$new_zipname);
I have gotten a problem about downloading .jpg and .avi files from a server using PHP
I have the following code:
$fileName = "Koala.jpg";
$filePath = "./Koala.jpg";
if (!file_exists($filePath)){
echo "No file";
return;
}
$fp = fopen($filePath, "r");
$fileSize = filesize($filePath);
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Length: $fileSize");
header("Content-Disposition: attachment;filename=".$fileName);
$buffer = 1024;
while(!feof($fp)){
$data = fread($fp, $fileSize);
echo $data;
}
fclose($fp);
The code downloads .txt file successfully and the downloaded file can be read.
However, when it comes to .jpg, the downloaded .jpg file cannot be read.
Can anyone give a helping hand? Thanks
Have just tried another method and it works fine
$file = 'Koala.jpg';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
But just wonder what reason causes the first method fail, even though using fopen("xxx", "rb") instead. Thank you
Try replacing application/octet-stream for image/jpeg .
Regards
I'm no php expert (sorry to say) but I remember having a similar problem when using php on a Windows server. It stemmed from opening the file without the binary-flag (should be fopen($filePath, "rb"); in your sample). If you don't set that flag your data might be altered when you read it from the stream which could break your files (and you wouldn't notice it on textfiles).
See http://www.php.net/manual/en/function.fopen.php for more info on the different modes available.
Try using this --
<?php
$filename = "MyImage.jpg";
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);
?>
Instead of the following code that you are using,
$buffer = 1024;
while(!feof($fp)){
$data = fread($fp, $fileSize);
echo $data;
}
Just use readfile method
readfile($filePath);
I'm trying to combine two CSV files in PHP. I'm looking for perfect method. Here's my code so far:
$one = fopen('data5.csv', 'r');
$two = fopen('userdata.csv', 'r');
$final = fopen('final_data.csv', 'a');
$temp1 = fread($one, filesize("data5.csv"));
$temp2 = fread($two, filesize("userdata.csv"));
fwrite($final, $temp1);
fwrite($final, $temp2);
I will give you a solution to use if you have big CVSs and you don't want to use much of your machine's RAM (imagine each CSV is 1GB, for example).
<?php
function joinFiles(array $files, $result) {
if(!is_array($files)) {
throw new Exception('`$files` must be an array');
}
$wH = fopen($result, "w+");
foreach($files as $file) {
$fh = fopen($file, "r");
while(!feof($fh)) {
fwrite($wH, fgets($fh));
}
fclose($fh);
unset($fh);
fwrite($wH, "\n"); //usually last line doesn't have a newline
}
fclose($wH);
unset($wH);
}
Usage:
<?php
joinFiles(array('join1.csv', 'join2.csv'), 'join3.csv');
Fun fact:
I just used this to concat 2 CSV files of ~500,000 lines each. It took around 5seconds and used 512kb of memory.
Logic:
Open each file, read one line and then write it to the output file. Yes, it may be slower writing each line rather than writing a whole buffer, but this allows the usage of heavy files while being gentle on the memory of the machine.
At any point, you are safe because the script only reads on line at a time and then writes it.
Enjoy!
How about...
file_put_contents('final_data.csv',
file_get_contents('data5.csv') .
file_get_contents('userdata.csv')
);
Note that this loads the entire files into PHP memory though. So, if they are big, you may get memory_limit issues.
If you want to just concatenate the two files you can do this easily with executing a shell script assuming you are on unix like os:
exec("cat data5.csv > final_data.csv && cat userdata.csv >> final_data.csv");
ob_start();
$dir1 = "csv/2014-01/";
$dir = $_REQUEST['folder_name'];
$totalfiles = count(glob($dir."/*",GLOB_BRACE));
echo "Total files in folder = ".$totalfiles;
if ($opend = opendir($dir)){
$i =0; $final_array_export= array();
$fil_csv =end(explode('/',$dir));
$file_name = 'download/'.$fil_csv.'.csv';
$file_cre = fopen($file_name,"w");
$headers = array("header1","header2");
fputcsv($file_cre,$headers);
while (($file = readdir($opend)) !== false){
$filename = $dir.'/'.$file;
$files = fopen($filename,"r");
if($files){
$fullarray = fgetcsv($files);
$head=array();
if(count($fullarray) >0){
foreach($fullarray as $headers){
$head[] = $headers;
}
}
while($data = fgetcsv($files,0,",")){
if(count($data) >0 && count($head) >0){
$array_combine = array_combine($head,$data);
}
fputcsv($file_cre,$array_combine);
}
}
}
fclose($file_cre);
header("Content-Type: application/force-download");
header("Content-type: application/csv");
header('Content-Description: File Download');
header('Content-Disposition: attachment; filename=' . $file_name);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
}