I keep having - I think permission issues - with unzipping a file (this part goes OK) and moving content to write folder.
I am running simple code:
$zip = new ZipArchive( );
$x = $zip->open( $file );
if ( $x === true ) {
$zip->extractTo( $target );
$zip->close( );
unlink( $file );
rmove( __DIR__ . '/' . $target . '/dist', __DIR__ );
} else {
die( "There was a problem. Please try again!" );
}
where rmove()
is a simple recursive function that iterates thru content and applies rename()
to each file.
Problem is that unzipping goes well, files are copied, but not moved - delete from a temporary folder. I read so far that could be caused by not having a write permission to unzipped files at the time of renaming.
How to control those permissions at the time of unzipping?
Update: content of rmove():
function rmove( $src, $dest ) {
// If source is not a directory stop processing
if ( ! is_dir( $src ) ) return false;
// If the destination directory does not exist create it
if ( ! is_dir( $dest ) ) {
if ( ! mkdir( $dest ) ) {
// If the destination directory could not be created stop processing
return false;
}
}
// Open the source directory to read in files
$i = new DirectoryIterator( $src );
foreach( $i as $f ) {
if ( $f->isFile( ) ) {
echo $f->getRealPath( ) . '<br/>';
rename( $f->getRealPath( ), "$dest/" . $f->getFilename( ) );
} else if ( ! $f->isDot( ) && $f->isDir( ) ) {
rmove( $f->getRealPath( ), "$dest/$f" );
unlink( $f->getRealPath( ) );
}
}
unlink( $src );
}
As far as I'm aware ZipArchive::extractTo
doesn't set any special write/delete permissions, so you should have full access to the extracted files.
The issue with your code is the rmove
function. You're trying to remove directories with unlink
, but unlink
removes files. You should use rmdir
to remove directories.
If we fix that issue, your rmove
function works fine.
function rmove($src, $dest) {
// If source is not a directory stop processing
if (!is_dir($src)) {
return false;
}
// If the destination directory does not exist create it
if (!is_dir($dest) && !mkdir($dest)) {
return false;
}
// Open the source directory to read in files
$contents = new DirectoryIterator($src);
foreach ($contents as $f) {
if ($f->isFile()) {
echo $f->getRealPath() . '<br/>';
rename($f->getRealPath(), "$dest/" . $f->getFilename());
} else if (!$f->isDot() && $f->isDir()) {
rmove($f->getRealPath(), "$dest/$f");
}
}
rmdir($src);
}
You don't have to remove every subfolder in the loop, the rmdir
at the end will remove all folders, since this is a recursive function.
If you still can't remove the contents of the folder, then you may not have sufficient permissions. I don't think that's very likely, but in that case you could try chmod
.
I just wonder about the $target.'/dist' directory. I assume that the 'dist' directory is coming from the archive. Having pointed out that I can see the 'rmove' function is prone to copy a file to a destination directory before it is created. Your code assumes that the directory will supersede the files in the iterator. If the file path supersedes the directory the destination directory won't exist to copy the file.
I would suggest you an alternative function to your custom written recursive 'rmove' function, which is the RecursiveDirectoryIterator.
http://php.net/manual/en/class.recursivedirectoryiterator.php
Let me simplify your code with RecursiveDirectoryIterator as follows
$directory = new \RecursiveDirectoryIterator( __DIR__ . '/' . $target . '/dist', RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directory);
foreach ($iterator as $f) {
if($f->isFile()){
if(!empty($iterator->getSubpath()))
@mkdir(__DIR__."/" . $iterator->getSubpath(),0755,true);
rename($f->getPathname(), __DIR__."/" . $iterator->getSubPathName());
}
}
Please check to see whether you still get the permission error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.