免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2254 | 回复: 0
打印 上一主题 下一主题

JIEQI CMS 之远程FTP附件上传改造 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-20 10:49 |只看该作者 |倒序浏览
通常网站数据中,图片或者附件下载总是特别耗服务器资源的。所以大型网站都采用了附件和网页分服务器的方法。
    从网站程序考虑,要把附件上传到独立服务器,一种方法是提交的时候直接提交到附件的服务器上,这样的话附件服务器需要有程序接受和处理程序。另一种常用方法是附件先提交到程序所在服务器,然后程序服务器用ftp功能把文件再传到附件服务器。对大部分用户来说,第二种方法会更简单点,至少附件服务器不用专门装个web程序了。
     JIEQI CMS在考虑ftp远程附件上传功能支持的时候,为了兼顾之前版本的升级,尽量不对以前程序和使用方式做大的改动。因此统一设计了一个ftp类和文件上传处理函数,同时支持普通的上传和传到ftp远程,这里的区别这是在参数设置上下功夫
JIEQI CMS里面对上传类文件的保存目录参数有三种写法
   1、仅填目录名,如 attachment ,则附件保存在网站 /files/modname/attachment 目录(这里的 modname 是指模块标记,如 system、article、forum)
   2、填完整的路径名,如 E:/web/attachment 则附件保存在这个目录下(这种情况,附件的访问url需要人工设置)
   3、保存到ftp远程服务器上,路径设置采用ftp的url写法,如 ftp://user:pass@www.domain.com/files/attachment ,则上传的附件程序自动通过ftp传到对应服务器目录下(这种情况,附件的访问url需要人工设置)

代码1:文件拷贝函数,支持普通文件拷贝和ftp拷贝,主要在上传附件后使用

  1. /**   
  2. * 拷贝或者移动文件   
  3. *   
  4. * @param      string     $from_file 原始文件名   
  5. * @param      string     $to_file 拷贝到文件名,支持ftp模式,如 [url=ftp://user:password@host/dir/file.txt]ftp://user:password@host/dir/file.txt[/url]   
  6. * @param      int        $mode 保存后的文件权限   
  7. * @param      bool       $move 是否移动文件,默认false表示拷贝,true表示移动   
  8. * @access     public   
  9. * @return     bool       成功返回true,失败返回false   
  10. */   
  11. function jieqi_copyfile($from_file, $to_file, $mode = 0777, $move = false){   
  12.     $from_file = trim($from_file);   
  13.     if(!is_file($from_file)) return false;   
  14.     $to_file = trim($to_file);   
  15.     $matches = array();   
  16.     if(!preg_match('/^(ftps?):\/\/([^:\/]+):([^:\/]*)@([0-9a-z\-\.]+)(:(\d+))?([0-9a-z_\-\/\.]*)/is', $to_file, $matches)){   
  17.         jieqi_checkdir(dirname($to_file), true);   
  18.         if(is_file($to_file)) @unlink($to_file);   
  19.         if($move) $ret = rename($from_file, $to_file);   
  20.         else $ret = copy($from_file, $to_file);   
  21.         if($ret && $mode) @chmod($to_file, $mode);   
  22.         return $ret;   
  23.     }else{   
  24.         include_once(JIEQI_ROOT_PATH.'/lib/ftp/ftp.php');   
  25.         $ftpssl = (strtolower($matches[1]) == 'ftps') ? 1 : 0;   
  26.         $matches[6]=intval(trim($matches[6]));   
  27.         $ftpport = ($matches[6] > 0) ? $matches[6] : 21;   
  28.         $ftp =& JieqiFTP::getInstance($matches[4], $matches[2], $matches[3], '.', $ftpport, 0, $ftpssl);   
  29.         if(!$ftp) return false;   
  30.         $matches[7] = trim($matches[7]);   
  31.         if(!$ftp->ftp_chdir(dirname($matches[7]))){   
  32.             if(substr($matches[7],0,1) == '/') $matches[7] = substr($matches[7],1);   
  33.             $pathary = explode('/', dirname($matches[7]));   
  34.             foreach ($pathary as $v){   
  35.                 $v=trim($v);   
  36.                 if(strlen($v) > 0){   
  37.                     if($ftp->ftp_mkdir($v) !== false && $mode) $ftp->ftp_chmod($mode, $v);   
  38.                     $ftp->ftp_chdir($v);   
  39.                 }   
  40.             }   
  41.         }   
  42.         $ret = $ftp->ftp_put(basename($matches[7]), $from_file);   
  43.         if($ret && $mode) $ftp->ftp_chmod($mode, basename($matches[7]));   
  44.         $ftp->ftp_close();   
  45.         if($move) @unlink($from_file);   
  46.         return $ret;   
  47.     }   
  48. }
复制代码


代码2:文件删除函数,支持本地文件和ftp文件,在删除附件时候用

  1. /**   
  2. * 删除文件   
  3. *   
  4. * @param      string     $file_name 文件名   
  5. * @access     public   
  6. * @return     bool       成功返回true,失败返回false   
  7. */   
  8. function jieqi_delfile($file_name){   
  9.     $file_name = trim($file_name);   
  10.     $matches = array();   
  11.     if(!preg_match('/^(ftps?):\/\/([^:\/]+):([^:\/]*)@([0-9a-z\-\.]+)(:(\d+))?([0-9a-z_\-\/\.]*)/is', $file_name, $matches)){   
  12.         return @unlink($file_name);   
  13.     }else{   
  14.         include_once(JIEQI_ROOT_PATH.'/lib/ftp/ftp.php');   
  15.         $ftpssl = (strtolower($matches[1]) == 'ftps') ? 1 : 0;   
  16.         $matches[6]=intval(trim($matches[6]));   
  17.         $ftpport = ($matches[6] > 0) ? $matches[6] : 21;   
  18.         $ftp =& JieqiFTP::getInstance($matches[4], $matches[2], $matches[3], '.', $ftpport, 0, $ftpssl);   
  19.         if(!$ftp) return false;   
  20.         $matches[7] = trim($matches[7]);   
  21.         return $ftp->ftp_delete($matches[7]);   
  22.     }   
  23. }   
复制代码


代码3:ftp类,通用的ftp处理

  1. <?php   
  2. /**   
  3. * FTP操作类   
  4. *   
  5. * 定义FTP相关功能   
  6. *   
  7. * 调用模板:无   
  8. *   
  9. * @category   jieqicms   
  10. * @package    system   
  11. * @copyright  Copyright (c) Hangzhou Jieqi Network Technology Co.,Ltd. ([url=http://www.jieqi.com]http://www.jieqi.com[/url])   
  12. * @author     $Author: juny $   
  13. * @version    $Id: [url=ftp://ftp.php]ftp.php[/url] 318 2009-01-09 04:58:56Z juny $   
  14. */   
  15.    
  16. /**   
  17. * FTP类   
  18. *   
  19. * @category   jieqicms   
  20. * @package    system   
  21. */   
  22. class JieqiFTP extends JieqiObject{   
  23.     var $_host;  //服务器   
  24.     var $_port = 21;  //端口   
  25.     var $_user;  //用户名   
  26.     var $_pass;  //密码   
  27.     var $_path = '.';  //默认路径   
  28.     var $_ssl = 0;  //是否使用SSL连接   
  29.     var $_timeout = 0;  //连接超时   
  30.     var $_pasv = 1;  //是否被动模式   
  31.     var $connid; //连接字符串   
  32.    
  33.    
  34.     /**   
  35.      * 去掉换行符   
  36.      *   
  37.      * @param      string      $str   
  38.      * @access     public   
  39.      * @return     string   
  40.      */   
  41.     function wipespecial($str) {   
  42.         return str_replace(array("\n", "\r"), '', $str);   
  43.     }   
  44.    
  45.     /**   
  46.      * 构造函数,设置ftp基本参数   
  47.      *   
  48.      * @param      string      $ftphost ftp服务器地址   
  49.      * @param      string      $ftpuser 用户名   
  50.      * @param      string      $ftppass 密码   
  51.      * @param      string      $ftppath 默认路径   
  52.      * @param      int         $ftpport 端口号   
  53.      * @access     private   
  54.      * @return     void   
  55.      */   
  56.     function JieqiFTP($ftphost = '', $ftpuser = '', $ftppass = '', $ftppath = '.', $ftpport = 21, $timeout = 0, $ftpssl = 0, $ftppasv = 1){   
  57.         $this->_host = $this->wipespecial($ftphost);   
  58.         $this->_user = $ftpuser;   
  59.         $this->_pass = $ftppass;   
  60.         $this->_port = intval($ftpport);   
  61.         $this->_timeout = intval($timeout);   
  62.         $this->_ssl = intval($ftpssl);   
  63.         $this->_pasv = intval($ftppasv);   
  64.         $this->_path = $ftppath;   
  65.     }   
  66.         
  67.     /**   
  68.      * 返回静态实例变量的引用   
  69.      *   
  70.      * @param      void         
  71.      * @access     private   
  72.      * @return     array   
  73.      */   
  74.     function &retInstance(){   
  75.         static $instance = array();   
  76.         return $instance;   
  77.     }   
  78.         
  79.     /**   
  80.      * 关闭所有ftp连接   
  81.      *   
  82.      * @param      void   
  83.      * @access     public   
  84.      * @return     bool   
  85.      */   
  86.     function close($ftp = NULL) {   
  87.         if(is_object($ftp)){   
  88.             $ftp->ftp_close();   
  89.         }else{   
  90.             $instance =& JieqiFTP::retInstance();   
  91.             if(!emptyempty($instance)){   
  92.                 foreach($instance as $ftp){   
  93.                     $ftp->ftp_close();   
  94.                 }   
  95.             }   
  96.         }   
  97.     }   
  98.         
  99.     /**   
  100.      * 创建一个实例,如果已经存在则直接返回   
  101.      *   
  102.      * @param      string      $ftphost ftp服务器地址   
  103.      * @param      string      $ftpuser 用户名   
  104.      * @param      string      $ftppass 密码   
  105.      * @param      string      $ftppath 默认路径   
  106.      * @param      int         $ftpport 端口号   
  107.      * @access     private   
  108.      * @return     void   
  109.      */   
  110.     function &getInstance($ftphost = '', $ftpuser = '', $ftppass = '', $ftppath = '.', $ftpport = 21, $timeout = 0, $ftpssl = 0, $ftppasv = 1){   
  111.         $instance =& JieqiFTP::retInstance();   
  112.         $inskey = md5($ftphost.','.$ftpuser.','.$ftppass.','.$ftppath.','.$ftpport.','.$timeout.','.$ftpssl.','.$ftppasv);   
  113.         if (!isset($instance[$inskey])) {   
  114.             $instance[$inskey] = new JieqiFTP($ftphost, $ftpuser, $ftppass, $ftppath, $ftpport, $timeout, $ftpssl, $ftppasv);   
  115.             $fid = $instance[$inskey]->ftp_connect();   
  116.             if(!$fid) return false;   
  117.         }   
  118.         return $instance[$inskey];   
  119.     }   
  120.    
  121.     /**   
  122.      * ftp链接   
  123.      *   
  124.      * @param      void   
  125.      * @access     public   
  126.      * @return     int   
  127.      */   
  128.     function ftp_connect() {   
  129.         [url=]//@set_time_limit(0[/url]);   
  130.         $func = $this->_ssl && function_exists('ftp_ssl_connect') ? 'ftp_ssl_connect' : 'ftp_connect';   
  131.         if($func == 'ftp_connect' && !function_exists('ftp_connect')) {   
  132.             $this->raiseError('FTP not supported', JIEQI_ERROR_RETURN);   
  133.             return -4; //不支持ftp函数   
  134.         }   
  135.         if($this->connid = @$func($this->_host, $this->_port, 20)) {   
  136.             if($this->_timeout && function_exists('ftp_set_option')) {   
  137.                 @ftp_set_option($this->connid, FTP_TIMEOUT_SEC, $this->_timeout);   
  138.             }   
  139.             if($this->ftp_login($this->_user, $this->_pass)) {   
  140.                 if($this->_pasv) {   
  141.                     $this->ftp_pasv(TRUE);   
  142.                 }   
  143.                 if($this->ftp_chdir($this->_path)) {   
  144.                     if(!defined('JIEQI_FTP_CONNECTED')) @define('JIEQI_FTP_CONNECTED',true);   
  145.                     return 1;   
  146.                 } else {   
  147.                     $this->ftp_close();   
  148.                     $this->raiseError('Chdir '.$this->_path,' error', JIEQI_ERROR_RETURN);   
  149.                     return -3; //设置目录失败   
  150.                 }   
  151.             } else {   
  152.                 $this->ftp_close();   
  153.                 $this->raiseError('FTP login failure', JIEQI_ERROR_RETURN);   
  154.                 return -2; //登录失败   
  155.             }   
  156.         } else {   
  157.             $this->raiseError('Couldn\'t connect to '.$this->_host.':'.$this->_port, JIEQI_ERROR_RETURN);   
  158.             return -2; //连接失败   
  159.         }   
  160.     }   
  161.    
  162.     /**   
  163.      * 新建目录   
  164.      *   
  165.      * @param      string      $directory   
  166.      * @access     public   
  167.      * @return     bool   
  168.      */   
  169.     function ftp_mkdir($directory) {   
  170.         $directory = $this->wipespecial($directory);   
  171.         return @ftp_mkdir($this->connid, $directory);   
  172.     }   
  173.    
  174.     /**   
  175.      * 删除目录   
  176.      *   
  177.      * @param      string      $directory   
  178.      * @access     public   
  179.      * @return     bool   
  180.      */   
  181.     function ftp_rmdir($directory) {   
  182.         $directory = $this->wipespecial($directory);   
  183.         return @ftp_rmdir($this->connid, $directory);   
  184.     }   
  185.    
  186.     /**   
  187.      * 上传文件   
  188.      *   
  189.      * @param      string      $remote_file 远程文件名   
  190.      * @param      string      $local_file 本地文件名   
  191.      * @param      int         $mode 传输方式   
  192.      * @param      int         $startpos 开始位置   
  193.      * @access     public   
  194.      * @return     bool   
  195.      */   
  196.     function ftp_put($remote_file, $local_file, $mode = FTP_BINARY, $startpos = 0 ) {   
  197.         $remote_file = $this->wipespecial($remote_file);   
  198.         $local_file = $this->wipespecial($local_file);   
  199.         $mode = intval($mode);   
  200.         $startpos = intval($startpos);   
  201.         return @ftp_put($this->connid, $remote_file, $local_file, $mode, $startpos);   
  202.     }   
  203.    
  204.     /**   
  205.      * 取得ftp服务器上文件大小   
  206.      *   
  207.      * @param      string      $remote_file   
  208.      * @access     public   
  209.      * @return     int   
  210.      */   
  211.     function ftp_size($remote_file) {   
  212.         $remote_file = $this->wipespecial($remote_file);   
  213.         return @ftp_size($this->connid, $remote_file);   
  214.     }   
  215.    
  216.     /**   
  217.      * 关闭ftp连接   
  218.      *   
  219.      * @param      void   
  220.      * @access     public   
  221.      * @return     bool   
  222.      */   
  223.     function ftp_close() {   
  224.         return @ftp_close($this->connid);   
  225.     }   
  226.    
  227.     /**   
  228.      * 删除文件   
  229.      *   
  230.      * @param      string      $path   
  231.      * @access     public   
  232.      * @return     bool   
  233.      */   
  234.     function ftp_delete($path) {   
  235.         $path = $this->wipespecial($path);   
  236.         return @ftp_delete($this->connid, $path);   
  237.     }   
  238.    
  239.     /**   
  240.      * 下载文件   
  241.      *   
  242.      * @param      string      $local_file 本地文件名   
  243.      * @param      string      $remote_file 远程文件名   
  244.      * @param      int         $mode 传输方式   
  245.      * @param      int         $resumepos 开始位置   
  246.      * @access     public   
  247.      * @return     bool   
  248.      */   
  249.     function ftp_get($local_file, $remote_file, $mode = FTP_BINARY, $resumepos = 0) {   
  250.         $remote_file = $this->wipespecial($remote_file);   
  251.         $local_file = $this->wipespecial($local_file);   
  252.         $mode = intval($mode);   
  253.         $resumepos = intval($resumepos);   
  254.         return @ftp_get($this->connid, $local_file, $remote_file, $mode, $resumepos);   
  255.     }   
  256.    
  257.     /**   
  258.      * ftp登录   
  259.      *   
  260.      * @param      string      $username 用户名   
  261.      * @param      string      $password 密码   
  262.      * @access     public   
  263.      * @return     bool   
  264.      */   
  265.     function ftp_login($username, $password) {   
  266.         $username = $this->wipespecial($username);   
  267.         $password = str_replace(array("\n", "\r"), array('', ''), $password);   
  268.         return @ftp_login($this->connid, $username, $password);   
  269.     }   
  270.    
  271.     /**   
  272.      * 主动还是被动模式   
  273.      *   
  274.      * @param      int         $pasv   
  275.      * @access     public   
  276.      * @return     bool   
  277.      */   
  278.     function ftp_pasv($pasv) {   
  279.         $pasv = intval($pasv);   
  280.         return @ftp_pasv($this->connid, $pasv);   
  281.     }   
  282.    
  283.     /**   
  284.      * 改变路径   
  285.      *   
  286.      * @param      string     $directory   
  287.      * @access     public   
  288.      * @return     bool   
  289.      */   
  290.     function ftp_chdir($directory) {   
  291.         $directory = $this->wipespecial($directory);   
  292.         return @ftp_chdir($this->connid, $directory);   
  293.     }   
  294.    
  295.     /**   
  296.      * 向服务器发送 SITE 命令   
  297.      *   
  298.      * @param      string     $cmd   
  299.      * @access     public   
  300.      * @return     bool   
  301.      */   
  302.     function ftp_site($cmd) {   
  303.         $cmd = $this->wipespecial($cmd);   
  304.         return @ftp_site($this->connid, $cmd);   
  305.     }   
  306.    
  307.     /**   
  308.      * 改变文件权限   
  309.      *   
  310.      * @param      int        $mode 访问权限   
  311.      * @param      string     $filename 文件名   
  312.      * @access     public   
  313.      * @return     bool   
  314.      */   
  315.     function ftp_chmod($mode, $filename) {   
  316.         $mode = intval($mode);   
  317.         $filename = $this->wipespecial($filename);   
  318.         if(function_exists('ftp_chmod')) {   
  319.             return @ftp_chmod($this->connid, $mode, $filename);   
  320.         } else {   
  321.             return $this->ftp_site($this->connid, 'CHMOD '.$mode.' '.$filename);   
  322.         }   
  323.     }   
  324.         
  325.     /**   
  326.      * 文件重命名   
  327.      *   
  328.      * @param      string     $oldfile 原文件名   
  329.      * @param      string     $newfile 新文件名   
  330.      * @access     public   
  331.      * @return     bool   
  332.      */   
  333.     function ftp_rename($oldfile, $newfile) {   
  334.         return @ftp_rename($this->connid, $oldfile, $newfile);   
  335.     }   
  336.    
  337.     /**   
  338.      * 获得当前路径   
  339.      *   
  340.      * @param      void   
  341.      * @access     public   
  342.      * @return     string   
  343.      */   
  344.     function ftp_pwd() {   
  345.         return @ftp_pwd($this->connid);   
  346.     }   
  347.         
  348.     /**   
  349.      * 返回给定目录的文件列表   
  350.      *   
  351.      * @param      string      $path   
  352.      * @access     public   
  353.      * @return     array   
  354.      */   
  355.     function ftp_nlist($path) {   
  356.         $path = $this->wipespecial($path);   
  357.         return @ftp_nlist($this->connid, $path);   
  358.     }   
  359.    
  360.     /**   
  361.      * 删除FTP文件夹及里面文件   
  362.      *   
  363.      * @param      string      $path   
  364.      * @param      bool       $flag true表示删除目录本身(默认),false表示清空目录里面内容   
  365.      * @access     public   
  366.      * @return     bool   
  367.      */   
  368.     function ftp_delfolder($path, $flag = true) {   
  369.         $path = $this->wipespecial($path);   
  370.         if($flag) $ret  = $this->ftp_rmdir($path) || $this->ftp_delete($path);   
  371.         else $ret = false;   
  372.         if (!$ret){   
  373.             $files = $this->ftp_nlist($path);   
  374.             foreach ($files as $values){   
  375.                 $values = basename($values);        //有的FTP服务器ftp_nlist()返回的是路径+文件名形式的数组   
  376.                 if(!$this->ftp_delete($path .'/'. $values)){   
  377.                     $this->ftp_delfolder($path .'/'. $values, true);   
  378.                 }   
  379.             }   
  380.             if($flag) return $this->ftp_rmdir($path);   
  381.             else return true;   
  382.         }else{   
  383.             return $ret;   
  384.         }   
  385.     }   
  386.    
  387.     /**   
  388.      * 根据给定路径字符串,循环创建目录(当前目录下创建)   
  389.      *   
  390.      * @param      string      $path   
  391.      * @access     public   
  392.      * @return     bool   
  393.      */   
  394.     function ftp_mkdirs($path)   
  395.     {   
  396.         $path = $this->wipespecial($path);   
  397.         $path_arr = explode('/',$path);        // 取目录数组   
  398.         $path_div  = count($path_arr);         // 取层数   
  399.    
  400.         foreach($path_arr as $val)             // 创建目录   
  401.         {   
  402.             if($this->ftp_chdir($val) == FALSE)   
  403.             {   
  404.                 $tmp = $this->ftp_mkdir($val);   
  405.                 if($tmp == FALSE)   
  406.                 {   
  407.                     $this->raiseError('FTP mkdir failure', JIEQI_ERROR_RETURN);   
  408.                     exit;   
  409.                 }   
  410.                 $this->ftp_chdir($val);   
  411.             }   
  412.         }   
  413.         for($i=1;$i<=$path_div;$i++)           // 回退到根(创建时的目录)   
  414.         {   
  415.             @ftp_cdup($this->connid);   
  416.         }   
  417.     }   
  418.         
  419. }   
  420. ?>
复制代码



本文首发及存档:http://www.xufeng.org/?action=show&id=36
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP