How to create Zip file and download in CakePhp? - php

I'm trying to create zip files using CakePhp 1.3. The file descriptions are stored in database. In my controller I'm using the following logic.
// Fetching File description form database.
$this->view = 'Media';
$user_id=$this->Session->read('userData.User.id');
$condition = "Document.isdeleted = '0' AND Document.project_id='". $project_id."'";
$projectDocumentList = $this->Document->find("all",array('conditions'=>$condition,'fields'=>array('Document.id','Document.document_name','Document.path'),'order' => array('Document.id ASC')));
$this->set('projectDocumentList',$projectDocumentList);
if(!empty($projectDocumentList)){
$fileNames = "";
$fileNamesArr = array();
foreach($projectDocumentList as $projectDocument){
$fileNamesArr[ ]= $projectDocument['Document']['document_name'];
}
}
// Making zip
$archive_file_name='myFile.zip';
$file_path= "my_file_path";// Here I'm using my server basepath
$zip = new ZipArchive();
if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) {
exit("cannot open <$archive_file_name>\n");
}
foreach($fileNamesArr as $files)
{
$zip->addFile($file_path.$files,$files);
//echo $file_path.$files."<br>"; // This can show the file in browser
}
$zip->close();
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=$archive_file_name");
header("Pragma: no-cache");
header("Expires: 0");
readfile("$archive_file_name");
exit;
Now the zip file download as myFile.zip, but when I'm going to open that file, it throws an error "The archive is either in unknown format or damaged".

Create Zip File of whole folder
// Get real path for our folder
$rootPath = realpath('folder-to-zip');
// Initialize archive object
$zip = new ZipArchive();
$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
// Create recursive directory iterator
/** #var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
// Add current file to archive
$zip->addFile($filePath, $relativePath);
}
}
// Zip archive will be created only after closing object
$zip->close();
And than pass the path of the zip file to the view.
$this->set('Zip_path'.zip_file_name);

Related

How to download a folder with all its folders and files without zipping it with php

1 - I have a folder has a lot of users folder inside it, and every user's folder has others folders inside it has ismages inside them like this:
localhost/cm/app/model/uploads/mark/3/small/car.jpg
localhost/cm/app/model/uploads/mark/3/big/car.jpg
localhost/cm/app/model/uploads/stiven/9/small/pc.jpg
localhost/cm/app/model/uploads/stiven/9/big/pc.jpg
2 - I want that i donwload this folders with all its content.
3 - I prefer that I download it without zipping it with the same name, if it's not possible with zipping it with any name.
4 - I've used this code and it's not working because when I try to open the zip folder after downloading it an error message appear and tell me that "the archive is either unknown format or damaged", and this my code:
<?php
$dir = 'http://localhost/cm/app/model/uploads'; //folder path
$archive = time().'download.zip';
$zip = new ZipArchive;
$zip->open($archive, ZipArchive::CREATE);
$files = scandir($dir);
unset($files[0], $files[1]);
foreach ($files as $file) {
$zip->addFile($dir.'/'.$file);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
?>
*So how to download my folder with all its folders and images without zipping it or with zipping if not possible?
I suspect you've got an error in you're code. maybe ext-zip isn't install one way of checking this is by running php -m in a terminal which will display all install and enabled modules.
If you open up the zip file with a text editor it's like there be an error message instead of archived data.
This is The best way that i found:
<?php
// Get real path for our folder
$rootPath = realpath('folder_for_ziping');
// Initialize archive object
$zip = new ZipArchive();
$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
// Create recursive directory iterator
/** #var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
// Add current file to archive
$zip->addFile($filePath, $relativePath);
}
}
// Zip archive will be created only after closing object
$zip->close();
$archive = "file.zip";
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
?>

how to download Zip file to browser

I am trying to download some images as a zip file to my download folder in pc. But it always downloaded to the projects public folder. What can be the issue?
Here is my code
$photos = json_decode(Input::get('photos'));
$dir = time();
foreach($photos as $file){
$imgName = last(explode('/', $file));
$path = public_path('downloads/'.$dir);
if(!File::exists($path)){
File::makeDirectory($path, 0775, true);
}
ImageHandler::downloadFile($file, $path.'/'.$imgName);
}
$rootPath = realpath($path);
$zip = new ZipArchive();
$file_name = 'photos.zip';
$zip->open( $file_name, ZipArchive::CREATE | ZipArchive::OVERWRITE);
/** #var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file1)
{
// Skip directories (they would be added automatically)
if (!$file1->isDir())
{
// Get real and relative path for current file
$filePath = $file1->getRealPath();
$relativePath = substr($filePath, strlen($rootPath));
// Add current file to archive
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=$file_name");
readfile($filePath);
exit;

How to compress a folder in yii2 web app into a zip?

I am trying to zip a folder.
This is the function in ExportarController.php
public function zipping(){
$rootPath = realpath('results/');
// Initialize archive object
$zip = new \ZipArchive();
$zip->open('../web/descargas/Region.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
// Initialize empty "delete list"
$filesToDelete = array();
// Create recursive directory iterator
/** #var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
// Add current file to archive
$zip->addFile($filePath, $relativePath);
// Add current file to "delete list"
// delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)
if ($file->getFilename() != 'important.txt')
{
$filesToDelete[] = $filePath;
}
}
}
// Zip archive will be created only after closing object
$zip->close();
// Delete all files from "delete list"
foreach ($filesToDelete as $file)
{
unlink($file);
}
}
It worked pefectly when I tried it outside yii2 webapp. But when I added the function to yii2 controller I got the error:
Class 'app\controllers\ZipArchive' not found
Do you know what is going wrong? does it have something to do with the directory I'm trying to write in?
Please help me.
Thank you so much.
SOLUTION
It was cuz of the namespace, I had to ad \ to every ziparchive function.
Like \ZipArchive() and \ZipArchive::CREATE | \ZipArchive::OVERWRITE
Thanks to all of you.
First enable php zip extension
$zip = new \ZipArchive();
$test = tempnam(sys_get_temp_dir(), rand(0, 999999999) . '.zip');
var_dump($test);
$res = $zip->open($test, \ZipArchive::CREATE);
if ($res) {
foreach ($csv_data as $data) {
$zip->addFile($data['file_name'],'chat_'. $data['chatID'] .'.csv');
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=chat_' . date('Ymd_His'). '.zip');
readfile($test);
} else {
echo 'zip error';
die;
}
Read for More : http://php.net/manual/en/class.ziparchive.php

Move or Delete and Force download of Archive after creation

To put it simply, I would like my users to be able to download their website files, so I created a "Download Website" button which uses this script to add all files/folders in their directory which is in the variable $direc and archive those files/folders.
<?
///////// DOWNLOAD ENTIRE WEBSITE:
if(isset($_POST['download_site'])){
// define some basics
$rootPath = '../useraccounts/'.$direc.'';
$archiveName = ''.$direc.'.zip';
// initialize the ZIP archive
$zip = new ZipArchive;
$zip->open($archiveName, ZipArchive::CREATE);
// create recursive directory iterator
$files = new RecursiveIteratorIterator (new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY);
// let's iterate
foreach ($files as $name => $file) {
$filePath = $file->getRealPath();
$zip->addFile($filePath);
}
// close the zip file
if (!$zip->close()) {
echo '<p>There was a problem writing the ZIP archive.</p>';
} else {
echo '<p>Successfully created the ZIP Archive!</p>';
}
}
?>
To my surprise, this code works. Although, there are a few hiccups:
It doesn't automatically force a download of that archive.
It adds the archive in to my main directory rather than moving it to a separate directory of my choice such as site_downloads or deletes it up on completed download.
Are these problems at all fixable or if not, is there a better way to do it so my main directory does not get filled with constant downloads? I guess it will cause a problem once a Archive is created more than once, as it uses the Directory name.
Solved this by using a few different combinations:
<?
///////// DOWNLOAD ENTIRE WEBSITE:
if(isset($_POST['download_site'])){
// define some basics
$rootPath = '../useraccounts/'.$direc.'';
$archiveName = ''.$direc.'.zip';
// initialize the ZIP archive
$zip = new ZipArchive;
$zip->open($archiveName, ZipArchive::CREATE);
// create recursive directory iterator
$files = new RecursiveIteratorIterator (new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY);
// let's iterate
foreach ($files as $name => $file) {
$filePath = $file->getRealPath();
$zip->addFile($filePath);
}
// close the zip file
if (!$zip->close()) {
echo '<p>There was a problem writing the ZIP archive.</p>';
} else {
rename($archiveName, 'user_archives/'.$archiveName.'');
$yourfile = "user_archives/".$archiveName."";
$file_name = basename($yourfile);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=$file_name");
header("Content-Length: " . filesize($yourfile));
readfile($yourfile);
ignore_user_abort(true);
if (connection_aborted()) {
unlink('user_archives/'.$archiveName.'');
} else {
unlink('user_archives/'.$archiveName.'');
}
echo '<p>Successfully created the ZIP Archive!</p>';
}
}
?>
This seems to fix all problems.

Zipping random files in PHP

Hi I am trying to collect a number of random files from a folder on my server (./uploads) and zip them so the user can download. I think I am pretty close but I could use some help. I am getting a "503 backend fetch" error everytime and i can not pinpoint my issue. Thank you!!!
<?php
$rootPath = realpath('./uploads');
//make zip file
$zip = new ZipArchive();
$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$nfiles = glob($rootPath.'*.{aiff}', GLOB_BRACE);
$files = $nfiles[array_rand($nfiles,20)];
//-------------------------------------------//
foreach ($files as $file)
{
if (!$file->isDir())
{
// Get path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
// Add file to zip
$zip->addFile($filePath, $relativePath);
}
}
//-------------------------------------------//
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.'generated
sounds.zip');
header('Content-Length: ' . filesize('file.zip'));
readfile('file.zip');
if(file_exists('file.zip')){
unlink('file.zip');
}
?>

Categories