2016-12-01 82 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發生了奇怪的事情。現在我只花了一個小時解決問題,而不是更多 –