To merge instead of replace in $zip->extractTo - php

I have used the following code to unzip a zip folder after upload.
/* here it is really happening */
if(move_uploaded_file($source, $targetzip)) {
$zip = new ZipArchive();
$x = $zip->open($targetzip); // open the zip file to extract
if ($x === true) {
echo $targetdir; exit;
$zip->extractTo($targetdir); // place in the directory with same name
$zip->close();
unlink($targetzip);
}
$message = "Your .zip file was uploaded and unpacked.";
} else {
$message = "There was a problem with the upload. Please try again.";
}
It is working fine. But the only problem is the that the folder is replaced by the new one uploaded. I want to merge it.
Suppose i have a zip folder.
One.zip
a
b
c
When i upload this, it should merge with the (One) folder which is already in the upload server. So the previous folders in the (One) folder should not be replaced.
I think It is understandable now. Please help to do the trick.

You can con-cat current time & date with you target fine name:
$targetdir = $targetdir."_".str_replace(' ',"/",date('Y-m-d H:i:s'));
Using this logic, you fine will not replace with previous file.

Related

how to unzip .zip file in codeigniter 4 (PHP)

I am trying to extract zip file in codeigniter 4... I have the code below
$file_name = session()->get('file_name');
// Zip file name
$filename = "/public/$file_name";
$zip = new \ZipArchive;
$res = $zip->open($filename);
if ($res === true) {
// Unzip path
$path = "/public";
// Extract file
$zip->extractTo($path);
$zip->close();
return 'Site Updated Successfully';
} else {
return "failed to update $filename!";
}
}
but I get this result: return "failed to update $filename!";
Please can someone help me fix the issue with the code.
This has nothing specifically to do with Codeigniter. It's just using PHP and ZipArchive. The code looks OK - be sure the file is really in the /public/ directory and that it is a zip archive. The PHP site has examples that are like $zip = new ZipArchive; (without the \ char); maybe try that.

Reading filenames from a zip file inside another zip file

I am trying to get all filenames from the files inside a zip file. It all works perfectly until the zip file contains another zip file and I try to get the included file names from the included zip as well.
I want to get all included filenames without extracting the file.
For some reason it always refuses to open the included zip file, as if it does not recognie it as a zip file.
To make 100% sure it is a zip for testing I simply included the same zip inside the main zip.
While it properly reads the main zipfile it returns false if I want to read the included file.
I have been trying to get this script to work for 3 days now but I keep failing so I decided to see if someone here can help me out with this.
This is the script I am using to read a zipfile contents:
function firstzipper($file) {
global $filesroot, $pagefile;
$zipinc = new ZipArchive();
if ($zipinc->open($file) === TRUE) {
for ($i = 0; $i < $zipinc->numFiles; $i++) {
$filename_full = $zipinc->getNameIndex($i);
$filename = substr($filename_full, strrpos($filename_full, '/') + 1);
if (!is_dir($filename)) {
$filename = filter_var($filename, FILTER_SANITIZE_STRING);
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($ext == 'zip') {
secondzipper($filesroot.$pagefile.'/'.$filename_full);
}
}
array_push($inc_files_arr,$filename);
}
return $inc_files_arr;
}
}
firstzipper($filesroot.$url);
secondzipper inside the function above is simply the same function, copied and renamed.
The zipfile looks like this:
E:/myfolder/fileserver/temper.zip/myincluded.zip
The function opens temper.zip but returns false on myincluded.zip.
I hope I have included all info needed, if not let me know and I add what else is required.

how to copy file content and directory data from zip archive using php

I am using php to open a zip file and read its content and then copy this content to some other location. I am stuck at one point that how to copy the file content(file is a json) and also have some images in other directories which I want to access.
$zip = zip_open(Input::file('file'));
$rzip = zip_read($zip);
$entr_open_zip = zip_entry_open($zip, $rzip, '');
if ($entr_open_zip) {
return "hello";
die;
} else {
return "hi";
die;
}
I have opened the file but don't know how to copy content or even how to open the directory and access files in that directory. Any help is appreciated. I will explain more if needed.Ignore the typos.
I have seen some questions related to it but not getting satisfactory solution.
ZipArchive in PHP have functions to handle .zip files. In your case to extract all contents to specific directory, extractTo function can make help.
Sample Code:
<?php
$zip = new ZipArchive;
if ($zip->open('test.zip') === TRUE) {
$zip->extractTo('/my/destination/dir/');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>

Linux PHP ExtractTo returns whole path instead of the file structure

I am pulling my hair out over here. I have spent the last week trying to figure out why the ZipArchive extractTo method behaves differently on linux than on our test server (WAMP).
Below is the most basic example of the problem. I simply need to extract a zip that has the following structure:
my-zip-file.zip
-username01
--filename01.txt
-images.zip
--image01.png
-songs.zip
--song01.wav
-username02
--filename01.txt
-images.zip
--image01.png
-songs.zip
--song01.wav
The following code will extract the root zip file and keep the structure on my WAMP server. I do not need to worry about extracting the subfolders yet.
<?php
if(isset($_FILES["zip_file"]["name"])) {
$filename = $_FILES["zip_file"]["name"];
$source = $_FILES["zip_file"]["tmp_name"];
$errors = array();
$name = explode(".", $filename);
$continue = strtolower($name[1]) == 'zip' ? true : false;
if(!$continue) {
$errors[] = "The file you are trying to upload is not a .zip file. Please try again.";
}
$zip = new ZipArchive();
if($zip->open($source) === FALSE)
{
$errors[]= "Failed to open zip file.";
}
if(empty($errors))
{
$zip->extractTo("./uploads");
$zip->close();
$errors[] = "Zip file successfully extracted! <br />";
}
}
?>
The output from the script above on WAMP extracts it correctly (keeping the file structure).
When I run this on our live server the output looks like this:
--username01\filename01.txt
--username01\images.zip
--username01\songs.zip
--username02\filename01.txt
--username02\images.zip
--username02\songs.zip
I cannot figure out why it behaves differently on the live server. Any help will be GREATLY appreciated!
To fix the file paths you can iterate over all extracted files and move them.
Supposing inside your loop over all extracted files you have a variable $source containing the file path (e.g. username01\filename01.txt) you can do the following:
// Get a string with the correct file path
$target = str_replace('\\', '/', $source);
// Create the directory structure to hold the new file
$dir = dirname($target);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
// Move the file to the correct path.
rename($source, $target);
Edit
You should check for a backslash in the file name before executing the logic above. With the iterator, your code should look something like this:
// Assuming the same directory in your code sample.
$dir = new DirectoryIterator('./uploads');
foreach ($dir as $fileinfo) {
if (
$fileinfo->isFile()
&& strpos($fileinfo->getFilename(), '\\') !== false // Checking for a backslash
) {
$source = $fileinfo->getPathname();
// Do the magic, A.K.A. paste the code above
}
}

extract only specific file types from zip with php

I'm creating a simple webapp my students can use to upload their projects (as a .zip file) to my server. This app takes the .zip > unzips it > displays a link to their web-project.
I'm using a php function like this, to extract the zip file:
function openZip($file_to_open) {
global $target;
$zip = new ZipArchive();
$x = $zip->open($file_to_open);
if($x === true) {
$zip->extractTo($target);
$zip->close();
unlink($file_to_open);
} else {
die("There was a problem. Please try again!");
}
}
is it possible to check the type of the files being extracted and only allow specific file types to get unzipped? Not that I don't trust my students... just want to make sure nothing malicious makes its way to my server.
my students will be uploading simple web projects, so I only want to allow .html, .css and .js (as well as image file types, and directories) to be extracted.
Check out ZipArchive::getFromName to pull just 1 file from the Zip by filename. You may also want to take a look at ZipArchive::getFromIndex
$zip = new ZipArchive;
if ($zip->open('test1.zip') === TRUE)
{
echo $zip->getFromName('testfromfile.php');
$zip->close();
}
else
{
echo 'failed';
}
You can always try finfo_file() like this:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, "yourfile.zip");
finfo_close($finfo);

Categories