PHP FTP 间歇性无法上传文件

2023-08-23 18:39:03 浏览数 (2)

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

0 人点赞