ZipArchive - zip is not getting created, but throws no errors - php

I'm struggling with creating zips with ZipArchive. I've modified a function that let's me create a zip from an array of file paths.
Can you spot any faults in this code, anything that prevents the zip file from being created?
// Function to create a zip archive for the low res images
function create_zip_lres($files = array(), $destination = '', $overwrite = false) {
// If the zip file already exists and overwrite is false, return false
if(file_exists($destination) && !$overwrite) { return false; }
$valid_files = array();
// If files were passed in
if(is_array($files)) {
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) {
$basename = basename($file);
$zip->addFile($file, $basename);
}
// DEBUG
echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
if ($zip->close()) {
echo ' - Success!';
echo '<br>';
echo 'Your zip path is: ' . $destination;
} else {
echo ' - Failed!';
}
// DEBUG
echo '<br>';
print_r($zip);
// Return filepath for zip
return $destination;
}
else {
return false;
}
}
// getting the images array
$resize_images = resize_images();
// destination path
$lres_directory = get_lres_full_upload_dir() . get_the_title() . '-low-res.zip';
if (function_exists('create_zip_lres')) {
create_zip_lres($resize_images, $lres_directory);
} else {
}
I've added some debugging lines to find out what's happening and although it's telling me everything looks fine, no file is created.
The zip archive contains 3 files with a status of 0 - Success!
Your zip path is: http://media.mysite.com/wp-content/uploads/lres-download-manager-files/Knus 1400-low-res.zip
ZipArchive Object ( [status] => 0 [statusSys] => 0 [numFiles] => 0 [filename] => [comment] => )

I have another solutions for dynamic array values enter to zip files.I have tested this is working fine.
Hope this helps:
<?php
//Our Dynamic array
$array = array( "name" => "raaaaaa",
"test" => "/sites/chessboard.jpg"
);
//After zip files are stored in this folder
$file= "/sites/master.zip";
$zip = new ZipArchive;
echo "zip started.\n";
if ($zip->open($file, ZipArchive::CREATE) === TRUE) {
foreach($array as $path){
$zip->addFile($path, basename($path));
echo "$path was added.\n";
}
$zip->close();
echo 'done';
} else {
echo 'failed';
}
?>

zipping multiple files to one zip file.
For Multiple files you can use this code for zip the specific folders.
I have tried this code and successfully zipped multiple files into one zip file.
I think this is help to your requirement.
<?php
function Zip($source, $destination)
{
echo "called function";
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
continue;
$file = realpath($file);
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
Zip('D:/tmp','D:/tmp/compressed.zip',true);
?>
Hope this helps

Related

How to backup site excluding folders using PHP

I want to take backup of my website files and want to exclude some folders/files.
I looked for a solution in an older post and tweaked a bit as described below:
<?php
/*
* PHP: Recursively Backup Files & Folders to ZIP-File
* (c) 2012-2014: Marvin Menzerath - http://menzerath.eu
* contribution: Drew Toddsby
*/
// Make sure the script can handle large folders/files
ini_set('max_execution_time', 600);
ini_set('memory_limit','1024M');
$dir = '/home/user10/public_html';
$HKfilename = date("Y-m-d-H-i");
$saveto = "/home/user10/public_ftp/file_bkup-$HKfilename.zip";
$exclude = array("$dir/cache","$dir/images", "$dir/media");
// Start the backup!
zipData($dir, $saveto, $exclude);
echo 'Files backup created: file_bkup-$HKfilename.zip';
// Here the magic happens :)
function zipData($source, $destination, $exclude) {
if (extension_loaded('zip')) {
if (file_exists($source)) {
$zip = new ZipArchive();
if ($zip->open($destination, ZIPARCHIVE::CREATE)) {
$source = realpath($source);
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);
// skip dot files while iterating
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
if ( in_array($file, $exclude) ) {
continue;
}
if ( is_file($file) ) {
$p = pathinfo($file);
if ( in_array($p['dirname'], $exclude) ) {
continue;
}
}
$file = realpath($file);
if (is_dir($file)) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
} else if (is_file($file)) {
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
} else if (is_file($source)) {
$zip->addFromString(basename($source), file_get_contents($source));
}
}
return $zip->close();
}
}
return false;
}
I'm getting below error, while executing the script.
[15-Dec-2017 12:17:02] PHP Fatal error: Call to undefined method RecursiveDirectoryIterator::setFlags() in /home/user10/public_ftp/filebackup.php on line 32
If I comment this code,
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
zip file is generated with file name file_bkup-2017-11-22-20-39.zip.KDzpTi (last 6 chars changes on each attempt). However, this zip file does not contain all files/folders. Also, this zip file contains the folders which are specified in exclude array.

PHP Create a Zip archive for file only particular extension

How to create Zip archive for file only particular extension in my case .TIF .JPG .TXT
currently i have added single extensions in code you can modify it later on.
<?php
/* creates a compressed zip file */
function create_zip($files = array(), $destination = '', $overwrite = false) {
//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, $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;
}
}
//your directory path where all files are stored
$dir = 'D:\xampp\htdocs\samples\zip';
$files1 = scandir($dir, 1);
// $ext = "png"; //whatever extensions which you want to be in zip.
$ext = ['jpg','tif','TXT']; //whatever extensions which you want to be in zip.
$finalArray = array();
foreach ($files1 as $key => $value) {
$getExt = explode(".", $value);
if ( in_array($getExt[1] , $ext) ) {
$finalArray[$key] = $value;
}
}
$result = create_zip($finalArray, 'my-archive' . time() . '.zip');
if ($result) {
echo "Operation done.";
}
?>
i think this is what you want.
let me know if you have any issue.

ZipArchive::close(): Read error: Is a directory

I'm trying to figure out this problem but I cannot imagine why it keeps happening. I'm adding files to a ZipArchive and when I try to close it, it get the error that the destination is a directory. But I'm pretty sure it is not.
This is the code of the zip function:
function create_zip($folder, $destination) {
$valid_files = get_files($folder);
if(count($valid_files)) {
$zip = new ZipArchive();
if($zip->open($destination, ZIPARCHIVE::CREATE) !== true) {
return false;
}
//add the files
foreach($valid_files as $file) {
$zip->addFile($file,$file);
}
$zip->close();
return file_exists($destination);
}
else
{
return false;
}
}
function get_files($folder){
$valid_files = array();
$files = scandir($folder);
foreach($files as $file) {
if(substr($file, 0, 1) == "." || !is_readable($folder . '/' . $file)) {
continue;
}
if(is_dir($file)){
array_merge($valid_files, get_files($folder . '/' . $file));
} else {
$valid_files[] = $folder . '/' . $file;
}
}
return $valid_files;
}
I'm calling it like this so it should really not be a directory:
$dest = "backups/" . time() . "_backup.zip";
if(file_exists($dest)){
if(is_dir($dest)) {
rmdir($dest);
} else {
unlink($dest);
}
}
create_zip('crawler/out', $dest);
Maybe someone here can help me with this. Thank you!
Simon
In this case, the directory is not zip archive, but the file that is added to it.
Try adding this before adding the file:
if (file_exists($file) && is_file($file))
And change the filename instead of the filepath in this place:
$zip->addFile($file,$file);
... also; a behaviour change from PHP 7. If you have sub-folders in the folder you want to zip:

zipping a folder not working in php

I have created a script to upload a photo and place different sizes versions into a folder. After that, I want to zip that folder. The script is doing all the work I want except zipping the files. No error is showing up.
Here's the code:
session_start();
$_SESSION['upload_time']=time();
$target_dir = 'downloads/'.$_FILES['userImage']["name"].'-'.$_SESSION['upload_time'].'/';
if(!is_dir($target_dir)){
mkdir($target_dir);
}
$file4 = file_get_contents('assets/sizes.txt', true);
$data4=json_decode($file4,true);
foreach($data4 as $data){
$data=explode('_',$data);
$data1= preg_replace("/[^0-9]/","",$data[0]);
$data2= preg_replace("/[^0-9]/","",$data[1]);
///uploading photo and creating its different sizes
store_uploaded_image('userImage',$data1,$data2,$data1.'x'.$data2 ,$target_dir);
}
$zip = new ZipArchive();
// open archive
if ($zip->open('my-archive.zip', ZIPARCHIVE::CREATE) !== TRUE) {
die ("Could not open archive");
}
// initialize an iterator
// pass it the directory to be processed
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($target_dir));
// iterate over the directory
// add each file found to the archive
foreach ($iterator as $key=>$value) {
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
// close and save archive
$zip->close();
echo "Archive created successfully.";
Try this code,For Local systems you can use this code for zip the specific folders.
Code:-
<?php
function Zip($source, $destination)
{
echo "called function";
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
continue;
$file = realpath($file);
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
Zip('/downloads','/my-archive.zip',true);
?>
Hope this helps.

zip generating function generating blank files

I am using this function to generate zip files:
function create_zip($files = array(),$destination = '',$overwrite = false) {
//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,$file);
//echo $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
echo $destination;
return file_exists($destination);
}
else
{
return false;
}
}
I am using this to zip a vanilla, unaltered Wordpress install.(http://wordpress.org/) However for some reason the wp-content folder is having a 'ghost' empty file generated with it's name. The folder (and everything else) itself compresses correctly, but most unzip applications (including php's own extractTo()) break when they reach this unwanted file due to the name conflict.
I've looked into the folder/file structure and as far as I can see the only difference of note between this and the other folders in the site is that it is the biggest at 5.86 mb.
Can anyone suggest a fix / workaround?
This is the sample example to zip a folder.
<?php
function Create_zipArch($archive_name, $archive_folder)
{
$zip = new ZipArchive;
if ($zip->open($archive_name, ZipArchive::CREATE) === TRUE)
{
$dir = preg_replace('/[\/]{2,}/', '/', $archive_folder . "/");
$dirs = array($dir);
while (count($dirs))
{
$dir = current($dirs);
$zip->addEmptyDir($dir);
$dh = opendir($dir);
while ($file = readdir($dh))
{
if ($file != '.' && $file != '..')
{
if (is_file($file))
$zip->addFile($dir . $file, $dir . $file);
elseif (is_dir($file))
$dirs[] = $dir . $file . "/";
}
}
closedir($dh);
array_shift($dirs);
}
$zip->close();
$result='success';
}
else
{
$result='failed';
}
return $result;
}
$zipArchName = "ZipFileName.zip"; // zip file name
$FolderToZip = "zipthisfolder"; // folder to zip
echo Create_zipArch($zipArchName, $FolderToZip);
?>

Categories