【问题标题】:Linux PHP ExtractTo returns whole path instead of the file structureLinux PHP ExtractTo 返回整个路径而不是文件结构
【发布时间】:2015-09-21 15:13:38
【问题描述】:

我在这里拉头发。上周我一直在试图弄清楚为什么 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

我无法弄清楚为什么它在实时服务器上的行为不同。任何帮助将不胜感激!

【问题讨论】:

  • 嘿@Zachary。我不清楚到底是什么问题。您想在两个系统中递归提取 zip 吗?
  • 感谢您的回复!问题是linux在我提取zip文件时破坏了文件结构.....我相信它与反斜杠有关,但我不知道如何让它使用正斜杠来保留目录结构
  • 我想我遇到了问题:斜杠成为 Linux 文件名的一部分。是吗?
  • 正确...需要有一个名为 username01 的文件夹,然后在该文件夹内应该有 filename01.txt 和 images.zip 和 song.zip....脚本在 windows WAMP 上完美运行。
  • 好的。我添加了一个可能的解决方案作为回答。

标签: php linux


【解决方案1】:

要修复文件路径,您可以遍历所有提取的文件并移动它们。

假设在所有提取文件的循环中,您有一个包含文件路径的变量$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

    }
}

【讨论】:

  • 仍然做同样的事情。我不认为 mkdir 函数和 rename 函数有任何作用。我会发布我的代码,但它不适合评论。
  • @Zachary,您可以添加您尝试过的代码来更新您的问题。
  • 我可以得到你的电子邮件地址吗?上面的代码比实际代码更具概念性。我想把实际的代码发给你。
  • @Zachary,很抱歉,我们不允许在此处发布电子邮件地址:meta.stackexchange.com/questions/37956/…。但是,您可以在我的个人资料中看到我的联系人。无论如何,我已经再次更新了我的答案,添加了一些有关如何迭代提取的文件的详细信息。
  • 你摇滚!有用!我想保持联系,因为我们一直需要 PHP 开发人员来开发项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多