2020-04-23 后记:疑似是前置的负载均衡服务器有问题,改为直接使用真实 IP 后问题消失。
代码语言:javascript复制PHP Warning: ftp_put(): php_connect_nonb() failed: Operation now in progress (115) in ...
环境 PHP 5.6.40
。在开发过程中遇到了一个很诡异的情况,在使用 FTP 函数上传文件时,会间歇性无法上传文件。找了几圈有说是 PHP bug、有说是防火墙,都不解决问题。
最后找到了一篇 Why is my PHP script intermittently unable to upload a file via FTP? | stackoverflow 解了大急。(当搜索结果没有找到答案时,可以考虑换几个相近的词再试试)
解决方法:进行循环调用尝试。
代码语言:javascript复制// 尝试 5 次
$uploaded = false;
$tries = 0;
while (!$uploaded && $tries <= 5) {
$tries;
$conn = ftp_ssl_connect($host, $port, 10) or die('FTP服务器连接失败');
//登陆(通过用户名或者匿名登陆)
$result = ftp_login($conn, $user, $password);
if (!$result) {
ftp_close($conn);
die('ftp_login 失败');
}
ftp_set_option($conn, FTP_USEPASVADDRESS, false);
// turn passive mode on
ftp_pasv($conn, true);
$success = ftp_put($conn, $remoteFile, $localFile, FTP_BINARY);
if ($success) {
$uploaded = true;
dump("ftp upload: $success, $remoteFile, $localFile");
} else {
dump("ftp upload failed, tries: $tries");
}
ftp_close($conn);
}
循环 try 第二次就成功了,不知为啥。PHP の FTP(S)通信で php_connect_nonb() failed: Operation now in progress (115) | qiita 这篇文章有分析,读后还是不太清楚,望有缘人来指导。
どうやら Operation now in progress (115)は EINPROGRESS から来ているらしい。常に非同期で connect するため最初の connect で EINPROGRESS が帰るのは正常だが、asynchronous=true の場合その後同期処理のために poll で接続完了を待つ。だが poll はエラーが起きても errno を更新しないため、接続に失敗したとき errno=EINPROGRESS の状態で返ってしまっているように見える。
– EOF –
- # php