2017-06-14 59 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); 
    } 
?>