PHP实现FTP上传、FTP下载、FTP移动、FTP复制、FTP删除的用法【博主自用】

2018年10月18日 113 次阅读 1 条评论 3 人点赞

我们在做开发的过程中,上传文件肯定是避免不了的,平常我们的程序和上传的文件都在一个服务器上,我们也可以使用第三方sdk上传文件,但是文件在第三方服务器上。现在我们使用PHP的ftp功能把文件上传到我们自己的服务器,我使用的linux的服务器,首先确保服务器上配置好ftp

PHP之FTP代码,拷贝可直接用

FTP官方文档详见: 
http://php.net/manual/en/book.ftp.php

FTP类,此类包含把文件上传、下载、删除和删除ftp服务器目录功能,测试环境php版本=5.6

<?php
namespace app\common\library;
/**
 * Note: PHP操作FTP.
 * User: ysongyang <49271743@qq.com>
 * Time: 2018/5/12 0012 17:13:58
 */
class Ftp
{
    //FTP 连接资源
    private $conn;
    //FTP连接时间
    public $conn_time;
    //错误代码
    private $err_code = 0;
    //传送模式 {文本模式:FTP_ASCII, 二进制模式:FTP_BINARY}
    public $mode = FTP_BINARY;

    /**
     * Ftps constructor.
     * @param array $data
     */
    public function __construct($data = [])
    {
        $this->_init($data);
    }

    /**
     * 初始化类
     * @param $data
     * @return bool
     */
    public function _init($data)
    {
        if (empty($data['port'])) $data['port'] = config('ftp.port');
        if (empty($data['pasv'])) $data['pasv'] = config('ftp.pasv');
        if (empty($data['ssl'])) $data['ssl'] = config('ftp.ssl');
        if (empty($data['timeout'])) $data['timeout'] = config('ftp.timeout');
        if (empty($data['host'])) $data['host'] = config('ftp.host');
        if (empty($data['username'])) $data['username'] = config('ftp.username');
        if (empty($data['password'])) $data['password'] = config('ftp.password');
        return $this->connect($data['host'], $data['username'], $data['password'], $data['port'], $data['pasv'], $data['ssl'], $data['timeout']);
    }

    /**
     * 连接FTP服务器
     * @param string $host 服务器地址
     * @param string $username 用户名
     * @param string $password 密码
     * @param string $port 服务器端口,默认值为21
     * @param bool $pasv 是否开启被动模式
     * @param bool $ssl 是否使用SSL连接
     * @param int $timeout 超时时间 
     * @return bool
     */
    public function connect($host, $username = '', $password = '', $port = '21', $pasv = false, $ssl = false, $timeout = 30)
    {
        $start = time();
        if ($ssl) {
            if (!$this->conn = @ftp_ssl_connect($host, $port, $timeout)) {
                $this->err_code = 1;
                return false;
            }
        } else {
            if (!$this->conn = @ftp_connect($host, $port, $timeout)) {
                $this->err_code = 1;
                return false;
            }
        }
        if (@ftp_login($this->conn, $username, $password)) {
            if ($pasv)
                ftp_pasv($this->conn, true);
            $this->conn_time = time() - $start;
            return true;
        } else {
            $this->err_code = 1;
            return false;
        }
        register_shutdown_function(array(&$this, 'close'));
    }

    /**
     * 通过FTP创建文件夹
     * @param string $dirPath 目录名,
     * @return bool
     */
    public function makeDir($dirPath)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        $dirPath = $this->check_dirName($dirPath);
        $nowDir = '/';
        foreach ($dirPath as $v) {
            if ($v && !$this->chgdir($nowDir . $v)) {
                if ($nowDir)
                    $this->chgdir($nowDir);
                @ftp_mkdir($this->conn, $v);
            }
            if ($v)
                $nowDir .= $v . '/';
        }
        return true;
    }

    /**
     * WIN环境下创建目录
     * @param $dir
     * @return bool
     */
    public function makeFolders($dir)
    {
        return is_dir($dir) or ($this->makeFolders(dirname($dir)) and mkdir($dir, 0777));
    }

    /**
     * 兼容WIN和LINUX
     * @param $path
     * @param $sysType
     */
    public function createFolders($path, $sysType = 'WIN')
    {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && $sysType === 'WIN') {
            $this->makeFolders(dirname($path));
        } else {
            $this->makeDir(dirname($path));
        }
    }

    /**
     * 上传文件
     * @param string $remote_file 远程存放地址
     * @param string $local_file 本地存放地址
     * @return bool
     */
    public function upload($remote_file, $local_file)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        $dirName = pathinfo($remote_file, PATHINFO_DIRNAME);
        if (!$this->chgdir($dirName)) {
            $this->makeDir($dirName);
        }
        if (@ftp_put($this->conn, $remote_file, $local_file, $this->mode)) {
            return true;
        } else {
            $this->err_code = 7;
            $this->get_error();
            return false;
        }
    }

    /**
     * 从FTP下载文件到本地
     * @param string $remote_file 远程文件路径
     * @param string $local_file 本地下载路径
     * @return boolean
     */
    function downFile($remote_file, $local_file)
    {
        //下载时需要判断本地环境是WIN还是LINUX
        $this->createFolders($local_file);
        if (file_exists($local_file))
            if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
                @unlink($local_file);
            } else {
                $this->delete($local_file);
            }
        $res = @ftp_get($this->conn, $local_file, $remote_file, FTP_BINARY);//下载
        if (!$res) {
            $this->err_code = 8;
            $this->get_error();
            return false;
        }
        return true;
    }

    /**
     * php通过FTP移动文件
     * @param $path
     * @param $newPath
     * @return bool
     */
    function moveFile($path, $newPath)
    {
        #创建文件夹,获取远程FTP服务器的系统类型标识符 UNIX WIN
        $this->createFolders($newPath, @ftp_systype($this->conn));
        $res = @ftp_rename($this->conn, $path, $newPath);
        if (!$res) {
            $this->err_code = 9;
            $this->get_error();
            return false;
        }
        return true;
    }

    /**
     * php通过FTP复制文件
     * 说明:由于FTP无复制命令,本方法变通操作为:下载后再上传到新的路径
     * @param $path  string   源文件存储路径
     * @param $newPath string  复制文件存储的路径
     * @param $downPath string  下载文件的路径
     */
    function copyFile($path, $newPath, $downPath)
    {
        $this->downFile($path, $downPath);
        $this->upload($newPath, $downPath);
    }

    /**
     * 删除文件夹
     * @param string $dirName 目录地址
     * @param bool $enforce 强制删除
     * @return bool
     */
    public function removeDir($dirName, $enforce = false)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        $list = $this->nlist($dirName);
        if ($list && $enforce) {
            $this->chgdir($dirName);
            foreach ($list as $v) {
                $this->delete($v);
            }
        } elseif ($list && !$enforce) {
            $this->err_code = 3;
            $this->get_error();
            return false;
        }
        @ftp_rmdir($this->conn, $dirName);
        return true;
    }

    /**
     * 删除指定文件
     * @param $filename
     * @return bool
     */
    public function delete($filename)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        if (@ftp_delete($this->conn, $filename)) {
            return true;
        } else {
            $this->err_code = 4;
            $this->get_error();
            return false;
        }
    }

    /**
     * 返回给定目录的文件列表
     * @param string $dirName 目录地址
     * @return array 文件列表数据
     */
    public function nlist($dirName)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        if ($list = @ftp_nlist($this->conn, $dirName)) {
            return $list;
        } else {
            $this->err_code = 5;
            $this->get_error();
            return false;
        }
    }

    /**
     * 在 FTP 服务器上改变当前目录
     * @param string $dirName 修改服务器上当前目录
     * @return boolean
     */
    public function chgdir($dirName)
    {
        if (!$this->conn) {
            $this->err_code = 2;
            $this->get_error();
            return false;
        }
        if (@ftp_chdir($this->conn, $dirName)) {
            return true;
        } else {
            $this->err_code = 6;
            $this->get_error();
            return false;
        }
    }

    /**
     * 获取错误信息
     */
    public function get_error()
    {
        if (!$this->err_code)
            return false;
        $err_msg = array(
            '1' => 'Server can not connect',
            '2' => 'Not connect to server',
            '3' => 'Can not delete non-empty folder',
            '4' => 'Can not delete file',
            '5' => 'Can not get file list',
            '6' => 'Can not change the current directory on the server',
            '7' => 'Can not upload files',
            '8' => 'File download failed',
            '9' => 'File migration failed',
        );
        $this->_error($err_msg[$this->err_code]);
    }

    /**
     * 检测目录名
     * @param string $url 目录
     * @return array 分开的返回数组
     */
    private function check_dirName($url)
    {
        $url = str_replace('', '/', $url);
        $urls = explode('/', $url);
        return $urls;
    }

    /**
     * 关闭FTP连接
     */
    public function close()
    {
        return @ftp_close($this->conn);
    }

    /**
     * 错误日志记录
     * @param string $msg
     * @return bool|int
     */
    private function _error($msg = '')
    {
        if (empty($msg)) return false;
        return @file_put_contents(RUNTIME_PATH . '/log/' . date('Ym') . '/ftp_err.log', "[" . date("Y-m-d H:i:s") . "]-msg[" . $msg . "]\n", FILE_APPEND);
    }
}

我们在做开发的过程中,上传文件肯定是避免不了的,平常我们的程序和上传的文件都在一个服务器上,我们也可以使用第三方sdk上传文件,但是文件在第三方服务器上。现在我们使用PHP的ftp功能把文件上传到我们自己的服务器,我使用的linux的服务器,首先确保服务器上配置好ftp,以vsftpd为例。以上就是php使用ftp上传文件到自己的服务器,如有疑问的地方请大家留言指正。


作为一个真正的程序员,首先应该尊重编程,热爱你所写下的程序,他是你的伙伴,而不是工具。

文章评论(1

  • 阳阳博主

    最近有朋友在群里咨询关于php操作ftp时遇到了一些问题,这里我把之前写过的一个FTP类找出来贴上来,仅供大家参考,如果有疑问请评论留言。

    #12018-10-18 16:08
  • 接收回复邮件通知