PHP 之ftp客戶端類封裝實現

<?php
/**
 * Class FtpClient
 */
class FtpClient
{
    private $host = '';//遠程服務器地址
    private $user = '';//ftp用戶名
    private $pass = '';//ftp密碼
    private $port = 21;//ftp登陸端口
    private $error = '';//最後失敗時的錯誤信息
    protected $conn;//ftp登陸資源

    /**
     * 能夠在實例化類的時候配置數據,也能夠在下面的connect方法中配置數據
     * Ftp constructor.
     * @param array $config
     */
    public function __construct(array $config = [])
    {
        empty($config) OR $this->initialize($config);
    }

    /**
     * 初始化數據
     * @param array $config 配置文件數組
     */
    public function initialize(array $config = [])
    {
        $this->host = $config['host'];
        $this->user = $config['user'];
        $this->pass = $config['pass'];
        $this->port = isset($config['port']) ?: 21;
    }

    /**
     * 鏈接及登陸ftp
     * @param array $config 配置文件數組
     * @return bool
     */
    public function connect(array $config = [])
    {
        empty($config) OR $this->initialize($config);
        if (FALSE == ($this->conn = @ftp_connect($this->host))) {
            $this->error = "主機鏈接失敗";
            return FALSE;
        }
        if (!$this->_login()) {
            $this->error = "服務器登陸失敗";
            return FALSE;
        }
        return TRUE;
    }
    /**
     * 上傳文件到ftp服務器
     * @param string $local_file 本地文件路徑
     * @param string $remote_file 服務器文件地址
     * @param string $mode 上傳模式(ascii和binary其中之一)
     * @param null $permissions 文件夾權限
     * @return bool
     */
    public function upload($local_file = '', $remote_file = '', $mode = 'auto', $permissions = NULL)
    {
        if (!file_exists($local_file)) {
            $this->error = "本地文件不存在";
            return FALSE;
        }
        if ($mode == 'auto') {
            $ext = $this->_get_ext($local_file);
            $mode = $this->_set_type($ext);
        }
        //建立文件夾
        $this->_create_remote_dir($remote_file);
        $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
        $result = @ftp_put($this->conn, $remote_file, $local_file, $mode);//同步上傳
        if ($result === FALSE) {
            $this->error = "文件上傳失敗";
            return FALSE;
        }
        return TRUE;
    }
    /**
     * 從ftp服務器下載文件到本地
     * @param string $local_file 本地文件地址
     * @param string $remote_file 遠程文件地址
     * @param string $mode 上傳模式(ascii和binary其中之一)
     * @return bool
     */
    public function download($local_file = '', $remote_file = '', $mode = 'auto')
    {
        if ($mode == 'auto') {
            $ext = $this->_get_ext($remote_file);
            $mode = $this->_set_type($ext);
        }
        $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
        $result = @ftp_get($this->conn, $local_file, $remote_file, $mode);
        if ($result === FALSE) {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 刪除ftp服務器端文件
     * @param string $remote_file 文件地址
     * @return bool
     */
    public function delete_file($remote_file = '')
    {
        $result = @ftp_delete($this->conn, $remote_file);
        if ($result === FALSE) {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * ftp建立多級目錄
     * @param string $remote_file 要上傳的遠程圖片地址
     * @param null $permissions 修改目錄權限
     */
    private function _create_remote_dir($remote_file = '', $permissions = NULL)
    {
        $remote_dir = dirname($remote_file);
        $path_arr = explode('/', $remote_dir); // 取目錄數組
        //$file_name = array_pop($path_arr); // 彈出文件名
        $path_div = count($path_arr); // 取層數
        foreach ($path_arr as $val) // 建立目錄
        {
            if (@ftp_chdir($this->conn, $val) == FALSE) {
                $tmp = @ftp_mkdir($this->conn, $val);//此處建立目錄時不用使用絕對路徑(不要使用:2018-02-20/ceshi/ceshi2,這種路徑),由於下面ftp_chdir已經已經把目錄切換成當前目錄
                if ($tmp == FALSE) {
                    echo "目錄建立失敗,請檢查權限及路徑是否正確!";
                    exit;
                }
                if ($permissions !== NULL) {
                    //修改目錄權限
                    $this->_chmod($val, $permissions);
                }
                @ftp_chdir($this->conn, $val);
            }
        }

        for ($i = 0; $i < $path_div; $i++) // 回退到根,由於上面的目錄切換致使當前目錄不在根目錄
        {
            @ftp_cdup($this->conn);
        }
    }
    /**
     * 遞歸刪除ftp端目錄
     * @param string $remote_dir ftp目錄地址
     * @return bool
     */
    public function delete_dir($remote_dir = '')
    {
        $list = $this->list_file($remote_dir);
        if (!empty($list)) {
            $count = count($list);
            for ($i = 0; $i < $count; $i++) {
                if (!preg_match('#\.#', $list[$i]) && !@ftp_delete($this->conn, $list[$i])) {
                    //這是一個目錄,遞歸刪除
                    $this->delete_dir($list[$i]);
                } else {
                    $this->delete_file($list[$i]);
                }
            }
        }
        if (@ftp_rmdir($this->conn, $remote_dir) === FALSE) {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 更改 FTP 服務器上的文件或目錄名
     * @param string $old_file 舊文件/文件夾名
     * @param string $new_file 新文件/文件夾名
     * @return bool
     */
    public function remane($old_file = '', $new_file = '')
    {
        $result = @ftp_rename($this->conn, $old_file, $new_file);
        if ($result === FALSE) {
            $this->error = "移動失敗";
            return FALSE;
        }
        return TRUE;
    }

    /**
     *
     * @param string $remote_path
     */
    /**
     * 列出ftp指定目錄
     * @param string $remote_path 服務器上的路徑
     * @return array
     */
    public function list_file($remote_path = '')
    {
        $contents = @ftp_nlist($this->conn, $remote_path);
        return $contents;
    }
    /**
     * 獲取文件的後綴名
     * @param string $local_file 本地文件
     * @return bool|string
     */
    private function _get_ext($local_file = '')
    {
        return (($dot = strrpos($local_file, '.')) == FALSE) ? 'txt' : substr($local_file, $dot + 1);
    }

    /**
     * 根據文件後綴獲取上傳編碼
     * @param string $ext
     * @return string
     */
    private function _set_type($ext = '')
    {
        //若是傳輸的文件是文本文件,可使用ASCII模式,若是不是文本文件,最好使用BINARY模式傳輸。
        return in_array($ext, ['txt', 'text', 'php', 'phps', 'php4', 'js', 'css', 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'], TRUE) ? 'ascii' : 'binary';
    }

    /**
     * 修改目錄權限
     * @param $path 目錄路徑
     * @param int $mode 權限值
     * @return bool
     */
    private function _chmod($path, $mode = 0755)
    {
        if (FALSE == @ftp_chmod($this->conn, $path, $mode)) {
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 登陸Ftp服務器
     * @return bool
     */
    private function _login()
    {
        return @ftp_login($this->conn, $this->user, $this->pass);
    }

    /**
     * 獲取上傳錯誤信息
     * @return string
     */
    public function get_error_msg()
    {
        return $this->error;
    }

    /**
     * 關閉ftp鏈接
     * @return bool
     */
    public function close()
    {
        return $this->conn ? @ftp_close($this->conn_id) : FALSE;
    }
}
相關文章
相關標籤/搜索