You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP:ftp_get()函数报错时为何返回true?

Why does ftp_get() return true despite "Failed to open file" warning for .filepart files?

Let's break down this issue by examining the PHP FTP extension source code you referenced:

Key Observations from the Source Code

The behavior you're seeing hinges on two critical factors: PHP version differences and FTP server handling of incomplete files:

1. PHP 5.6 and Earlier: Missing Error Checks

In older PHP versions (like 5.6), the ftp_get() function has a flaw in its error-handling logic. Here's the relevant snippet:

if (php_stream_copy_to_fd(stream, fd, mode) == FAILURE) {
    php_error_docref(NULL, E_WARNING, "Transfer failed");
}

php_stream_close(stream);
VCWD_CLOSE(fd);

RETURN_TRUE;

Notice that even if the file transfer fails (e.g., the remote .filepart file is locked or incomplete), the function unconditionally returns true after triggering a warning. There's no check for the final FTP server response code (like 226, which confirms successful transfer completion).

2. FTP Server Behavior for Incomplete Files

When dealing with an unfinished .filepart file (still being uploaded), some FTP servers may:

  • Accept the RETR command (returning a 1xx/2xx success code, so PHP thinks the command worked)
  • Fail to read the full file content (due to locks or partial data)
  • Send a response message like "Failed to open file" which PHP surfaces as a warning

Since PHP only checks if the initial RETR command succeeded (not the final transfer status), it returns true even though the file wasn't properly downloaded.

3. Local File Edge Cases

In rare scenarios, the "Failed to open file" warning could come from local file system issues (e.g., sudden permission changes after opening the file). However, in the source code, a failed local file open would immediately return false—so this doesn't explain why you're getting true. The far more likely culprit is the combination of old PHP behavior and server-side handling of incomplete files.

Solution

To fix this:

  • Upgrade PHP: Modern PHP versions (7.0+) added checks for the final FTP response code (226) and properly return false if the transfer fails:
    if (ftp_get_last_response_code(&ftp) != 226) {
        php_error_docref(NULL, E_WARNING, "%s", ftp.msg);
        retval = FAILURE;
    }
    
    if (retval == FAILURE) {
        RETURN_FALSE;
    }
    RETURN_TRUE;
    
  • Prevent downloading incomplete files: Before calling ftp_get(), use ftp_nlist() or ftp_size() to verify the remote file isn't a .filepart (or check if its size is stable, indicating upload completion).
  • Add manual validation: After downloading, check if the local file size matches the remote file size (using ftp_size()) to confirm the transfer succeeded.

内容的提问来源于stack exchange,提问作者Lars Moelleken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:53:13