我正在使用PHP的PharData类从tar档案中提取文件,但我看到了一种非常奇怪的行为。这是我正在使用的代码:
$filePattern = "$homeDirectory/*tgz";
$fileArray = glob($filePattern);
$i = 0;
foreach($fileArray as $file) {
$phar = new PharData($file);
$phar->extractTo($homeDirectory."/logs-$i");
array_push($extractedDirectories, $homeDirectory."/logs-$i");
$i++;
}
foreach循环应该提取主目录中的每个归档,并将它们移动到名为“logs- n ”的目录中,其中n是主目录下面的整数,包括0。但是,我得到一个例外陈述:
Encountered error: exception 'PharException' with message 'Extraction from phar "/home/user/file.tgz" failed: Cannot extract "output" to "/home/user/logs-0/output", path already exists'
我的第一个想法是存档包含两个“输出”目录,所以我手动提取存档并检查内容;瞧,只有一个输出目录。我想到的另一个想法是循环可能试图对同一个存档运行两次,但两种情况都没有发生。
重复目录“logs- n ”在循环开始使用特定的tar存档之前不存在。然后它抛出一个异常,说提取它的路径已经存在。
我开始认为我遇到了PharData类或者extractTo方法的某种限制,但php.net上没有任何文档涵盖这样的内容,也没有发现任何涉及某些内容的问题像这样在SO上,这就是为什么我要添加这个。
答案 0 :(得分:3)
好的,所以在我的头撞了一下之后。问题是我没有使用extractTo方法的完整参数集。该方法接受一个必需参数和两个可选参数,第一个可选参数是包含要提取的特定文件名的字符串或数组,第二个可选参数是“覆盖”标志。当我将代码更改为以下内容时:
foreach($fileArray as $file) {
$phar = new PharData($file);
$phar->extractTo($homeDirectory."/logs-$i", null, true);
array_push($extractedDirectories, $homeDirectory."/logs-$i");
$i++;
}
在这里,我只是要求提取所有文件并允许覆盖。一旦我这样做,问题就解决了。如果您阅读此方法的PHP docs,则表示此标志确定是否覆盖现有文件。我不确定为什么要这样做才有必要。最接近的我可以想出为什么会发生这种情况是由于某种原因,extractTo方法在父文件“output”目录首次迭代子日志文件后看到已经存在并失败。