仿写CodeIgniter的FTP操作类

jerry thinkphp 2015年11月19日 收藏
仿写CodeIgniter的FTP操作类
  1. <?PHP
  2. /**
  3.  * 仿写CodeIgniter的FTP类
  4.  * FTP基本操作:
  5.  * 1) 登陆;             connect
  6.  * 2) 当前目录文件列表;  filelist
  7.  * 3) 目录改变;            chgdir
  8.  * 4) 重命名/移动;        rename
  9.  * 5) 创建文件夹;        mkdir
  10.  * 6) 删除;                delete_dir/delete_file
  11.  * 7) 上传;                upload
  12.  * 8) 下载                download
  13.  *
  14.  * 
  15.  */
  16. class Ftp {

  17.     private $hostname    = '';
  18.     private $username    = '';
  19.     private $password    = '';
  20.     private $port         = 21;
  21.     private $passive     = TRUE;
  22.     private $debug        = TRUE;
  23.     private $conn_id     = FALSE;
  24.     
  25.     /**
  26.      * 构造函数
  27.      *
  28.      * @param    array    配置数组 : $config = array('hostname'=>'','username'=>'','password'=>'','port'=>''...);
  29.      */
  30.     public function __construct($config = array()) {
  31.         if(count($config) > 0) {
  32.             $this->_init($config);
  33.         }
  34.     }
  35.     
  36.     /**
  37.      * FTP连接
  38.      *
  39.      * @access     public
  40.      * @param     array     配置数组
  41.      * @return    boolean
  42.      */
  43.     public function connect($config = array()) {
  44.         if(count($config) > 0) {
  45.             $this->_init($config);
  46.         }
  47.         
  48.         if(FALSE === ($this->conn_id = @ftp_connect($this->hostname,$this->port))) {
  49.             if($this->debug === TRUE) {
  50.                 $this->_error("ftp_unable_to_connect");
  51.             }
  52.             return FALSE;
  53.         }
  54.         
  55.         if( ! $this->_login()) {
  56.             if($this->debug === TRUE) {
  57.                 $this->_error("ftp_unable_to_login");
  58.             }
  59.             return FALSE;
  60.         }
  61.         
  62.         if($this->passive === TRUE) {
  63.             ftp_pasv($this->conn_id, TRUE);
  64.         }
  65.         
  66.         return TRUE;
  67.     }

  68.     
  69.     /**
  70.      * 目录改变
  71.      *
  72.      * @access     public
  73.      * @param     string     目录标识(ftp)
  74.      * @param    boolean    
  75.      * @return    boolean
  76.      */
  77.     public function chgdir($path = '', $supress_debug = FALSE) {
  78.         if($path == '' OR ! $this->_isconn()) {
  79.             return FALSE;
  80.         }
  81.         
  82.         $result = @ftp_chdir($this->conn_id, $path);
  83.         
  84.         if($result === FALSE) {
  85.             if($this->debug === TRUE AND $supress_debug == FALSE) {
  86.                 $this->_error("ftp_unable_to_chgdir:dir[".$path."]");
  87.             }
  88.             return FALSE;
  89.         }
  90.         
  91.         return TRUE;
  92.     }
  93.     
  94.     /**
  95.      * 目录生成
  96.      *
  97.      * @access     public
  98.      * @param     string     目录标识(ftp)
  99.      * @param    int      文件权限列表    
  100.      * @return    boolean
  101.      */
  102.     public function mkdir($path = '', $permissions = NULL) {
  103.         if($path == '' OR ! $this->_isconn()) {
  104.             return FALSE;
  105.         }
  106.         
  107.         $result = @ftp_mkdir($this->conn_id, $path);
  108.         
  109.         if($result === FALSE) {
  110.             if($this->debug === TRUE) {
  111.                 $this->_error("ftp_unable_to_mkdir:dir[".$path."]");
  112.             }
  113.             return FALSE;
  114.         }
  115.         
  116.         if( ! is_null($permissions)) {
  117.             $this->chmod($path,(int)$permissions);
  118.         }
  119.         
  120.         return TRUE;
  121.     }
  122.     
  123.     /**
  124.      * 上传
  125.      *
  126.      * @access     public
  127.      * @param     string     本地目录标识
  128.      * @param    string    远程目录标识(ftp)
  129.      * @param    string    上传模式 auto || ascii
  130.      * @param    int        上传后的文件权限列表    
  131.      * @return    boolean
  132.      */
  133.     public function upload($localpath, $remotepath, $mode = 'auto', $permissions = NULL) {
  134.         if( ! $this->_isconn()) {
  135.             return FALSE;
  136.         }
  137.         
  138.         if( ! file_exists($localpath)) {
  139.             if($this->debug === TRUE) {
  140.                 $this->_error("ftp_no_source_file:".$localpath);
  141.             }
  142.             return FALSE;
  143.         }
  144.         
  145.         if($mode == 'auto') {
  146.             $ext = $this->_getext($localpath);
  147.             $mode = $this->_settype($ext);
  148.         }
  149.         
  150.         $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
  151.         
  152.         $result = @ftp_put($this->conn_id, $remotepath, $localpath, $mode);
  153.         
  154.         if($result === FALSE) {
  155.             if($this->debug === TRUE) {
  156.                 $this->_error("ftp_unable_to_upload:localpath[".$localpath."]/remotepath[".$remotepath."]");
  157.             }
  158.             return FALSE;
  159.         }
  160.         
  161.         if( ! is_null($permissions)) {
  162.             $this->chmod($remotepath,(int)$permissions);
  163.         }
  164.         
  165.         return TRUE;
  166.     }
  167.     
  168.     /**
  169.      * 下载
  170.      *
  171.      * @access     public
  172.      * @param     string     远程目录标识(ftp)
  173.      * @param    string    本地目录标识
  174.      * @param    string    下载模式 auto || ascii    
  175.      * @return    boolean
  176.      */
  177.     public function download($remotepath, $localpath, $mode = 'auto') {
  178.         if( ! $this->_isconn()) {
  179.             return FALSE;
  180.         }
  181.         
  182.         if($mode == 'auto') {
  183.             $ext = $this->_getext($remotepath);
  184.             $mode = $this->_settype($ext);
  185.         }
  186.         
  187.         $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
  188.         
  189.         $result = @ftp_get($this->conn_id, $localpath, $remotepath, $mode);
  190.         
  191.         if($result === FALSE) {
  192.             if($this->debug === TRUE) {
  193.                 $this->_error("ftp_unable_to_download:localpath[".$localpath."]-remotepath[".$remotepath."]");
  194.             }
  195.             return FALSE;
  196.         }
  197.         
  198.         return TRUE;
  199.     }
  200.     
  201.     /**
  202.      * 重命名/移动
  203.      *
  204.      * @access     public
  205.      * @param     string     远程目录标识(ftp)
  206.      * @param    string    新目录标识
  207.      * @param    boolean    判断是重命名(FALSE)还是移动(TRUE)    
  208.      * @return    boolean
  209.      */
  210.     public function rename($oldname, $newname, $move = FALSE) {
  211.         if( ! $this->_isconn()) {
  212.             return FALSE;
  213.         }
  214.         
  215.         $result = @ftp_rename($this->conn_id, $oldname, $newname);
  216.         
  217.         if($result === FALSE) {
  218.             if($this->debug === TRUE) {
  219.                 $msg = ($move == FALSE) ? "ftp_unable_to_rename" : "ftp_unable_to_move";
  220.                 $this->_error($msg);
  221.             }
  222.             return FALSE;
  223.         }
  224.         
  225.         return TRUE;
  226.     }
  227.     
  228.     /**
  229.      * 删除文件
  230.      *
  231.      * @access     public
  232.      * @param     string     文件标识(ftp)
  233.      * @return    boolean
  234.      */
  235.     public function delete_file($file) {
  236.         if( ! $this->_isconn()) {
  237.             return FALSE;
  238.         }
  239.         
  240.         $result = @ftp_delete($this->conn_id, $file);
  241.         
  242.         if($result === FALSE) {
  243.             if($this->debug === TRUE) {
  244.                 $this->_error("ftp_unable_to_delete_file:file[".$file."]");
  245.             }
  246.             return FALSE;
  247.         }
  248.         
  249.         return TRUE;
  250.     }
  251.     
  252.     /**
  253.      * 删除文件夹
  254.      *
  255.      * @access     public
  256.      * @param     string     目录标识(ftp)
  257.      * @return    boolean
  258.      */
  259.     public function delete_dir($path) {
  260.         if( ! $this->_isconn()) {
  261.             return FALSE;
  262.         }
  263.         
  264.         //对目录宏的'/'字符添加反斜杠'\'
  265.         $path = preg_replace("/(.+?)\/*$/", "\\1/", $path);
  266.     
  267.         //获取目录文件列表
  268.         $filelist = $this->filelist($path);
  269.         
  270.         if($filelist !== FALSE AND count($filelist) > 0) {
  271.             foreach($filelist as $item) {
  272.                 //如果我们无法删除,那么就可能是一个文件夹
  273.                 //所以我们递归调用delete_dir()
  274.                 if( ! @delete_file($item)) {
  275.                     $this->delete_dir($item);
  276.                 }
  277.             }
  278.         }
  279.         
  280.         //删除文件夹(空文件夹)
  281.         $result = @ftp_rmdir($this->conn_id, $path);
  282.         
  283.         if($result === FALSE) {
  284.             if($this->debug === TRUE) {
  285.                 $this->_error("ftp_unable_to_delete_dir:dir[".$path."]");
  286.             }
  287.             return FALSE;
  288.         }
  289.         
  290.         return TRUE;
  291.     }
  292.     
  293.     /**
  294.      * 修改文件权限
  295.      *
  296.      * @access     public
  297.      * @param     string     目录标识(ftp)
  298.      * @return    boolean
  299.      */
  300.     public function chmod($path, $perm) {
  301.         if( ! $this->_isconn()) {
  302.             return FALSE;
  303.         }
  304.         
  305.         //只有在PHP5中才定义了修改权限的函数(ftp)
  306.         if( ! function_exists('ftp_chmod')) {
  307.             if($this->debug === TRUE) {
  308.                 $this->_error("ftp_unable_to_chmod(function)");
  309.             }
  310.             return FALSE;
  311.         }
  312.         
  313.         $result = @ftp_chmod($this->conn_id, $perm, $path);
  314.         
  315.         if($result === FALSE) {
  316.             if($this->debug === TRUE) {
  317.                 $this->_error("ftp_unable_to_chmod:path[".$path."]-chmod[".$perm."]");
  318.             }
  319.             return FALSE;
  320.         }
  321.         return TRUE;
  322.     }
  323.     
  324.     /**
  325.      * 获取目录文件列表
  326.      *
  327.      * @access     public
  328.      * @param     string     目录标识(ftp)
  329.      * @return    array
  330.      */
  331.     public function filelist($path = '.') {
  332.         if( ! $this->_isconn()) {
  333.             return FALSE;
  334.         }
  335.         
  336.         return ftp_nlist($this->conn_id, $path);
  337.     }
  338.     
  339.     /**
  340.      * 关闭FTP
  341.      *
  342.      * @access     public
  343.      * @return    boolean
  344.      */
  345.     public function close() {
  346.         if( ! $this->_isconn()) {
  347.             return FALSE;
  348.         }
  349.         
  350.         return @ftp_close($this->conn_id);
  351.     }
  352.     
  353.     /**
  354.      * FTP成员变量初始化
  355.      *
  356.      * @access    private
  357.      * @param    array    配置数组     
  358.      * @return    void
  359.      */
  360.     private function _init($config = array()) {
  361.         foreach($config as $key => $val) {
  362.             if(isset($this->$key)) {
  363.                 $this->$key = $val;
  364.             }
  365.         }

  366.         //特殊字符过滤
  367.         $this->hostname = preg_replace('|.+?://|','',$this->hostname);
  368.     }
  369.     
  370.     /**
  371.      * FTP登陆
  372.      *
  373.      * @access     private
  374.      * @return    boolean
  375.      */
  376.     private function _login() {
  377.         return @ftp_login($this->conn_id, $this->username, $this->password);
  378.     }
  379.     
  380.     /**
  381.      * 判断con_id
  382.      *
  383.      * @access     private
  384.      * @return    boolean
  385.      */
  386.     private function _isconn() {
  387.         if( ! is_resource($this->conn_id)) {
  388.             if($this->debug === TRUE) {
  389.                 $this->_error("ftp_no_connection");
  390.             }
  391.             return FALSE;
  392.         }
  393.         return TRUE;
  394.     }
  395.     
  396.     /**
  397.      * 从文件名中获取后缀扩展
  398.      *
  399.      * @access     private
  400.      * @param     string     目录标识
  401.      * @return    string
  402.      */
  403.     private function _getext($filename) {
  404.         if(FALSE === strpos($filename, '.')) {
  405.             return 'txt';
  406.         }
  407.         
  408.         $extarr = explode('.', $filename);
  409.         return end($extarr);
  410.     }
  411.     
  412.     /**
  413.      * 从后缀扩展定义FTP传输模式  ascii 或 binary
  414.      *
  415.      * @access     private
  416.      * @param     string     后缀扩展
  417.      * @return    string
  418.      */
  419.     private function _settype($ext) {
  420.         $text_type = array (
  421.                             'txt',
  422.                             'text',
  423.                             'php',
  424.                             'phps',
  425.                             'php4',
  426.                             'js',
  427.                             'css',
  428.                             'htm',
  429.                             'html',
  430.                             'phtml',
  431.                             'shtml',
  432.                             'log',
  433.                             'xml'
  434.                             );
  435.         
  436.         return (in_array($ext, $text_type)) ? 'ascii' : 'binary';
  437.     }
  438.     
  439.     /**
  440.      * 错误日志记录
  441.      *
  442.      * @access     prvate
  443.      * @return    boolean
  444.      */
  445.     private function _error($msg) {
  446.         return @file_put_contents('ftp_err.log', "date[".date("Y-m-d H:i:s")."]-hostname[".$this->hostname."]-username[".$this->username."]-password[".$this->password."]-msg[".$msg."]\n", FILE_APPEND);
  447.     }
  448. }



  449. $config = array(
  450.             'hostname' => '124.160.116.76',
  451.             'username' => 'hangye_lsp_19@192.168.18.19',
  452.             'password' => 'tb6bCnHNrO',
  453.             'port' => 52816
  454.                 );

  455. $ftp = new Ftp();

  456. $ftp->connect($config);
  457. $ftp->upload('localfile.log','remotefile.log');
  458. ?>