PHP 7 SSH2.SFTP stat() ошибка обходной путь
У меня есть приложение, которое использует соединение SFTP для загрузки файлов. Он работал правильно в PHP 5.6, а не в PHP 7. Я получаю следующее сообщение об ошибке:
Предупреждение PHP: filesize(): сбой статистики для 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;
}
}
После некоторых исследований я обнаружил, что есть проблема с stat ():
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)
2 ответа
Цитирование PHP ssh2.sftp opendir/readdir исправить,
Вместо того, чтобы использовать
"ssh2.sftp://$sftp"
в качестве пути потока конвертируйте $sftp в целое число следующим образом:"ssh2.sftp://" . intval($sftp) . "/"
, Тогда все будет работать нормально.
Причина изменения заключается в следующем:
PHP 5.6.28 (и, по-видимому, 7.0.13) представил исправление безопасности при разборе URL, из-за которого интерполяция строк дескриптора ресурса $sftp больше не распознавалась как действительный URL. В свою очередь, это приводит к сбою opendir(), readdir() и т. Д. При использовании ресурса $sftp в строке пути после обновления до одной из этих версий PHP.
Что касается других библиотек... только другая библиотека, о которой я знаю, это phpseclib, у которой есть своего рода эмулятор для libssh2:
https://github.com/phpseclib/libssh2-compatibility-layer
Этот "эмулятор", безусловно, может быть улучшен. Как файл composer.json должен быть добавлен и т. Д.
У меня была такая же проблема с php 8.0.
Попробуйте поставить команду "размер файла" перед "fopens".