• PHP使用FTP上传文件到服务器(实战篇)


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

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

    <?php
    /**
     * Created by PhpStorm.
     * User: 123456
     * Date: 2018/9/20
     * Time: 11:15
     * @author sunjiaqiang
     * @email 1355049422@qq.com
     */
        class Ftp{
            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 bool $permissions 文件夹权限
             * @param string $mode 上传模式(ascii和binary其中之一)
             */
            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其中之一)
             */
            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 文件地址
             */
            public function delete_file(string $remote_file=''){
                $result = @ftp_delete($this->conn,$remote_file);
                if ($result === FALSE){
                    return FALSE;
                }
                return TRUE;
            }
            /**
             * ftp创建多级目录
             * @param string $remote_file 要上传的远程图片地址
             */
            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目录地址
             */
            public function delete_dir(string $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 新文件/文件夹名
             */
            public function remane(string $old_file='',string $new_file=''){
                $result = @ftp_rename($this->conn,$old_file,$new_file);
                if ($result === FALSE){
                    $this->error = "移动失败";
                    return FALSE;
                }
                return TRUE;
            }
    
            /**
             * 列出ftp指定目录
             * @param string $remote_path
             */
            public function list_file(string $remote_path=''){
                $contents = @ftp_nlist($this->conn, $remote_path);
                return $contents;
            }
    
            /**
             * 获取文件的后缀名
             * @param string $local_file
             */
            private function _get_ext($local_file=''){
                return (($dot = strrpos($local_file,'.'))==FALSE) ? 'txt' : substr($local_file,$dot+1);
            }
    
            /**
             * 根据文件后缀获取上传编码
             * @param string $ext
             */
            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 权限值
             */
            private function _chmod($path,$mode=0755){
                if (FALSE == @ftp_chmod($this->conn,$path,$mode)){
                    return FALSE;
                }
                return TRUE;
            }
    
            /**
             * 登录Ftp服务器
             */
            private function _login(){
                return @ftp_login($this->conn,$this->user,$this->pass);
            }
    
            /**
             * 获取上传错误信息
             */
            public function get_error_msg(){
                return $this->error;
            }
    /**
     * 关闭ftp连接
     * @return bool
     */
    public function close(){
        return $this->conn ? @ftp_close($this->conn_id) : FALSE;
    }
        }

    使用方法,包含文件上传、下载、删除、移动以及删除整个文件夹

    <?php
    /**
     * Created by PhpStorm.
     * User: 123456
     * Date: 2018/9/20
     * Time: 14:07
     */
    declare(strict_types=1);
    include 'Ftp.php';
    $config = [
        'host'=>'192.168.0.148',
        'user'=>'ftpuser',
        'pass'=>'123456'
    ];
    $ftp = new Ftp($config);
    $result = $ftp->connect();
    if ( ! $result){
        echo $ftp->get_error_msg();
    }
    
    $local_file = 'video3.mp4';
    $remote_file = date('Y-m').'/video3.mp4';
    
    //上传文件
    if ($ftp->upload($local_file,$remote_file)){
        echo "上传成功";
    }else{
        echo "上传失败";
    }
    //删除文件
    if ($ftp->delete_file($remote_file)){
        echo "删除成功";
    }else{
        echo "删除失败";
    }
    
    //删除整个目录
    $remote_path='2018-09-19';
    if ($ftp->delete_dir($remote_path)){
        echo "目录删除成功";
    }else{
        echo "目录删除失败";
    }
    
    //下载文件
    $local_file2 = 'video5.mp4';
    $remote_file2='video3.mp4';
    if ($ftp->download($local_file2,$remote_file2)){
        echo "下载成功";
    }else{
        echo "下载失败";
    }
    
    //移动文件|重命名文件
    $local_file3 = 'video3.mp4';
    $remote_file3='shangchuan3/video3.mp4';
    if ($ftp->remane($local_file3,$remote_file3)){
        echo "移动成功";
    }else{
        echo "移动失败";
    }
    $ftp->close();
    //p($result);
    
    function p($data=''){
        echo '<pre>';
        print_r($data);
        echo '</pre>';
    }

    以上就是php使用ftp上传文件到自己的服务器,如有不对的地方还请大家指正。

  • 相关阅读:
    深入浅出Vue基于“依赖收集”的响应式原理(转)
    10道初级渗透测试面试题,测测你离职场有多远?
    CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞
    CTF必备技能丨Linux Pwn入门教程——利用漏洞获取libc
    CTF必备技能丨Linux Pwn入门教程——调整栈帧的技巧
    CTF必备技能丨Linux Pwn入门教程——ROP技术(下)
    用实力燃爆暑期丨i春秋渗透测试工程师线下就业班开课了!
    CTF必备技能丨Linux Pwn入门教程——ROP技术(上)
    CTF必备技能丨Linux Pwn入门教程——ShellCode
    CTF必备技能丨Linux Pwn入门教程——栈溢出基础
  • 原文地址:https://www.cnblogs.com/phproom/p/9683612.html
Copyright © 2020-2023  润新知