【问题标题】:PHP - ZipArchive() permission issues with clean upPHP - ZipArchive() 清理权限问题
【发布时间】:2018-09-07 13:29:58
【问题描述】:

我一直有 - 我认为权限问题 - 解压缩文件(这部分没问题)并将内容移动到写入文件夹。

我正在运行简单的代码:

$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!" );
}

其中rmove() 是一个简单的递归函数,它遍历内容并将rename() 应用于每个文件。

问题是解压缩顺利,文件被复制,但没有移动 - 从临时文件夹中删除。到目前为止,我读到这可能是由于在重命名时没有对解压缩文件的写权限。

解压时如何控制这些权限?

更新: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 );
}

【问题讨论】:

  • 您是否收到任何错误消息
  • 否 - 根本没有错误消息 -
  • 请添加rmove()的内容...
  • 您的问题与移动dist 目录有关吗?使用unlink() 无法删除目录;但是,正如下面提到的@t.m.adam,您必须使用rmdir()。当我运行您的代码时,我得到“PHP 警告:unlink(/path/to/dist): Is a directory in ... on line ...”。

标签: php permissions ziparchive


【解决方案1】:

据我所知ZipArchive::extractTo 没有设置任何特殊的写入/删除权限,因此您应该拥有对提取文件的完全访问权限。

您的代码的问题是rmove 函数。您正在尝试使用unlink 删除目录,但unlink 删除了文件。您应该使用rmdir 删除目录。

如果我们解决了这个问题,您的 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) && !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);
}

您不必删除循环中的每个子文件夹,最后的 rmdir 将删除所有文件夹,因为这是一个递归函数。

如果您仍然无法删除文件夹的内容,那么您可能没有足够的权限。我认为这不太可能,但在这种情况下,您可以尝试chmod

【讨论】:

    【解决方案2】:

    我只是想知道 $target.'/dist' 目录。我假设“dist”目录来自存档。已经指出,我可以看到“rmove”函数很容易在创建文件之前将文件复制到目标目录。您的代码假定该目录将取代迭代器中的文件。如果文件路径取代了目录,则目标目录将不存在以复制文件。

    我建议您使用自定义编写的递归“rmove”函数的替代函数,即 RecursiveDirectoryIterator。

    http://php.net/manual/en/class.recursivedirectoryiterator.php

    让我用 RecursiveDirectoryIterator 简化你的代码,如下所示

    $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());
    
        }
    
    }
    

    请检查是否仍然出现权限错误。

    【讨论】:

      猜你喜欢
      • 2016-07-17
      • 2020-09-05
      • 1970-01-01
      • 2010-12-16
      • 2018-09-17
      • 2018-06-09
      • 2019-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多