PHP通过FTP上传、下载

<?php
class Ftp{
    private $conn;
    private $ftpSession     = false;
    private $blackList      = array('.', '..');
    private $logPath        = '';//日志文件路径
    private $uploadTime     = 0;//最后上传时间
    private $downloadTime   = 0;//最后下载时间

    public function __construct($host = "", $log = '', $upTimeLog = '', $downTimeLog = '') 
    {
        if ($host != "") {
            $this->conn = ftp_connect($host, 21);
        }
        if ($upTimeLog && file_exists($upTimeLog)) {
            $this->uploadTime = file_get_contents($upTimeLog);
        }
        if ($downTimeLog && file_exists($downTimeLog)) {
            $this->downloadTime = file_get_contents($downTimeLog);
        }
        $this->logPath = $log;
    }

    public function __destruct() 
    {
        $this->disconnect();
    }

    public function connect($host) 
    {     
        $this->disconnect();
        $this->conn = ftp_connect($host);
        if (!$this->conn) {
            $this->log('Error: Connection failed.');
            die();
        }
        return $this->conn;
    }

    public function login($user, $pwd) 
    {
        $this->ftpSession = ftp_login($this->conn, $user, $pwd);
        if (!$this->ftpSession) {
            $this->log("Error: User $user login failed.");
            ftp_close($this->conn);
            die();
        }
        return $this->ftpSession;
    }

    public function disconnect() 
    {
        if (isset($this->conn)) {
            ftp_close($this->conn);
            unset($this->conn);
        }
    }

    public function log($msg)
    {
        $msg = $this->encodeTo($msg, 'UTF-8');
        file_put_contents($this->logPath.date('Ymd').'.log', date('Y-m-d H:i:s').' '.$msg."\r\n", FILE_APPEND);
    }

    /* 修改编码 */
    public function encodeTo($str, $encode)
    {
        // 我们一般写php程序,都会使用utf8编码来显示网页。但是我们Windows的文件名不支持utf8,如果用utf8写文件名会出现乱码,这个时候我们的解决办法就是把文件名字从utf8编码转到Windows能识别的文件目录,即gbk编 码
        $curEncode = mb_detect_encoding($str, array("ASCII",'UTF-8',"GB2312","GBK",'BIG5','EUC-CN','CP936'));
        if ($curEncode != $encode) {
            // var_dump("$str curEncode = $curEncode , now = $encode");
            return iconv($curEncode, $encode, $str);
        }
        return $str;
    }

    /* 上传目录 */
    public function upload($local, $remote) 
    {
        return $this->upload_recurse($local, $local, $remote);
    }
    private function upload_recurse($root, $local, $remote) 
    {
        if ($remote != '.') {
            $this->make_directory("$remote");
        }
        $errorList = array();
        $local_GBK = $this->encodeTo($local, 'GBK');
        if (!file_exists($local_GBK)) {
            mkdir($local_GBK, 0777, true);
        }
        $directory = opendir($local_GBK);
        while ($file_GBK = readdir($directory)){
            $file = $this->encodeTo($file_GBK, 'UTF-8');
            if (in_array($file, $this->blackList)) continue;
            if (is_dir("$local/$file_GBK")) {
                $result = $this->make_directory("$remote/$file");
                if ($result) {
                    $errorList["$remote/$file"] = $result;
                }

                $result2 = $this->upload_recurse($root, "$local/$file", "$remote/$file");
                if ($result2) {
                    $errorList[] = $result2;
                }
            } else {
                $result = $this->put_file("$local/$file", "$remote/$file");
                if ($result) {
                    $errorList["$remote/$file"] = $result;
                }
            }
        }
        return $errorList;
    }
    public function make_directory($remote) 
    {
        $error = "";
        try {
            @ftp_mkdir($this->conn, $this->encodeTo($remote, 'GBK'));
        } catch (Exception $e) {
            $this->log('Error: '.$e->getMessage());
            if ($e->getCode() == 2) $error = $e->getMessage(); 
        }
        return $error;
    }
    public function put_file($local, $remote) 
    {
        $error = "";
        try {
            $remote_GBK = $this->encodeTo($remote, 'GBK');
            $local_GBK = $this->encodeTo($local, 'GBK');

            //对比判断: 本地文件最后修改时间 > 最后FTP上传时间
            if (fileatime($local_GBK) > $this->uploadTime) {
                $result = ftp_put($this->conn, $remote_GBK, $local_GBK, FTP_BINARY);
                $status = $result ? 'Success' : 'Error';
                $this->log("$status : upload file <$local> to <$remote>");
            }
        } catch (Exception $e) {
            $this->log('Error: '.$e->getMessage());
            if ($e->getCode() == 2) $error = $e->getMessage(); 
        }
        return $error;
    }

    /* 下载目录 */
    public function download($local, $remote) 
    {
        //获取文件、目录
        $list = ftp_nlist($this->conn, $this->encodeTo($remote, 'GBK'));

        //创建目录
        $local_GBK = $this->encodeTo($local, 'GBK');
        if (!file_exists($local_GBK)) {
            mkdir($local_GBK, 0777, true);
        }
        foreach ($list as $value) {
            $filename = substr($value, strrpos($value, '/') ? strrpos($value, '/') + 1 : 0);
            $filename = $this->encodeTo($filename, 'UTF-8');
            $localFile = $local.'/'.$filename;
            $remoteFile = $remote.'/'.$filename;

            $localFile_BGK = $this->encodeTo($localFile, 'GBK');
            $remoteFile_BGK = $this->encodeTo($remoteFile, 'GBK');
            //判断是否是文件
            if (ftp_size($this->conn, $remoteFile_BGK) != -1) {
                //对比判断:FTP文件最后修改时间 > 最后FTP下载时间
                if (ftp_mdtm($this->conn, $remoteFile_BGK) > $this->downloadTime) {
                    $downloadStatus = 'Error';
                    $deleteStatus = 'Error';

                    $downloadResult = ftp_get($this->conn, $localFile_BGK, $remoteFile_BGK, FTP_BINARY);//下载FTP文件
                    if ($downloadResult) {
                        $downloadStatus = 'Success';
                        $deleteResult = ftp_delete($this->conn, $remoteFile_BGK);//删除FTP文件
                        if ($deleteResult) {
                            $deleteStatus = 'Success';
                        }
                    }
                    $this->log("{$downloadStatus} : download file <{$remoteFile}> to <{$localFile}>");
                    $this->log("{$deleteStatus} : delete file <{$remoteFile}>");
                }
            } else {
                if (!file_exists($localFile_BGK)) {
                    mkdir($localFile_BGK, 0777, true);                    
                } 
                $this->download($localFile, $remoteFile);
            }
        }
    }
}

header("Content-type:text/html;charset=utf-8"); 
ignore_user_abort(true);
set_time_limit(0);
session_write_close();

$hostname = '192.168.6.28';
$ftpUpload = 'upload';//FTP目录
$ftpDownload = 'back';//FTP目录

$dir = dirname(__FILE__);//当前文件路径
$killLog = $dir.'/killLoop.log';//关闭循环文件
$interval = 10;// 间隔执行时间

/* 本地测试用 */
// $hostname       = '172.30.8.142';
// $ftpUpload      = 'upload';//FTP目录
// $ftpDownload    = 'back';//FTP目录

$list = array(
    array(
        'username' => 'xxxxx',
        'password' => '*******',
        'uploadDir' => 'D:\ftp_dir\u01\upload\ftpfile',
        'downloadDir' => 'D:\ftp_dir\u01\download',
        'logDir' => "{$dir}/ftplog/default/", // 日志文件
        'upTimeLog' => "{$dir}/ftplog/default/ftpUploadTime.log", // 最后上传时间日志文件
        'downTimeLog' => "{$dir}/ftplog/default/ftpDownloadTime.log" // 最后下载时间日志文件
    ),
    array(
        'username' => 'xxxxx',
        'password' => '*******',
        'uploadDir' => 'D:\ftp_dir\u01\upload\ftpfile_HX',
        'downloadDir' => 'D:\ftp_dir\u01\download',
        'logDir' => "{$dir}/ftplog/hx/",
        'upTimeLog' => "{$dir}/ftplog/hx/ftpUploadTime.log",
        'downTimeLog' => "{$dir}/ftplog/hx/ftpDownloadTime.log"
    )
    
    /* 本地测试 */
    // array(
    //     'username' => 'hsb',
    //     'password' => 'Hongshaobo2020',
    //     'uploadDir' => 'D:\upload2',
    //     'downloadDir' => 'D:\download2',
    //     'logDir' => "{$dir}/ftplog/test1/",
    //     'upTimeLog' => "{$dir}/ftplog/test1/ftpUploadTime.log",
    //     'downTimeLog' => "{$dir}/ftplog/test1/ftpDownloadTime.log"
    // ),
    // array(
    //     'username' => 'hsb',
    //     'password' => 'Hongshaobo2020',
    //     'uploadDir' => 'D:\upload',
    //     'downloadDir' => 'D:\download',
    //     'logDir' => "{$dir}/ftplog/test2/",
    //     'upTimeLog' => "{$dir}/ftplog/test2/ftpUploadTime.log",
    //     'downTimeLog' => "{$dir}/ftplog/test2/ftpDownloadTime.log"
    // )
);

while(true) {
    if (file_get_contents($killLog) != '') {
        var_dump('sync ftp was stoped..');
        break;
    }
    foreach ($list as $val) {
        if (!file_exists($val['logDir'])) {
            mkdir($val['logDir'], 0777, true);
        }

        $ftp = new Ftp($hostname, $val['logDir'], $val['upTimeLog'], $val['downTimeLog']);
        $ftpSession = $ftp->login($val['username'], $val['password']);
        if (!$ftpSession) {
            $ftp->log('Failed to connect.');
            die('Failed to connect.');
        }
        
        $ftp->log('============= start upload =============');
        $ftp->upload($val['uploadDir'], $ftpUpload);
        $ftp->log('============= end upload =============');
        file_put_contents($val['upTimeLog'], time());

        $ftp->log('============= start download =============');
        $ftp->download($val['downloadDir'], $ftpDownload);
        $ftp->log('============= end download =============');
        file_put_contents($val['downTimeLog'], time());

        $ftp->disconnect();
    }
    
    sleep($interval);
}

退出PHP循环任务:在Ftp.php文件所在的目录创建文件killLoop.log,在文件内随便写入一些内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值