I'm trying to extract a directory of zip files in the same directory they are located in.
public function buildRecords($quickCheckOutputDir, $salvageVinsDir)
{
//unzip
$files_to_extract = $this->getFiles($salvageVinsDir);
$zip = new ZipArchive();
foreach($files_to_extract as $file) {
$res = $zip->open($salvageVinsDir . $file);
if($res) {
echo $zip->extractTo($salvageVinsDir);
//$zip->deleteName($salvageVinsDir . $file);
$zip->close();
} else {
echo 'failed, code:' . $res;
}
}
}
The echo $zip->extractTo($salvageVinsDir) returns 1 so I would think that the method is working but when I check the directory only the zipped files are there. Nothing has been extracted. What is the issue here?
Edit: I gave the directory I'm working in chmod 777.I'm working on centos 7.
Related
I'm running a php script (like bash).
This script do this:
Download a zip file from FTP server
ftp_get($ftp, $myFile.zip, $file, FTP_BINARY);
When I have downloaded the file, I want to extract its content:
$zip = new ZipArchive;
$res = $zip->open($myFile);
if ($res === TRUE) {
$zip->extractTo($extractDir);
$zip->close();
} else {
dump( 'error, code:' . $res);
die;
}
But, I get the error 19 who is: "Not a zip archive"
If I open the .zip, it is a compressed archive because I have the PK key...
Does anyone have a solution or idea ?
Regards
Solutions
I am using this code and it work fine.
$zip = new ZipArchive;
$myfileDir = './abc.zip';
$extractDir = './';
$res = $zip->open($myfileDir);
if ($res === TRUE) {
$zip->extractTo($extractDir);
$zip->close();
echo 'Successfully extract the file';
} else {
echo ('error, code:' . $res);
die;
}
Question
I believe the problem is because of the zip file, would upload the the zip folder to google drive and let us download and test it locally?
I am creating a php file that will update my site after pulling it off of BitBucket (Git repo). It downloads a zip file of the entire master or a commit, then unzips it in the website's folder.
The problem I am having is there is a randomly named folder that contains all the files in the zip file.
My zip file's contents is similar:
master.php
- (bitbucketusername)-(reponame)-(commitnumber)
- folder1
- index.php
- test.php
- index.php
- config.php
- etc...
but how can I "bypass" the "randomly" named folder and extract the contents of the folder to the website's root?
echo "Unzipping update...<br>" . PHP_EOL;
$zip = new ZipArchive;
$res = $zip->open($filename);
if ($res === TRUE) {
$zip->extractTo('/path/to/www');
$zip->close();
} else {
echo 'Error: The zip file could not be opened...<br>' . PHP_EOL;
}
Found a related question here:
Operating with zip file in PHP
But how can I make it get the "randomly" named folder's name?
Unzip the files to a tmp directory and then mv the files out from the "randomly" named parent folder to the folder that you want to.
echo "Unzipping update...<br>" . PHP_EOL;
$zip = new ZipArchive;
$res = $zip->open($filename);
if ($res === TRUE) {
$zip->extractTo('/tmp/unzip');
$directories = scandir('/tmp/unzip');
foreach($directories as $directory){
if($directory!='.' and $directory!='..' ){
if(is_dir($directory)){
// rcopy from http://ben.lobaugh.net/blog/864/php-5-recursively-move-or-copy-files
rcopy('/tmp/unzip/'.$directory,'/path/to/www');
// rm /tmp/unzip here
}
}
}
$zip->close();
} else {
echo 'Error: The zip file could not be opened...<br>' . PHP_EOL;
}
I am trying to extract a ZipArchive to 'http://localhost/MODULES/ZIP_RAR_MANAGER/'.
No errors are shown, and I get the message Zip File Opened.
Why are the files not being correctly extracted from the zip archive?
$zip = new ZipArchive;
if ($zip->open('../test.zip'))
{
echo 'ZIP FILE OPENED...<br/>';
if ($zip->extractTo('http://localhost/MODULES/ZIP_RAR_MANAGER/'))
{
echo 'ZIP FILE EXTRACTED';
}
$zip->close();
}
else
{
echo 'failed';
}
You are trying to extract it to non-existent folder http://localhost/MODULES/ZIP_RAR_MANAGER/. You cannot use url as a folder/file path.
You should use:
if ($zip->extractTo($_SERVER['DOCUMENT_ROOT'] . '/MODULES/ZIP_RAR_MANAGER/') {
...
}
I have a zip file containing one folder, that contains more folders and files, like this:
myfile.zip
-firstlevel
--folder1
--folder2
--folder3
--file1
--file2
Now, I want to extract this file using PHPs ZipArchive, but without the "firstlevel" folder. At the moment, the results look like this:
destination/firstlevel/folder1
destination/firstlevel/folder2
...
The result I'd like to have would look like this:
destination/folder1
destination/folder2
...
I've tried extractTo, which produces the first mentioned result, and copy(), as suggested here, but this doesn't seem to work at all.
My current code is here:
if($zip->open('myfile.zip') === true) {
$firstlevel = $zip->getNameIndex(0);
for($i = 0; $i < $zip->numFiles; $i++) {
$entry = $zip->getNameIndex($i);
$pos = strpos($entry, $firstlevel);
if ($pos !== false) {
$file = substr($entry, strlen($firstlevel));
if(strlen($file) > 0){
$files[] = $file;
}
}
}
//attempt 1 (extractTo):
//$zip->extractTo('./test', $files);
//attempt 2 (copy):
foreach($files as $filename){
copy('zip://'.$firstlevel.'/'.$filename, 'test/'.$filename);
}
}
How can I achieve the result I'm aiming for?
Take a look at my Quick Unzipper script. I wrote this for personal use a while back when uploading large zip files to a server. It was a backup, and 1,000s of files take forever with FTP so using a zip file was faster. I use Git and everything, but there wasn't another option for me. I place this php file in the directory I want the files to go, and put the zip file in the same directory. For my script, they all have to operate in the same directory. It was an easy way to secure it for my needs, as everything I needed was in the same dir.
Quick Unzipper: https://github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php
I linked the file because I am not showcasing the repo, just the code that makes the unzip tick. With modern versions of PHP, there should't be anything that isn't included on your setup. So you shouldn't need to do any server config changes to use this.
Here is the PHP Doc for the ZipArchive class it uses: http://php.net/manual/en/class.ziparchive.php
There isn't any included way to do what you want, which is a shame. So I would unzip the file to a temp directory, then use another function to copy the contents to where you want. So when using ZipArchive, you will need to return the first item to get the folder name if it is unknown. If the folder is known, ie: the same pesky folder name every time, then you could hard code the name.
I have made it return the first item from the index. So if you ALWAYS have a zip with 1 folder inside it, and everything in that folder, this would work. However, if you have a zip file without everything consolidated inside 1 folder, it would fail. The code I have added will take care of your question. You will need to add further logic to handle alternate cases.
Also, You will still be left with the old directory from when we extract it to the temp directory for "processing". So I included code to delete it too.
NOTE: The code uses a lot of if's to show the processing steps, and print a message for testing purposes. You would need to modify it to your needs.
<?php
public function copyDirectoryContents($source, $destination, $create=false)
{
if ( ! is_dir($source) ) {
return false;
}
if ( ! is_dir($destination) && $create === true ) {
#mkdir($destination);
}
if ( is_dir($destination) ) {
$files = array_diff(scandir($source), array('.','..'));
foreach ($files as $file)
{
if ( is_dir($file) ) {
copyDirectoryContents("$source/$file", "$destination/$file");
} else {
#copy("$source/$file", "$destination/$file");
}
}
return true;
}
return false;
}
public function removeDirectory($directory, $options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file)
{
if (is_dir("$directory/$file"))
{
if(!$options['traverseSymlinks'] && is_link(rtrim($file,DIRECTORY_SEPARATOR))) {
unlink("$directory/$file");
} else {
removeDirectory("$directory/$file",$options);
}
} else {
unlink("$directory/$file");
}
}
return rmdir($directory);
}
$file = dirname(__FILE__) . '/file.zip'; // full path to zip file needing extracted
$temp = dirname(__FILE__) . '/zip-temp'; // full path to temp dir to process extractions
$path = dirname(__FILE__) . '/extracted'; // full path to final destination to put the files (not the folder)
$firstDir = null; // holds the name of the first directory
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$firstDir = $zip->getNameIndex(0);
$zip->extractTo($temp);
$zip->close();
$status = "<strong>Success:</strong> '$file' extracted to '$temp'.";
} else {
$status = "<strong>Error:</strong> Could not extract '$file'.";
}
echo $status . '<br />';
if ( empty($firstDir) ) {
echo 'Error: first directory was empty!';
} else {
$firstDir = realpath($temp . '/' . $firstDir);
echo "First Directory: $firstDir <br />";
if ( is_dir($firstDir) ) {
if ( copyDirectoryContents($firstDir, $path) ) {
echo 'Directory contents copied!<br />';
if ( removeDirectory($directory) ) {
echo 'Temp directory deleted!<br />';
echo 'Done!<br />';
} else {
echo 'Error deleting temp directory!<br />';
}
} else {
echo 'Error copying directory contents!<br />';
}
} else {
echo 'Error: Could not find first directory';
}
}
I am extracting a zip file in PHP and trying to rename it to content.txt. Here is my code:
if($this->copyFile($this->src,$this->dest)) {
$this->log .= "Successfully copied the file. Starting unzip.<br />";
$res = $this->zip->open($this->dest);
if ($res === TRUE) {
$this->zip->extractTo("/htdocs/content-refresh/");
$this->extracted = $this->zip->getNameIndex(0);
$this->log .= "Extracted ".$this->extracted." onto our server.<br />";
if($this->zip->renameIndex(0,'content.txt')) {
$this->log .= "Renamed update file to content.txt.<br />";
} else {
$this->log .= "Could not rename update file to content.txt.<br />";
}
$this->zip->close();
$this->log .= "The update file is ready to go. Now you can use the update functions.<br />";
} else {
$this->log .= "Could not unzip the file.<br />";
}
}
Here is the file output:
Successfully copied the file. Starting unzip.
Extracted Hotel_All_Active 01-19-11.txt onto our server.
Renamed update file to content.txt.
The update file is ready to go. Now you can use the update functions.
The problem is that it does not rename the file. I have also tried:
$this->zip->renameName(strval($this->extracted),'content.txt')
But that also prints out that it renamed the file, but does not. Am I doing something wrong here, or is this function buggy?
The renameIndex() function is for renaming a file inside an archive.
Looking at the code in the PHP Manual for that function, it's you can see it's modifying the archive:
$zip = new ZipArchive;
$res = $zip->open('test.zip');
if ($res === TRUE) {
$zip->renameIndex(2,'newname.txt');
$zip->close();
} else {
echo 'failed, code:' . $res;
}
You need to use the rename() function instead.