I have a problem.
I searched the internet for a solution, but nothing works well. I'm trying to make a script that will take files from a folder and threw them into a zip archive.
But it doesn't work ..
I tried through different paths, but it's only me mixed up and nothing came of it.
Here is the current code that is according to me the easiest and should workbut doesn't do that ..
Can you help me?
function archivebackup(){
$zip = new ZipArchive;
if ($zip->open('Mail.zip', ZipArchive::CREATE) === TRUE){
foreach (new DirectoryIterator('Mails/') as $fileInfo) {
$fileName = $fileInfo->getFilename();
// echo $fileName ."<br>";
$zip->addFile($fileName);
}
$zip->close();
}
}
It seems you're not including files in your current working directory and getFilename() only returns a filename without a path.
Do the following:
function archivebackup(){
$zip = new ZipArchive;
if ($zip->open('Mail.zip', ZipArchive::CREATE) === TRUE){
foreach (new DirectoryIterator('Mails/') as $fileInfo) {
if (in_array($fileInfo->getFilename(), [ ".", ".." ]) { continue; }
$fileName = $fileInfo->getPathname();
$zip->addFile($fileName);
}
$zip->close();
}
}
Related
I'm using following codes to create zip file in Laravel:
$files = Answer::where('questionid', $questionId)
->pluck('answer')
->all();
$zip = new ZipArchive;
$zip_name = time() . "_$questionId" . ".zip";
if ($zip->open(storage_path($zip_name), ZipArchive::CREATE) === true) {
foreach ($files as $file) {
$relativeNameInZipFile = explode('/', $file)[3];
$zip->addFile(Storage::path($file), $relativeNameInZipFile);
}
$zip->close();
}
return Storage::download($zip_name);
It works properly.But when the last line of the code that returns file to download create an extra zip file in the storage!
return Storage::download($zip_name);
Why!!??
i will create a Zip Archive with the PHP Class. But it still not working.
It comes no fail and the response is 1. He don't create the Zip-File.
$zip = new ZipArchive;
$res = $zip->open('qr_img/'.'ab387bas.zip'.'', ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFile($file, 'screen.png');
$zip->close();
}
know's everyone the answer ?
$file_names is the array of files which are you want to add in the zip.
function zipFile($file_names,$archive_file_name)
{
$zip = new ZipArchive();
//create the file and throw the error if unsuccessful
if ($zip->open($archive_file_name, ZIPARCHIVE::OVERWRITE )!==TRUE) {
}
//add each files of $file_name array to archive
foreach($file_names as $files)
{
// $zip->addFile($files,$files);
$zip->addFromString(basename($files), file_get_contents($files));
}
$zip->close();
}
Trying to get import/export functionality.
With a folder containing a file
Zip the folder in PHP using ZipArchive
Unzip the zipped folder using ZipArchive
New folder is created, but the file inside is missing
function unArchive(){
$zip = new ZipArchive;
$res = $zip->open('zipTest.zip');
if ($res === TRUE) {
echo 'ok';
$zip->extractTo("testfolder2");
$zip->close();
} else {
echo 'failed, code:' . $res;
}
}
function Zip($source, $destination){
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('\\', '/', 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( "testfolder/" , "./zipTest.zip" );
unArchive();
Code works fine for single files.
With a file zipped using ZipArchive, I can manually unzip using WinRAR, then rezip using WinRAR, and then ZipArchive can successfully unzip that file.
The problem is that ZipArchive won't extract the archive that it directly zipped.
I can also see in Notepad++ that the ZipArchive zip is different from the WinRAR zip, and the file size is different. I can successfully call winrar as a system command in php for the desired functionality, but this seems like a bad idea.
Is there some reason ZipArchive creates zip files that it can't extract?
Error message: ZipArchive::extractTo(): Invalid argument in [file] on line [$zip->extractTo("testfolder2");]
The RecursiveIteratorIterator returns the pseudo-files "." and, that's important here, ".." - the parent directory. When you use addEmptyDir to add the parent directory, the ZipArchive will add it (somehow)! You may even try "$zip->addEmptyDir("../something")" and it will not complain.
Now, usually, zip files don't behave this way. When you extract them, you expect all contents to be in the folder you extract them, not in the parent folders. This is why ordinary ZIP extraction programs do not show it.
The PHP ZipArchive will extract even these folders, however. Then, this error will somehow occur, because you tried to include the "." or ".." directories.
Add this at the beginning of the foreach cycle to resolve this:
if (basename($file) === ".") { continue;}
if (basename($file) === "..") { continue; }
Test case:
<?php
$archive = new ZipArchive();
$archive->open('c.zip',ZipArchive::CREATE);
$archive->addFile('a.txt');
$archive->addFile('b.txt');
$archive->addEmptyDir("../../down");
$archive->close();
$archive2 = new ZipArchive();
$archive2->open('c.zip');
$archive2->extractTo('here');
$archive2->close();
I tested this only on Windows.
I have a directory structure like this :
members/
login.php
register.php
I zip them by PHP ZipArchive in my windows machine, but when I upload it to linux host and extract there by PHP it gives me these as two files with no directory :
members\login.php
members\register.php
I want to have the complete directory structure on the host after unzipping the file.
Note that this unpacking code runs without any problem in my local machine. Is it something about windows and linux or what? How can I resolve it?
PHP does not actually provide a function that extracts a ZIP including its directory structure. I found the following code in a user comment in the manual:
function unzip($zipfile)
{
$zip = zip_open($zipfile);
while ($zip_entry = zip_read($zip)) {
zip_entry_open($zip, $zip_entry);
if (substr(zip_entry_name($zip_entry), -1) == '/') {
$zdir = substr(zip_entry_name($zip_entry), 0, -1);
if (file_exists($zdir)) {
trigger_error('Directory "<b>' . $zdir . '</b>" exists', E_USER_ERROR);
return false;
}
mkdir($zdir);
}
else {
$name = zip_entry_name($zip_entry);
if (file_exists($name)) {
trigger_error('File "<b>' . $name . '</b>" exists', E_USER_ERROR);
return false;
}
$fopen = fopen($name, "w");
fwrite($fopen, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)), zip_entry_filesize($zip_entry));
}
zip_entry_close($zip_entry);
}
zip_close($zip);
return true;
}
Source here.
try DIRECTORY_SEPARATOR
instead of using:
$path = $someDirectory.'/'.$someFile;
use:
$path = $someDirectory. DIRECTORY_SEPARATOR .$someFile;
Change your code to this:
$zip = new ZipArchive;
if ($zip->open("module. DIRECTORY_SEPARATOR .$file[name]") === TRUE) {
$zip->extractTo('module. DIRECTORY_SEPARATOR');
}
And it will work for both operating systems.
Good luck,
The problem solved! Here's what I did :
I change the code of creating zip file into this function from php.net user comments :
function addFolderToZip($dir, $zipArchive){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
$zipArchive->addEmptyDir($dir);
// Loop through all the files
while (($file = readdir($dh)) !== false) {
//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if(($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive);
}
}else{
// Add the files
$zipArchive->addFile($dir . $file);
}
}
}
}
}
$zip = new ZipArchive;
$zip->open("$modName.zip", ZipArchive::CREATE);
addFolderToZip("$modName/", $zip);
$zip->close();
And in the host I wrote just this code to extract the zipped file :
copy($file["tmp_name"], "module/$file[name]");
$zip = new ZipArchive;
if ($zip->open("module/$file[name]") === TRUE) {
$zip->extractTo('module/');
}
$zip->close();
It created the folder and sub-folders. The only bug left is that it extracts every file in all subfolders in the main folder too, so there is two versions of each file in subfolders.
Currently FTP is insanely slow on our server when it comes to multiple small files.
I am wanting to create a file that I can run in my browser that creates a zip file.
Basically this file will sit in /htdocs
The zip file it creates must take all files in /htdocss (and sub folders ect) and mimic the structure.
Can anyone point me in the right direction?
I am attempting to use the below code.
The only issue is that,
I am getting some blank folders
say the file is:
C:/xampp/htdocs/booking/zip.php
I get
/C
/C/xampp
/C/xampp/htdocs
/C/xampp/htdocs/booking
/C/xampp/htdocs/booking/image.png
/C/xampp/htdocs/booking/index.php
I dont want /C/xampp/htdocs/booking
I just want the zip file to contain
image.png
index.php
How can I fix this?
<?php
function Zip($source, $destination) {
if(extension_loaded('zip') === true) {
if(file_exists($source) === true) {
$zip = new ZipArchive();
if($zip->open($destination, ZIPARCHIVE::CREATE) === true) {
$source = realpath($source);
if(is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach($files as $file) {
$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();
}
}
return false;
}
Zip(dirname(__FILE__), 'testzip.zip');
?>
There are two options. You can use PHPs built-in ZipArchive and manually iterate over the directory contents (readdir or DirectoryIterator).
Or you can do the lazy thing:
header("Content-Type: archive/zip"); // mime 2.0
header("Content-Disposition: attachment; filename=dir.zip");
passthru("zip -q -r - .");
Depends on the installed zip tool. It complains if you try that on the terminal, but should work over the passthru pipe.