2015-11-02 91 views
0

我用下面的代码通过FTP在PHP中下载文件:PHP FTP代码失败,即使文件被下载成功

$fp = fopen($local_file, 'w+'); 
$conn_id = ftp_connect($host); 
$login_result = ftp_login($conn_id, $user, $pass); 
$ret = ftp_nb_fget($conn_id, $fp, $remote_file, FTP_BINARY); 

while ($ret == FTP_MOREDATA) { 
    $ret = ftp_nb_continue($conn_id); 
} 

if ($ret != FTP_FINISHED) { 
    echo "<span style='color:red;'><b>There was an error downloading the file!</b></span><br>"; 
    logThis("log.txt", date('h:i:sa'), "ERROR DOWNLOADING FILE!"); 
    exit(); 
} 

fclose($fp); 

<<php code continues below this....>> 

此代码似乎工作的罚款。该文件被下载,并且文件的MD5哈希值与下载之前其他服务器上文件的哈希值相匹配。所以下载完成。

无论如何,使用上面的代码,即使文件成功下载,它也会触发if($ ret!= FTP_FINISHED)条件中的代码。

如果文件下载正常,为什么FTP_FINISHED不正确?

编辑

当我从while循环之后检查$ ret值为,时代脚本完成罚款$ RET = 1和时代脚本失败$ RET = 0

然而,有时候脚本失败,因为当文件实际下载正确时,$ ret = 0,这可以通过MD5比较来确认。

另外,0或1不是应从这些命令返回的值。 PHP官方文档举三个可能的返回值,他们FTP_FAILED或FTP_FINISHED或FTP_MOREDATA

+1

在while循环之后'$ ret'的值是什么? – dstudeba

+0

您是否已验证文件的所有部分已成功传输?对收到的和源文件执行md5验证以确认。 – shrmn

+0

@shrmn我原来的帖子提到我没有比较文件的MD5哈希值,并且该文件确实可以正常下载。 –

回答

0

编辑:

我的第一个解决方案是不正确的。在查看下面的注释之后,我必须说你的代码是正确的,并且问题可能出在“upload_max_size”和“post_max_size”值上。

看到这里 “Upload large files to FTP with PHP”,主要在这里: “Changing upload_max_filesize on PHP

因此,所提出的解决方案是把它添加到.htaccess文件:

php_value upload_max_filesize 2G 
php_value post_max_size 2G 

,或者如果服务器是你(专用),请在php.ini中设置它们(您需要重新启动服务器以使更改生效)。

您也可能会在php.net中找到有用的post_max_size信息。我发现特别有趣的是:

如果POST数据的大小大于post_max_size中,$ _ POST和 $ _FILES超全局是空的。这可以通过各种方式进行跟踪,例如 通过将$ _GET变量传递给处理数据的脚本 即,然后检查是否设置了 $ _GET ['processed']。

+0

我会试试这个。但是,我使用的代码显示在PHP网站的官方示例中,因此我认为它将按预期运行。 –

+0

我以后见过。我明白你的信任。我也是。我在代码中看到的唯一区别是“fopen($ local_file,'w +')”,(write&read),而不是“fopen($ local_file,'w')”。我会说它不会弄乱任何东西,但是......你试过“fopen($ local_file,'w')”吗? – Giuseppe

+0

此代码在小文件上工作正常。但是,当文件大小接近1gb时,会显示错误。拥有w +应该不重要,除了使用+创建的文件(如果不存在),它们会执行相同的操作。没有这个,我需要额外的代码来创建文件。 –

1

我想到了一种解决方案。由于文件确实得到正确下载,也可通过从原始源(我们确实有)的MD5校验确定,我可以修改代码是这样的:

if ($ret != FTP_FINISHED) { 

$localMD5 = md5_file($local_file); 

    if($localMD5 != $remoteMD5){ 
     echo "<span style='color:red;'><b>There was an error downloading the file!</b></span><br>"; 
     logThis("log.txt", date('h:i:sa'), "ERROR DOWNLOADING FILE!"); 
     exit(); 
    } 
} 

在预期脚本完成大多数情况下,这样这块代码永远不会运行。但是,在发生上述错误并且运行此代码的情况下,它可能会验证文件的MD5哈希值,并且只在与原始源文件的MD5不匹配时才运行错误代码。如果MD5匹配,那么无论如何下载成功,所以错误代码不应该运行

+0

它是有道理的。做得好。让我们知道它是否有效。 – Giuseppe