/** * FTP-文件下载 * * @param string $local_file 本地文件 * @param string $ftp_file Ftp文件 * * @return bool */ public function download($local_file, $ftp_file) { if (empty($local_file) || empty($ftp_file)) { return false; } $ret = ftp_nb_get($this->linkid, $local_file, $ftp_file, FTP_BINARY); while ($ret == FTP_MOREDATA) { $ret = ftp_nb_continue($this->linkid); } if ($ret != FTP_FINISHED) { return false; } return true; }
function down($file, $name = "") { if (!$file) { return false; } if (!$name) { $name = basename($file); } $rs = ftp_nb_get($this->conn, $file, $file, FTP_BINARY); while ($res == FTP_MOREDATA) { $res = ftp_nb_continue($this->conn); } if ($res == FTP_FINISHED) { return true; } elseif ($res == FTP_FAILED) { return false; } }
/** * 下载文件(支持全新下载和断点下载) * @uses $exist = file_exists($local) <br> * <pre> * 1、指定的本地文件存在 * 1.1全新:选定了全新下载,但指定的本地文件已存在 * (开发者可根据此状态来询问客户端是否需要覆盖本地文件)<br> * (当客户端决定覆盖上传时,应该先使服务器备份指定的本地文件,再继续全新下载)<br> * 1.2续传:正常执行断点下载 * 2、指定的本地文件不存在 * 2.1全新:正常执行全新下载 * 2.2续传:选定了断点下载,但指定的本地文件不存在 * (开发者可根据此状态来询问客户端是否要继续下载)<br> * (当客户端决定继续下载时,应该采用全新下载方式)<br> * </pre> * @param string $local 本地文件路径(如e:\abc\def.txt或./a/b/c.txt) * @param string $remote 远程文件全路径(如/a/b/c.txt) * @param boolean $isContinue 是否断点续传,默认为false,全新下载 * @return int 下载状态<br> * AiFtpStatus::DOWNLOAD_FILE_SUCCESS为上传成功,<br> * 其它值为下载失败。<br> * 上传失败的原因一般有:连接断开、编码错误、远程文件不存在、本地文件已存在等等<br> */ function downloadFile($local, $remote, $isContinue = false) { $local = $this->scriptToFsCharset($local); $remote = $this->upcharconv($remote); if (-1 == ftp_size($this->stream, $remote)) { return $isContinue ? AiFtpStatus::DOWNLOAD_HALF_FILE_HASNO_REMOTEFILE : AiFtpStatus::DOWNLOAD_NEW_FILE_HASNO_REMOTEFILE; } $ret = null; if (file_exists($local)) { if (!$isContinue) { return AiFtpStatus::DOWNLOAD_NEW_FILE_EXIST_LOCALFILE; } //ftp_set_option($this->stream, FTP_AUTOSEEK, false);//禁止自动搜寻断点开始处 @($ret = ftp_nb_get($this->stream, $local, $remote, FTP_BINARY, filesize($local))); } else { if ($isContinue) { return AiFtpStatus::DOWNLOAD_HALF_FILE_HASNO_LOCALFILE; } @($ret = ftp_nb_get($this->stream, $local, $remote, FTP_BINARY)); } while (FTP_MOREDATA == $ret) { $ret = ftp_nb_continue($this->stream); } if (FTP_FINISHED != $ret) { return $isContinue ? AiFtpStatus::DOWNLOAD_HALF_FILE_UN_FINISH : AiFtpStatus::DOWNLOAD_NEW_FILE_UN_FINISH; } return AiFtpStatus::DOWNLOAD_FILE_SUCCESS; }
<?php require 'server.inc'; $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) { die("Couldn't connect to the server"); } $local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_get_large.txt"; touch($local_file); ftp_nb_get($ftp, $local_file, 'fget_large.txt', FTP_BINARY, 5368709119); $fp = fopen($local_file, 'r'); fseek($fp, 5368709119); var_dump(fread($fp, 1)); var_dump(filesize($local_file)); fclose($fp); @unlink(dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_get_large.txt");
function ftp_get_file($opts, $pipe = false, $cmd = __FUNCTION__) { # set prefix $prefix = 'ftp'; # merge opts $opts = merge_opts($opts, $pipe, 'remote_file'); # get execute opt $execute = get_opt_config_value($prefix, $opts, 'execute', true); if (!check_opt_set_type($cmd, $execute, 'execute', 'boolean')) { return false; } # check if we should execute or not if (!$execute) { return true; } # get remote file opt $remote_file = get_opt($prefix, $opts, 'remote_file'); if (!check_opt_set_type($cmd, $remote_file, 'remote_file', 'string')) { return false; } # get local file opt $local_file = get_opt($prefix, $opts, 'local_file', $remote_file); if (!check_opt_set_type($cmd, $local_file, 'local_file', 'string')) { return false; } # get get retries opt $get_retries = get_opt_config_value($prefix, $opts, 'get_retries', 3); if (!check_opt_set_type($cmd, $get_retries, 'get_retries', 'integer')) { return false; } # get download progress update opt $download_progress_update = get_opt_config_value($prefix, $opts, 'download_progress_update', true); if (!check_opt_set_type($cmd, $download_progress_update, 'download_progress_update', 'boolean')) { return false; } # check to see if we shall re-use the file if it already exists if (is_file($local_file)) { $use_saved_file = get_opt_config_value($prefix, $opts, 'use_saved_file', true); if (!check_opt_set_type($cmd, $use_saved_file, 'use_saved_file', 'boolean')) { return false; } # get backup old downloaded files $backup_old_saved_files = get_opt_config_value($prefix, $opts, 'backup_old_saved_files', true); if (!check_opt_set_type($cmd, $backup_old_saved_files, 'backup_old_saved_files', 'boolean')) { return false; } if ($use_saved_file) { debug_echo($cmd, "using saved file instead of executing the FTP request : {$local_file}"); return array('file' => $local_file); } elseif ($backup_old_saved_files && !backup_file($local_file)) { return error($cmd, "could not backup previously downloaded file : {$local_file}"); } } # setup connection $conn = ftp_get_conn($opts, $cmd); if (!$conn) { return false; } # get connection values $ftp_handle = $conn['handle']; $svr = $conn['svr']; # make the parent dir of local file if (!make_dir(dirname($local_file), $opts, $cmd)) { return false; } # get the size of the remote file $size = ftp_size($ftp_handle, $remote_file); if ($size == -1) { debug_echo($cmd, "fetching file from FTP server : {$remote_file} => {$local_file} (unknown size) ..."); } else { $size_str = human_filesize($size); debug_echo($cmd, "fetching file from FTP server : {$remote_file} => {$local_file} (size: {$size_str}) ..."); } # get the file if ($download_progress_update) { # get the file with a progress monitor (a little slower) for ($j = 0; $j < $get_retries; $j++) { $ret = ftp_nb_get($ftp_handle, $local_file, $remote_file, FTP_BINARY); while ($ret == FTP_MOREDATA) { # get the size of the downloaded file (note: we need to use file handlers otherwise it doesn't work) $fh = fopen($local_file, 'r'); $stat = fstat($fh); $dl_size = $stat['size']; fclose($fh); # print progress download_progress($size, $dl_size); # continue downloading $ret = ftp_nb_continue($ftp_handle); } if ($ret == FTP_FINISHED) { return array('file' => $local_file); } } } else { # get local handle $local_file_handle = fopen($local_file, 'w'); if (!$local_file_handle) { return error($cmd, "could not open local file : {$local_file}"); } # get the file without a progress monitor (a bit quicker) for ($j = 0; $j < $get_retries; $j++) { if (@ftp_fget($ftp_handle, $local_file_handle, $remote_file, FTP_BINARY)) { return array('file' => $local_file); } } fclose($local_file_handle); } return error($cmd, "could not fetch file from FTP server : {$remote_file}"); }
/** * Download a file from FTP server. * * @param string local file * @param string remote file The remote file path. * @param const mode The transfer mode. Must be either <strong>FTP_ASCII</strong> or <strong>FTP_BINARY</strong>. * @param boolean $asynchronous Flag indicating if file transfert should block php application or not. * @return boolean */ public function get($remote, $local = null, $mode = FTP_BINARY, $asynchronous = false) { if ($this->getActive()) { if (!isset($local) || $local == null || !is_string($local) || trim($local) == '') { $local = getcwd() . DIRECTORY_SEPARATOR . basename($remote); } // Get the requested file if ($asynchronous === false) { if (ftp_get($this->_connection, $local, $remote, $mode)) { // If successful, return the path to the downloaded file... return $remote; } else { return false; } } else { $ret = ftp_nb_get($this->_connection, $local, $remote, $mode); while ($ret == FTP_MOREDATA) { // continue downloading $ret = ftp_nb_continue($this->_connection); } if ($ret == FTP_FAILED) { return false; } else { return $remote; } } } else { throw new \Exception('EFtpComponent is inactive and cannot perform any FTP operations.'); } }
/** * Get file * @param $path The remote file path * @param $l Lang * @param $overwrite Overwrite the target file */ public static function getFile($path, $l, $overwrite){ try{ $pathinfo = pathinfo($path); $fs = OCP\Files::getStorage('files'); if($fs->file_exists('/Downloads/' . $pathinfo['basename']) && !$overwrite){ $pathinfo['basename'] = md5(rand()) . '_' . $pathinfo['basename']; } $size = self::getRemoteFileSize($path); if($size == 0){ OC_ocDownloaderPB::setError($l->t('Filesize is null')); self::closeConnection(); exit(); } $chunkSize = self::getChunkSize($size); $received = $last = 0; $ret = ftp_nb_get(self::$conn, $fs->getLocalFile('/Downloads/' . $pathinfo['basename']), $path, FTP_BINARY); while($ret == FTP_MOREDATA){ $received += $fs->filesize('/Downloads/' . $pathinfo['basename']); if($received >= $size){ $percent = 100; }else{ $percent = @round(($received/$size)*100, 2); } if($received > $last + $chunkSize){ OC_ocDownloaderPB::setProgressBarProgress($percent); $last = $received; } usleep(100); $ret = ftp_nb_continue(self::$conn); } if($ret != FTP_FINISHED){ OC_ocDownloaderPB::setError($l->t('Download error')); self::closeConnection(); exit(); }else{ OC_ocDownloaderPB::setProgressBarProgress(100); OC_ocDownloader::setUserHistory($pathinfo['basename'], 1); } self::closeConnection(); }catch(exception $e){ OC_ocDownloaderPB::setError($l->t('Unknown error')); } }
<?php $ftp = null; var_dump(ftp_connect(array())); var_dump(ftp_connect('127.0.0.1', 0, -3)); var_dump(ftp_raw($ftp)); var_dump(ftp_mkdir($ftp)); var_dump(ftp_rmdir($ftp)); var_dump(ftp_nlist($ftp)); var_dump(ftp_rawlist($ftp)); var_dump(ftp_fget($ftp)); var_dump(ftp_nb_fget($ftp)); var_dump(ftp_nb_get($ftp)); var_dump(ftp_pasv($ftp)); var_dump(ftp_nb_continue()); var_dump(ftp_fput()); var_dump(ftp_nb_fput($ftp)); var_dump(ftp_put($ftp)); var_dump(ftp_nb_put($ftp)); var_dump(ftp_size($ftp)); var_dump(ftp_mdtm($ftp)); var_dump(ftp_rename($ftp)); var_dump(ftp_site($ftp)); var_dump(ftp_set_option($ftp)); var_dump(ftp_get_option($ftp));
<?php require 'server.inc'; $file = "mediumfile.txt"; $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) { die("Couldn't connect to the server"); } $local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . $file; touch($local_file); $r = ftp_nb_get($ftp, $local_file, $file, FTP_BINARY); while ($r == FTP_MOREDATA) { $r = ftp_nb_continue($ftp); } ftp_close($ftp); echo file_get_contents($local_file); error_reporting(0); @unlink(dirname(__FILE__) . DIRECTORY_SEPARATOR . "mediumfile.txt");
protected function nb_get($localfile, $remotefile, $start = FTP_AUTORESUME) { clearstatcache(); if (!file_exists($localfile)) { $start = 0; } $ret = @ftp_nb_get($this->connexion, $localfile, $remotefile, FTP_BINARY, $start); while ($ret === FTP_MOREDATA) { set_time_limit(20); $ret = ftp_nb_continue($this->connexion); } return $ret; }
/** * @param $local * @param $path * * @return bool */ public function get($local, $path) { $path = $this->getPath($path); $mode = $this->getFileMode($path); // Non-blocking mode if (@function_exists('ftp_nb_get')) { $resource = $this->getResource(); $res = @ftp_nb_get($resource, $local, $path, $mode); while ($res == FTP_MOREDATA) { $res = @ftp_nb_continue($resource); } $return = $res === FTP_FINISHED; } else { $return = @ftp_get($this->_handle, $local, $path, $mode); } if (!$return) { throw new DriverException(sprintf('Unable to get "%s" to "%s"', $path, $local)); } return true; }
/** * FTP中文件下载到本地 * * @params array $params 参数 array('local'=>'本地文件路径','remote'=>'远程文件路径','resume'=>'文件指针位置') * @params string $msg * @return bool */ public function pull($params, &$msg) { if ($this->ftp_extension) { $ret = ftp_nb_get($this->conn, $params['local'], $params['remote'], $this->mode, $params['resume']); while ($ret == FTP_MOREDATA) { $ret = ftp_nb_continue($this->conn); } } else { $ret = $this->ftpclient->download($params['remote'], $params['local'], $this->mode, $params['resume']); } if ($ret == FTP_FAILED || $ret === false) { $msg = app::get('importexport')->_('FTP下载文件失败'); return false; } return true; }
public function get($local, $path) { $path = $this->path($path); // Get mode $mode = $this->getFileMode($path); // Non-blocking mode if (@function_exists('ftp_nb_get')) { $resource = $this->getResource(); $res = @ftp_nb_get($resource, $local, $path, $mode); while ($res == FTP_MOREDATA) { //$this->_announce('nb_get'); $res = @ftp_nb_continue($resource); } $return = $res === FTP_FINISHED; } else { $return = @ftp_get($this->_handle, $local, $path, $mode); } // Error if (!$return) { throw new Engine_Vfs_Adapter_Exception(sprintf('Unable to get "%s" to "%s"', $path, $local)); } return true; }
/** * * 从 FTP 服务器上获取文件并写入本地文件(non-blocking) * * @param string $local_file * @param string $remote_file * @param int $mode * @param int $resumepos * @return int 返回 FTP_FAILED,FTP_FINISHED 或 FTP_MOREDATA */ public static function nbGet($local_file, $remote_file, $mode = FTP_ASCII, $resumepos = 0) { return ftp_nb_get(self::$resource, $local_file, $remote_file, $mode, $resumepos); }
/** * @see RemoteDriver::get($mode, $remote_file, $local_file, $asynchronous) */ public function get($remote_file, $local_file = null, $mode = FTP_ASCII, $asynchronous = false) { $this->connectIfNeeded(); if (!isset($local_file) || $local_file == null || !is_string($local_file) || trim($local_file) == "") { $local_file = getcwd() . DIRECTORY_SEPARATOR . basename($remote_file); } $this->param = array('remote_file' => $remote_file, 'local_file' => $local_file, 'asynchronous' => $asynchronous); if ($asynchronous !== true) { if (!ftp_get($this->handle, $local_file, $remote_file, $mode)) { throw new FtpException(Yii::t('gftp', 'Could not synchronously get file "{remote_file}" from server "{host}"', ['host' => $this->host, 'remote_file' => $remote_file])); } } else { $ret = ftp_nb_get($this->handle, $local_file, $remote_file, $mode); while ($ret == FTP_MOREDATA) { // continue downloading $ret = ftp_nb_continue($this->handle); } if ($ret == FTP_FAILED) { throw new FtpException(Yii::t('gftp', 'Could not asynchronously get file "{remote_file}" from server "{host}"', ['host' => $this->host, 'remote_file' => $remote_file])); } } return realpath($local_file); }
/** * Retrieves a file from the server and writes it to a local file * @link http://php.net/ftp_nb_get * * @param string $localFile The local file path * @param string $remoteFile The remote file path * @param integer $mode The transfer mode (FTPWrapper::ASCII, FTPWrapper::BINARY) * @param integer $resumepos The position in the remote file to start downloading from * @return integer FTPWrapper::FAILED, FTPWrapper::FINISHED or FTPWrapper::MOREDATA */ public function getNb($localFile, $remoteFile, $mode = self::BINARY, $resumepos = 0) { return ftp_nb_get($this->connection->getStream(), $localFile, $remoteFile, $mode, $resumepos); }
/** * Downloads a file from the FTP server to the local system but does not block other operations * * @param string $remotefile Remote path of the file to download * @param string $localfile Local path where the file should be stored * @param string $mode Transfer mode for the file. (auto or ascii or binary) * @param integer $position Pointer of the remote file from where the download should be resumed * @return integer 0 = Transfer failed (FTP_FAILED) | 1 = Transfer finished (FTP_FINISHED) | 2 = Transfer in progress (FTP_MOREDATA) */ public function downloadUnobtrusive($remotefile, $localfile, $mode = 'auto', $position = null) { if (is_resource($this->cid)) { $transfermode = self::transferMode($mode); return ftp_nb_get($this->cid, $localfile, $remotefile, $transfermode, $position); } }
/** * Download remote file to local file. * * @throws * @param string $remote_file * @param string $local_file */ public function get($remote_file, $local_file) { $lfile = File::exists($local_file); if ($lfile && $this->hasCache($remote_file, File::md5($local_file))) { $this->_log($remote_file . ' exists'); return; } $this->_log("download {$remote_file} as {$local_file}"); $ret = @ftp_nb_get($this->ftp, $local_file, $remote_file, FTP_BINARY); while ($ret === FTP_MOREDATA) { $ret = @ftp_nb_continue($this->ftp); } if ($ret !== FTP_FINISHED) { throw new Exception('FTP download failed', "local_file={$local_file} remote_file={$remote_file}"); } $this->cache[$remote_file] = [File::md5($local_file), File::size($local_file), File::lastModified($local_file)]; }
function get_htaccess($ftp_handle, $dir) { $local_htaccess = tempnam("files", "down"); $ftp_htaccess = str_replace("//", "/", $dir . '/.htaccess'); $ret = @ftp_nb_get($ftp_handle, $local_htaccess, $ftp_htaccess, FTP_BINARY); while ($ret == FTP_MOREDATA) { // Продолжаем загрузку $ret = @ftp_nb_continue($ftp_handle); } @chmod($local_htaccess, 0644); $content = @file_get_contents($local_htaccess); @unlink($local_htaccess); return $content; }
/** * @throws TransportException * @return string * */ protected function downloadToTmpFile() { $conn = $this->getFtpConnection(); $file = $this->getFilename(); $tmpFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . basename($file); $fileSize = $this->getSize(); $mode = $this->getMode() ? constant('FTP_' . strtoupper($this->getMode())) : FTP_ASCII; $ret = ftp_nb_get($conn, $tmpFile, $file, $mode); $currentBytes = 0; while ($ret === FTP_MOREDATA) { $ret = ftp_nb_continue($conn); clearstatcache(); $bytes = filesize($tmpFile); $diff = $bytes - $currentBytes; $currentBytes = $bytes; $this->eventDispatcher->dispatch(FeedEvents::FETCH_PROGRESS, new FetchProgressEvent($currentBytes, $diff, $fileSize)); } if ($ret !== FTP_FINISHED) { throw new TransportException(sprintf('Error downloading feed to %s', $tmpFile)); } return $tmpFile; }
private function get_large_ftp_file($file){ $url = "ftp://{$this->user}:{$this->pass}@{$this->server}/{$this->directory}/$file"; $path = ABSPATH."simple-backup/".$file; $start = $this->timer(); clearstatcache(); $file_size = filesize($url); $connection = $this->connect(); if($connection === false){ die('Can not Connect to FTP Server'); } if($login = $this->login($connection)){ ftp_pasv($connection,TRUE); $upload_path = $this->find_target_dir($connection); $i = 0; //loop counter $ret = @ftp_nb_get($connection, $path, $file, FTP_BINARY, FTP_AUTORESUME); while ($ret == FTP_MOREDATA) { $i++; if($i % 500 == 0){ clearstatcache(); $transfer_progress = filesize($path); $timer = ($this->timer() - $start); $pct_complete = ($transfer_progress/$file_size) * 100; $percentage_complete = number_format($pct_complete,1); $pct_complete = $percentage_complete."%"; $message = ' %2$s of %3$s Transferred (%1$s Complete) in %4$s Seconds!'; $msg = sprintf( $message, $pct_complete, size_format($transfer_progress,2), size_format($file_size,2), number_format($timer,2) ); $status = array(); $status['message'] = $msg; $status['code'] = "PROCESSING"; $status['percentage'] = $percentage_complete; update_option('simple-backup-file-transfer', $status); echo "."; if($i % 2000 == 0){ flush(); ob_flush(); } } // Continue upload... $ret = ftp_nb_continue($connection); } if ($ret == FTP_FINISHED) { $end = number_format(($this->timer() - $start), 2); $rate = size_format((filesize($path) / $end),2) . "/s"; $message = "Successfully downloaded $file to $path in $end seconds (rate: $rate)"; $status['message'] = $message; $status['code'] = "FINISHED"; $status['percentage'] = 100; update_option('simple-backup-file-transfer', $status); echo "\r\n$message"; } else { $message = "There was a problem while downloading $file to $path '$ret'"; $status['message'] = $message; $status['code'] = "ERROR"; update_option('simple-backup-file-transfer', $status); echo "\r\n$message"; } ftp_close($connection); } return true; }
/** * This function will download a file from the ftp-server. You can either spcify a absolute * path to the file (beginning with "/") or a relative one, which will be completed * with the actual directory you selected on the server. You can specify * the path to which the file will be downloaded on the local * maschine, if the file should be overwritten if it exists (optionally, default is * no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be * downloaded (if you do not specify this, the method tries to determine it automatically * from the mode-directory or uses the default-mode, set by you). If you give a relative * path to the local-file, the script-path is used as basepath. * * @access public * @param string $remote_file The absolute or relative path to the file to download * @param string $local_file The local file to put the downloaded in * @param bool $overwrite (optional) Whether to overwrite existing file * @param int $mode (optional) Either FTP_ASCII or FTP_BINARY * @return mixed True on success, otherwise PEAR::Error * @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED */ function get($remote_file, $local_file, $overwrite = false, $mode = null) { if (!isset($mode)) { $mode = $this->checkFileExtension($remote_file); } $remote_file = $this->_construct_path($remote_file); if (@file_exists($local_file) && !$overwrite) { return $this->raiseError("Local file '{$local_file}' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN); } if (@file_exists($local_file) && !@is_writeable($local_file) && $overwrite) { return $this->raiseError("Local file '{$local_file}' is not writeable. Can not overwrite.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); } if (@function_exists('ftp_nb_get')) { $res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode); while ($res == FTP_MOREDATA) { $this->_announce('nb_get'); $res = @ftp_nb_continue($this->_handle); } } else { $res = @ftp_get($this->_handle, $local_file, $remote_file, $mode); } if (!$res) { return $this->raiseError("File '{$remote_file}' could not be downloaded to '{$local_file}'.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); } else { return true; } }
/** * 下载文件 * */ public function download($localfile, $remotefile) { ftp_set_option($this->ftpobj, FTP_AUTOSEEK, FALSE); $res = ftp_nb_get($this->ftpobj, $localfile, $remotefile, $this->mode, ftp_size($this->ftpobj, $localfile)); while ($res == FTP_MOREDATA) { $res = ftp_nb_continue($this->ftpobj); } if ($res != FTP_FINISHED) { return FALSE; } return TRUE; }
/** * FTP-文件下载 * @param string $localFile 本地文件 * @param string $ftpFile Ftp文件 * @return bool */ public function download($localFile, $ftpFile) { if (!$localFile || !$ftpFile) { return false; } $ret = ftp_nb_get($this->link, $localFile, $ftpFile, FTP_BINARY); while ($ret == FTP_MOREDATA) { $ret = ftp_nb_continue($this->link); } if ($ret != FTP_FINISHED) { return false; } return true; }