Reading files from ZIP without extracting to disk - php

Is it possible to open a ZIP file on a server, read a file from its content and display it / send it to a client directly without extracting it to disk first ? I am talking about pdf's and images. Haven't found any hints in the php sites.

Well,there is a PHP Extension.
If you use the extractTo method, you would be able to extract a single file, checkout the documentation.
From the documentation, extracting two files:-
<?php
$zip = new ZipArchive;
$res = $zip->open('test_im.zip');
if ($res === TRUE) {
$zip->extractTo('/my/destination/dir/', array('pear_item.gif', 'testfromfile.php'));
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>
You would need to provide an array of path inside the zip.

Related

In PHP - Overwrite Specific File in Zip Folder [duplicate]

I have a ZIP file on my server. I want to create a PHP file, loadZIP.php that will accept a single parameter, and then modify a text file within the ZIP to reflect that parameter.
So, accessing loadZIP.php?param=blue, will open up the zip file, and replace some text in a text file I specify with 'blue', and allow the user to download this edited zip file.
I've looked over all of the PHP ZIP functions, but I can't find a simple solution. It seems like a relatively easy problem, and I believe I'm over thinking it. Before I go and write some overly complex functions, I was wondering how you'd go about this.
Have you taken a look at PHP5's ZipArchive functions?
Basically, you can use ZipArchive::Open() to open the zip, then ZipArchive::getFromName() to read the file into memory. Then, modify it, use ZipArchive::deleteName() to remove the old file, use ZipArchive::AddFromString() to write the new contents back to the zip, and ZipArchive::close():
$zip = new ZipArchive;
$fileToModify = 'myfile.txt';
if ($zip->open('test1.zip') === TRUE) {
//Read contents into memory
$oldContents = $zip->getFromName($fileToModify);
//Modify contents:
$newContents = str_replace('key', $_GET['param'], $oldContents)
//Delete the old...
$zip->deleteName($fileToModify)
//Write the new...
$zip->addFromString($fileToModify, $newContents);
//And write back to the filesystem.
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
Note ZipArchive was introduced in PHP 5.2.0 (but, ZipArchive is also available as a PECL package).
In PHP 8 you can use ZipArchive::replaceFile
As demonstrated by this example from the docs:
<?php
$zip = new ZipArchive;
if ($zip->open('test.zip') === TRUE) {
$zip->replaceFile('/path/to/index.txt', 1);
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>

Unable to extract zip file which generated using php

I have written the PHP script to generate the zip file. it's working fine when I use rar software to extract it but not getting extract with rar software. I can't ask to users to install rar software to extract downloaded zip file.
I don't know where i am commiting mistakes.
Here i attached error screen shot which i get when try to open zip file.
// Here is code snippet
$obj->create_zip($files_to_zip, $dir . '/download.zip');
// Code for create_zip function
//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) {
$filearr = explode('/', $file);
$zip->addFile($file, end($filearr));
}
$zip->close();
If $valid_files is a glob'd array, use basename() instead of end(), your zip might not actually have added any files causing for it to be an invalid zip (however that would be visible in the size of the zip file).
Also try winrar/winzip/7zip and see what they return, microsoft's internal zip engine might not be up to date enough to open the zips.
I have also encountered this problem, using 7z solved the problem but we need to send the zip to somebody else so 7z is a nono.
I found that, in my case it is that the file path is too long:
When I use this:
$zip->addFile($files_path.'/people.txt');
And it generated a zip folder nested very deep e.g. ["/tmp/something/something1/something2/people.txt"]
So I need to use this instead
$zip->addFile($files_path.'/people.txt', 'people.txt');
Which generate a a zip folder with only 1 layer ["people.txt"], and Windows Zip read perfectly~
Hope this helps somebody that also have this problem!

Is there a (PHP) shortcut to zip all files in a folder (perform the reverse of the ZipArchive extractTo operation)?

The code from this answer simply extracts the contents of a zip file to a folder:
<?php
$zip = new ZipArchive;
$res = $zip->open('file.zip');
if ($res === TRUE) {
$zip->extractTo('/myzips/extract_path/');
$zip->close();
echo 'woot!';
} else {
echo 'doh!';
}
?>
Is there any simple way (without a foreach loop, per file, and recursively descending into subfolders) to run this operation in reverse, in PHP, so that the original zip file is created again?
The "extract_path" folder must not be included in the zip file, which is why I can't simply use the recursive function linked above.
This would be the PHP equivalent of doing these linux shell commands, which are pretty simple:
cd /myzips/extract_path/
zip /dest/file.zip *
(before anyone comments "Why would you want to do that?", it's because I want to modify a file then recreate the zip file)

Help with php function zip_open

It's now 5am, and as much as I try to research, I can't find much information on this function set. Here's the code I have (shortened slightly):
<?php
$source = $_FILES["restore_file"]["tmp_name"];
$zip = zip_open($source);
while ($zip_entry = zip_read($zip)) {
echo zip_entry_name($zip_entry).'\n';
}
?>
which when I upload my example zip out puts:
example/
example/index.php
example/file1.csv
example/file2.csv
example/file3.csv
etc.
I need to know how to access the contents of those files though, and also be able to specify which file I am accessing exactly. For example, before going through the csv files, I need to check a php variable in the index.php file of the archive, to make sure it is correct.
Is using the ZipArchive class a better idea instead of the zip functions perhaps? I was under the impression though that using the zip functions would be better as it can access the files on the fly (without having to transfer the files to a new directory).
Use ZipArchive::getFromName(). Example from the PHP manual adapted to your case:
$zip = new ZipArchive();
if ($zip->open($_FILES["restore_file"]["tmp_name"]) === true) {
echo $zip->getFromName('example/index.php');
$zip->close();
} else {
echo 'failed';
}

Modifying a single text file in a ZIP file, in PHP

I have a ZIP file on my server. I want to create a PHP file, loadZIP.php that will accept a single parameter, and then modify a text file within the ZIP to reflect that parameter.
So, accessing loadZIP.php?param=blue, will open up the zip file, and replace some text in a text file I specify with 'blue', and allow the user to download this edited zip file.
I've looked over all of the PHP ZIP functions, but I can't find a simple solution. It seems like a relatively easy problem, and I believe I'm over thinking it. Before I go and write some overly complex functions, I was wondering how you'd go about this.
Have you taken a look at PHP5's ZipArchive functions?
Basically, you can use ZipArchive::Open() to open the zip, then ZipArchive::getFromName() to read the file into memory. Then, modify it, use ZipArchive::deleteName() to remove the old file, use ZipArchive::AddFromString() to write the new contents back to the zip, and ZipArchive::close():
$zip = new ZipArchive;
$fileToModify = 'myfile.txt';
if ($zip->open('test1.zip') === TRUE) {
//Read contents into memory
$oldContents = $zip->getFromName($fileToModify);
//Modify contents:
$newContents = str_replace('key', $_GET['param'], $oldContents)
//Delete the old...
$zip->deleteName($fileToModify)
//Write the new...
$zip->addFromString($fileToModify, $newContents);
//And write back to the filesystem.
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
Note ZipArchive was introduced in PHP 5.2.0 (but, ZipArchive is also available as a PECL package).
In PHP 8 you can use ZipArchive::replaceFile
As demonstrated by this example from the docs:
<?php
$zip = new ZipArchive;
if ($zip->open('test.zip') === TRUE) {
$zip->replaceFile('/path/to/index.txt', 1);
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>

Categories