我正在建立一个php脚本,将大型文件从本地php服务器上传到远程ftp服务器,并在mysql库中记录进度。 Evrything工作正常,但我的恢复功能有问题,我找不到任何关于恢复ftl上传与curl的过程的明确信息。我的代码如下:
$fp = fopen($localfile, 'r');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_NOPROGRESS, false);
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curlProgressCallback'); // lof progress to base
curl_setopt($curl, CURLOPT_READFUNCTION, 'curlAbortCallback'); // check if user request abort
curl_setopt($curl, CURLOPT_URL, $ftp);
curl_setopt($curl, CURLOPT_PORT, FTPPort);
curl_setopt($curl, CURLOPT_LOW_SPEED_LIMIT, 1000);
curl_setopt($curl, CURLOPT_LOW_SPEED_TIME, 20);
curl_setopt($curl, CURLOPT_USERPWD, FTPLog . ":" . FTPPass);
curl_setopt($curl, CURLOPT_FTP_CREATE_MISSING_DIRS, true);
curl_setopt($curl, CURLOPT_UPLOAD, 1);
if($resume){
$startFrom=ftpFileSize($dest); // return the actual file size on the ftp server
}else{
$startFrom=false;
}
if($startFrom){
curl_setopt ($curl, CURLOPT_FTPAPPEND, 1);
curl_setopt($curl, CURLOPT_RESUME_FROM, $startFrom);
fseek($fp, $startFrom, SEEK_SET);
$sizeToUp=filesize($localfile);//-$startFrom;
}else{
$sizeToUp=filesize($localfile);
}
curl_setopt($curl, CURLOPT_INFILE, $fp);
curl_setopt($curl, CURLOPT_INFILESIZE, $sizeToUp);
curl_exec($curl);
如果有人打电话给我这方面的帮助,或者重定向我一个有效的例子,那将非常有帮助和欣赏。
提出反馈意见
先生
答案 0 :(得分:0)
我不认为cURL& PHP可以做到这一点。
您使用的是Linux吗?如果是这样看看aria2。它支持可恢复连接并支持FTP。我不确定它是否会完全符合您的要求。
答案 1 :(得分:0)
所以我中止了我的研究,用卷曲制作简历,而不是帮助或文件, 使用ftp_nb_put来实现它真的更容易。所以我可以帮助别人,你可以找到我的最终代码的例子:
define("FTPAdd","your serveur ftp address");
define("FTPPort",21);
define("FTPTimeout",120);
define("FTPLog","your login");
define("FTPPass","your password");
function ftpUp_checkForAndMakeDirs($ftpThread, $file) {
$parts = explode("/", dirname($file));
foreach ($parts as $curDir) {
if (@ftp_chdir($ftpThread, $curDir) === false) { // Attempt to change directory, suppress errors
ftp_mkdir($ftpThread, $curDir); //directory doesn't exist - so make it
ftp_chdir($ftpThread, $curDir); //go into the new directory
}
}
}
function ftpUp_progressCallBack($uploadedData){
global $abortRequested;
//you can do any action you want while file upload progress, personaly, il log progress in to data base
//and i request DB to know if user request a file transfert abort and set the var $abortRequested to true or false
}
function ftpUp($src,$file,$dest,$resume){
global $abortRequested;
$conn_id = ftp_connect(FTPAdd,FTPPort,FTPTimeout);
if ($conn_id==false){
echo "FTP Connection problem";return false;
}else{
$login_res = ftp_login($conn_id, FTPLog, FTPPass);
if ($login_res){
$ftpThread=$conn_id;
}else{
echo "FTP Authentification error";return false;
}
}
$fp = fopen($src, 'r');
ftpUp_checkForAndMakeDirs($ftpThread, $dest); //verif et creation de l'arborescence sur le serveur ftp
ftp_set_option ($ftpThread, FTP_AUTOSEEK, TRUE); // indispensable pour pouvoir faire du resume
if($resume){
$upload = ftp_nb_fput ($ftpThread, $file, $fp ,FTPUpMode, FTP_AUTORESUME);
}else{
$upload = ftp_nb_fput ($ftpThread, $file, $fp ,FTPUpMode);
}
///////////////////////////////////////////////////////////////////////////////////
//uploading process
while ($upload == FTP_MOREDATA) {
//progress of upload
ftpUp_progressCallBack(ftell ($fp));
//continue or abort
if(!$abortRequested){
$upload = ftp_nb_continue($ftpThread);
}else{
$upload = "userAbort";
}
}
///////////////////////////////////////////////////////////////////////////////////
//end and result
ftpUp_progressCallBack(ftell ($fp));
if ($upload != FTP_FINISHED) {
@fclose($fp);
@ftp_close ($ftpThread);
if ($abortRequested){
echo "FTP Abort by user : resume needed";
}else{
echo "FTP upload error : ".$upload." (try resume)";
}
}else{
@fclose($fp);
@ftp_close ($ftpThread);
echo "upload sucess";
}
}
$file="test.zip";
$src = "FilesToUp/" . $file;
$destDir = "www/data/upFiles/";
$dest = $destDir . $file;
$abortRequested=false;
ftpUp($src,$file,$dest,true);
答案 2 :(得分:0)
我正在寻找一个可行的答案,使用CURL + PHP来恢复被破坏的传输,并且无法在互联网上找到明确,可行的解决方案。这是一个老问题,但我认为它确实需要一个正确的答案。这是一两天研究的结果。请参阅以下功能和快速使用示例。
连接功能:
function ftp_getconnect($uName, $pWord, $uHost)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, "$uName:$pWord");
curl_setopt($ch, CURLOPT_URL, $uHost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$return = curl_exec($ch);
if($return === false)
{
print_r(curl_getinfo($ch));
echo curl_error($ch);
curl_close($ch);
die('Could not connect');
}
else
{
return $ch;
}
}
断开连接功能:
function ftp_disconnect($ch)
{
$return = curl_close($ch);
if($return === false)
{
return "Error: Could not close connection".PHP_EOL;
}
else
{
return $return;
}
}
获取远程文件大小的函数(以字节为单位):
function get_rem_file_size($ch, $rem_file)
{
curl_setopt($ch, CURLOPT_INFILE, STDIN);
curl_setopt($ch, CURLOPT_URL, $rem_file);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FTP_CREATE_MISSING_DIRS, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FTPLISTONLY, false);
$return = curl_exec($ch);
if($return === false)
{
print_r(curl_getinfo($ch));
echo curl_error($ch);
curl_close($ch);
die('Could not connect');
}
else
{
$file_header = curl_getinfo($ch);
return $file_header['download_content_length'];
}
}
上传文件功能:
function upload_file($ch,$local_file,$remote_file,$resume)
{
echo "attempting to upload $local_file to $remote_file".PHP_EOL;
$file = fopen($local_file, 'rb');
if($resume)
{
curl_setopt($ch, CURLOPT_RESUME_FROM, get_rem_file_size($ch, $remote_file));
}
curl_setopt($ch, CURLOPT_URL, $remote_file);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FTP_CREATE_MISSING_DIRS, true);
curl_setopt($ch, CURLOPT_INFILE, $file);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($local_file));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$return = curl_exec($ch);
if($return === false)
{
fclose($file);
return curl_error($ch).PHP_EOL;
}
else
{
fclose($file);
echo $local_file.' uploaded'.PHP_EOL;
return true;
}
}
快速使用示例:
$ftp = ftp_getconnect($uName, $pWord, 'ftp://'.$uHost);
$rem_file = 'ftp://'.$uHost.'/path/to/remote/file.ext';
$loc_file = 'path/to/local/file.ext';
$resume = 'true';
$success = upload_file($ftp, $loc_file, $rem_file, $resume);
if($success !== true)
{
//failure
echo $success;
curl_close($ch);
}
print_r(ftp_disconnect($ftp));
快速注意,如果有大量文件,您可以循环浏览它们upload_file
,而无需每次连接/断开连接。