2017-06-14 92 views
1
下运行

我得到以下警告PHP ZipArchive未能提取在Ubuntu Linux文件时,Windows

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

有了这个代码,提取使用的是Ubuntu子系统在Windows上的任何zip文件运行PHP 7.1:

<?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; 
     } 
    } 
} 

?> 

在Linux(CentOS)下的Windows和PHP 7.1下,相同的代码在PHP 7.1下正常工作。

+0

_Just傻点:_你设置'$ DS = DIRECTORY_SEPARATOR;'然后从不使用'$ ds'但你用'DIRECTORY_SEPARATOR'? ? – RiggsFolly

+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); 
    } 
?>