PHP ZipArchive无法在Windows下运行的Ubuntu Linux上提取文件

时间:2017-06-14 12:56:40

标签: php linux windows ubuntu zip

我收到以下警告

PHP Warning:  ZipArchive::extractTo(/mnt/c/some/folder\data.json):
failed to open stream: Invalid argument in /mnt/c/somefile.php on line 54

使用此代码,在运行PHP 7.1的Windows上使用Ubuntu子系统解压缩任何zip文件:

<?php
class someClass
{
    public static function unzip($fn, $to = null)
    {
        $zip = new ZipArchive;

        if (is_null($to)) {
            $to = self::dirname($fn) . DIRECTORY_SEPARATOR . self::filename($fn);
        }

        if (!is_dir($to)) {
            self::mkdir($to, 0755, true);
        }

        $res = $zip->open($fn);
        if ($res === true) {
            $zip->extractTo($to);
            $zip->close();
            return $to;
        } else {
            return false;
        }
    }
}

?>

相同的代码在Windows下的PHP 7.1和Linux下的PHP 7.1(CentOS)下运行良好。

1 个答案:

答案 0 :(得分:0)

问题是zip文件名中的正斜杠。

使用以下内容似乎解决了这个问题:

<?php

class someClass
{
    public static function unzip($fn, $to = null)
    {
        $zip = new ZipArchive;
        $ds  = DIRECTORY_SEPARATOR;
        if (is_null($to)) {
            $to = self::dirname($fn) . $ds . self::filename($fn);
        }

        $to = self::slashes($to);

        if (!is_dir($to)) {
            self::mkdir($to, 0755, true);
        }

        $res = $zip->open($fn);
        if ($res === true) {
            for ($i = 0; $i < $zip->numFiles; $i++) {
                $ifn = self::slashes($zip->getNameIndex($i));
                if (!is_dir(self::dirname($to . $ds . $ifn))) {
                    self::mkdir(self::dirname($to . $ds . $ifn), 0755, true);
                }

                $fp  = $zip->getStream($zip->getNameIndex($i));
                $ofp = fopen($to . $ds . $ifn, 'w');

                if (!$fp) {
                    throw new \Exception('Unable to extract the file.');
                }

                while (!feof($fp)) {
                    fwrite($ofp, fread($fp, 8192));
                }

                fclose($fp);
                fclose($ofp);
            }
            $zip->close();
            return $to;
        } else {
            return false;
        }
    }

    public static function slashes($fn)
    {
        return str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $fn);
    }
?>