2016-12-01 62 views
4

我有一个应用程序使用SFTP连接来下载文件。这是在PHP 5.6正常工作,与其说是在PHP 7.我得到的错误如下:PHP 7 SSH2.SFTP stat()bug解决

PHP的警告:文件大小():统计失败ssh2.sftp ...

我的代码如下:

public function retrieveFiles($downloadTargetFolder,$remoteFolder = '.') { 

      $fileCount = 0; 

       echo "\nSftpFetcher retrieveFiles\n"; 

     $con = ssh2_connect($this->host,$this->port) or die("Couldn't connect\n"); 
     if($this->pubKeyFile){ 
       $isAuth = ssh2_auth_pubkey_file($con, $this->user, $this->pubKeyFile, $this->privKeyFile); 
     } else { 
       $isAuth = ssh2_auth_password($con, $this->user, $this->pass); 
     }; 


     if ($isAuth) { 

       $sftp = ssh2_sftp($con); 
       $rd = "ssh2.sftp://{$sftp}{$remoteFolder}"; 

       if (!$dir = opendir($rd)) { 
         echo "\nCould not open the remote directory\n"; 
       } else { 
         $files = array(); 
           while (false != ($file = readdir($dir))) { 
            if ($file == "." || $file == "..") 
             continue; 
            $files[] = $file; 
           } 

         if (is_array($files)) { 
          foreach ($files as $remoteFile) { 
               echo "\ncheck file: $remoteFile vs filter: " . $this->filter."\n"; 
           if ($this->filter !== null && strpos($remoteFile,$this->filter) === false) { 
            continue; 
           } 
               echo "file matched\n"; 
           $localFile = $downloadTargetFolder . DIRECTORY_SEPARATOR . basename($remoteFile); 


           //$result = ftp_get($con,$localFile,$remoteFile,FTP_BINARY); 
           $result = true; 
           // Remote stream 
           if (!$remoteStream = @fopen($rd."/".$remoteFile, 'r')) { 
             echo "Unable to open the remote file $remoteFolder/$remoteFile\n"; 
             $return = false; 
           } else { 
             // Local stream 
             if (!$localStream = @fopen($localFile, 'w')) { 
               echo "Unable to open the local file $localFile\n"; 
               $return = false; 
             } else { 
               // Write from our remote stream to our local stream 

               $read = 0; 
               $fileSize = filesize($rd."/".$remoteFile); 
               while ($read < $fileSize && ($buffer = fread($remoteStream, $fileSize - $read))) { 
                 $read += strlen($buffer); 
                 if (fwrite($localStream, $buffer) === FALSE) { 
                   echo "Unable to write the local file $localFile\n"; 
                   $return = false; 
                   break; 
                 } 
               } 


               echo "File retrieved"; 
               // Close 
               fclose($localStream); 
               fclose($remoteStream); 

             } 

           } 

           if ($result) { 
            $fileCount++; 
           } 
          } 
         } 

         ssh2_exec($con, 'exit'); 
         unset($con); 
       } 

     } else { 
       echo "Error authenticating the user ".$this->user."\n"; 
     } 

      return $fileCount; 

    } 
} 

经过一番研究,我发现有一个与统计()的一个问题:

http://dougal.gunters.org/blog/2016/01/18/wordpress-php7-and-updates-via-php-ssh2/ https://bugs.php.net/bug.php?id=71376

我的问题

有一种解决方法,以允许鉴于我目前的代码我通过SFTP下载或有其他库有人可以推荐改为使用?

我的PHP版本: PHP 7.0.8-0ubuntu0.16.04.3(CLI)(NTS)

回答

6

引用PHP ssh2.sftp opendir/readdir fix

而不是使用"ssh2.sftp://$sftp"作为流的路径,转换$ SFTP像这样的整数:"ssh2.sftp://" . intval($sftp) . "/"。那么它会工作得很好。

的原因变化如下:

PHP 28年6月5日(显然7.0.13)推出的安全修复程序URL解析,导致该$ SFTP资源的字符串插值处理为不再被识别为有效的URL。反过来,在升级到其中一个PHP版本后,在路径字符串中使用$ sftp资源时,会导致opendir(),readdir()等失败。

至于其他图书馆...只有其他图书馆我所知道的是phpseclib,里面有各种各样的用于libssh2模拟器:

https://github.com/phpseclib/libssh2-compatibility-layer

那“模拟器”当然可以提高在tho。就像一个composer.json文件应该被添加,等等。

+0

刚刚遇到这个,你的答案保存了一天。谢谢! – Revent

+0

谢谢:)在OS更新后,Php 5.6,intval发生了奇怪的事情。现在我只花了一个小时解决问题,而不是更多 –