我在这里扯头发。上周我一直在试图弄清楚为什么 ZipArchive extractTo 方法在 Linux 上的行为与在我们的测试服务器 (WAMP) 上的行为不同。
下面是问题的最基本的例子。我只需要提取一个具有以下结构的 zip:
my-zip-file.zip
-username01
--filename01.txt
-images.zip
--image01.png
-songs.zip
--song01.wav
-username02
--filename01.txt
-images.zip
--image01.png
-songs.zip
--song01.wav
以下代码将提取根 zip 文件并将结构保留在我的 WAMP 服务器上。我还不需要担心提取子文件夹的问题。
<?php
if(isset($_FILES["zip_file"]["name"])) {
$filename = $_FILES["zip_file"]["name"];
$source = $_FILES["zip_file"]["tmp_name"];
$errors = array();
$name = explode(".", $filename);
$continue = strtolower($name[1]) == 'zip' ? true : false;
if(!$continue) {
$errors[] = "The file you are trying to upload is not a .zip file. Please try again.";
}
$zip = new ZipArchive();
if($zip->open($source) === FALSE)
{
$errors[]= "Failed to open zip file.";
}
if(empty($errors))
{
$zip->extractTo("./uploads");
$zip->close();
$errors[] = "Zip file successfully extracted! <br />";
}
}
?>
上面脚本在 WAMP 上的输出正确地提取了它(保持文件结构)。
当我在我们的实时服务器上运行它时,输出如下所示:
--username01\filename01.txt
--username01\images.zip
--username01\songs.zip
--username02\filename01.txt
--username02\images.zip
--username02\songs.zip
我不明白为什么它在实时服务器上的行为不同。任何帮助将不胜感激!
最佳答案
要修复文件路径,您可以遍历所有提取的文件并移动它们。
假设在所有提取文件的循环中,您有一个包含文件路径的变量 $source
(例如 username01\filename01.txt
),您可以执行以下操作:
// Get a string with the correct file path
$target = str_replace('\\', '/', $source);
// Create the directory structure to hold the new file
$dir = dirname($target);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
// Move the file to the correct path.
rename($source, $target);
编辑
在执行上述逻辑之前,您应该检查文件名中的反斜杠。使用迭代器,您的代码应如下所示:
// Assuming the same directory in your code sample.
$dir = new DirectoryIterator('./uploads');
foreach ($dir as $fileinfo) {
if (
$fileinfo->isFile()
&& strpos($fileinfo->getFilename(), '\\') !== false // Checking for a backslash
) {
$source = $fileinfo->getPathname();
// Do the magic, A.K.A. paste the code above
}
}
关于php - Linux PHP ExtractTo 返回整个路径而不是文件结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32698752/