- 论坛徽章:
- 0
|
通常网站数据中,图片或者附件下载总是特别耗服务器资源的。所以大型网站都采用了附件和网页分服务器的方法。
从网站程序考虑,要把附件上传到独立服务器,一种方法是提交的时候直接提交到附件的服务器上,这样的话附件服务器需要有程序接受和处理程序。另一种常用方法是附件先提交到程序所在服务器,然后程序服务器用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拷贝,主要在上传附件后使用
-
- /**
- * 拷贝或者移动文件
- *
- * @param string $from_file 原始文件名
- * @param string $to_file 拷贝到文件名,支持ftp模式,如 [url=ftp://user:password@host/dir/file.txt]ftp://user:password@host/dir/file.txt[/url]
- * @param int $mode 保存后的文件权限
- * @param bool $move 是否移动文件,默认false表示拷贝,true表示移动
- * @access public
- * @return bool 成功返回true,失败返回false
- */
- function jieqi_copyfile($from_file, $to_file, $mode = 0777, $move = false){
- $from_file = trim($from_file);
- if(!is_file($from_file)) return false;
- $to_file = trim($to_file);
- $matches = array();
- if(!preg_match('/^(ftps?):\/\/([^:\/]+):([^:\/]*)@([0-9a-z\-\.]+)(:(\d+))?([0-9a-z_\-\/\.]*)/is', $to_file, $matches)){
- jieqi_checkdir(dirname($to_file), true);
- if(is_file($to_file)) @unlink($to_file);
- if($move) $ret = rename($from_file, $to_file);
- else $ret = copy($from_file, $to_file);
- if($ret && $mode) @chmod($to_file, $mode);
- return $ret;
- }else{
- include_once(JIEQI_ROOT_PATH.'/lib/ftp/ftp.php');
- $ftpssl = (strtolower($matches[1]) == 'ftps') ? 1 : 0;
- $matches[6]=intval(trim($matches[6]));
- $ftpport = ($matches[6] > 0) ? $matches[6] : 21;
- $ftp =& JieqiFTP::getInstance($matches[4], $matches[2], $matches[3], '.', $ftpport, 0, $ftpssl);
- if(!$ftp) return false;
- $matches[7] = trim($matches[7]);
- if(!$ftp->ftp_chdir(dirname($matches[7]))){
- if(substr($matches[7],0,1) == '/') $matches[7] = substr($matches[7],1);
- $pathary = explode('/', dirname($matches[7]));
- foreach ($pathary as $v){
- $v=trim($v);
- if(strlen($v) > 0){
- if($ftp->ftp_mkdir($v) !== false && $mode) $ftp->ftp_chmod($mode, $v);
- $ftp->ftp_chdir($v);
- }
- }
- }
- $ret = $ftp->ftp_put(basename($matches[7]), $from_file);
- if($ret && $mode) $ftp->ftp_chmod($mode, basename($matches[7]));
- $ftp->ftp_close();
- if($move) @unlink($from_file);
- return $ret;
- }
- }
复制代码
代码2:文件删除函数,支持本地文件和ftp文件,在删除附件时候用
-
- /**
- * 删除文件
- *
- * @param string $file_name 文件名
- * @access public
- * @return bool 成功返回true,失败返回false
- */
- function jieqi_delfile($file_name){
- $file_name = trim($file_name);
- $matches = array();
- if(!preg_match('/^(ftps?):\/\/([^:\/]+):([^:\/]*)@([0-9a-z\-\.]+)(:(\d+))?([0-9a-z_\-\/\.]*)/is', $file_name, $matches)){
- return @unlink($file_name);
- }else{
- include_once(JIEQI_ROOT_PATH.'/lib/ftp/ftp.php');
- $ftpssl = (strtolower($matches[1]) == 'ftps') ? 1 : 0;
- $matches[6]=intval(trim($matches[6]));
- $ftpport = ($matches[6] > 0) ? $matches[6] : 21;
- $ftp =& JieqiFTP::getInstance($matches[4], $matches[2], $matches[3], '.', $ftpport, 0, $ftpssl);
- if(!$ftp) return false;
- $matches[7] = trim($matches[7]);
- return $ftp->ftp_delete($matches[7]);
- }
- }
复制代码
代码3:ftp类,通用的ftp处理
-
- <?php
- /**
- * FTP操作类
- *
- * 定义FTP相关功能
- *
- * 调用模板:无
- *
- * @category jieqicms
- * @package system
- * @copyright Copyright (c) Hangzhou Jieqi Network Technology Co.,Ltd. ([url=http://www.jieqi.com]http://www.jieqi.com[/url])
- * @author $Author: juny $
- * @version $Id: [url=ftp://ftp.php]ftp.php[/url] 318 2009-01-09 04:58:56Z juny $
- */
-
- /**
- * FTP类
- *
- * @category jieqicms
- * @package system
- */
- class JieqiFTP extends JieqiObject{
- var $_host; //服务器
- var $_port = 21; //端口
- var $_user; //用户名
- var $_pass; //密码
- var $_path = '.'; //默认路径
- var $_ssl = 0; //是否使用SSL连接
- var $_timeout = 0; //连接超时
- var $_pasv = 1; //是否被动模式
- var $connid; //连接字符串
-
-
- /**
- * 去掉换行符
- *
- * @param string $str
- * @access public
- * @return string
- */
- function wipespecial($str) {
- return str_replace(array("\n", "\r"), '', $str);
- }
-
- /**
- * 构造函数,设置ftp基本参数
- *
- * @param string $ftphost ftp服务器地址
- * @param string $ftpuser 用户名
- * @param string $ftppass 密码
- * @param string $ftppath 默认路径
- * @param int $ftpport 端口号
- * @access private
- * @return void
- */
- function JieqiFTP($ftphost = '', $ftpuser = '', $ftppass = '', $ftppath = '.', $ftpport = 21, $timeout = 0, $ftpssl = 0, $ftppasv = 1){
- $this->_host = $this->wipespecial($ftphost);
- $this->_user = $ftpuser;
- $this->_pass = $ftppass;
- $this->_port = intval($ftpport);
- $this->_timeout = intval($timeout);
- $this->_ssl = intval($ftpssl);
- $this->_pasv = intval($ftppasv);
- $this->_path = $ftppath;
- }
-
- /**
- * 返回静态实例变量的引用
- *
- * @param void
- * @access private
- * @return array
- */
- function &retInstance(){
- static $instance = array();
- return $instance;
- }
-
- /**
- * 关闭所有ftp连接
- *
- * @param void
- * @access public
- * @return bool
- */
- function close($ftp = NULL) {
- if(is_object($ftp)){
- $ftp->ftp_close();
- }else{
- $instance =& JieqiFTP::retInstance();
- if(!emptyempty($instance)){
- foreach($instance as $ftp){
- $ftp->ftp_close();
- }
- }
- }
- }
-
- /**
- * 创建一个实例,如果已经存在则直接返回
- *
- * @param string $ftphost ftp服务器地址
- * @param string $ftpuser 用户名
- * @param string $ftppass 密码
- * @param string $ftppath 默认路径
- * @param int $ftpport 端口号
- * @access private
- * @return void
- */
- function &getInstance($ftphost = '', $ftpuser = '', $ftppass = '', $ftppath = '.', $ftpport = 21, $timeout = 0, $ftpssl = 0, $ftppasv = 1){
- $instance =& JieqiFTP::retInstance();
- $inskey = md5($ftphost.','.$ftpuser.','.$ftppass.','.$ftppath.','.$ftpport.','.$timeout.','.$ftpssl.','.$ftppasv);
- if (!isset($instance[$inskey])) {
- $instance[$inskey] = new JieqiFTP($ftphost, $ftpuser, $ftppass, $ftppath, $ftpport, $timeout, $ftpssl, $ftppasv);
- $fid = $instance[$inskey]->ftp_connect();
- if(!$fid) return false;
- }
- return $instance[$inskey];
- }
-
- /**
- * ftp链接
- *
- * @param void
- * @access public
- * @return int
- */
- function ftp_connect() {
- [url=]//@set_time_limit(0[/url]);
- $func = $this->_ssl && function_exists('ftp_ssl_connect') ? 'ftp_ssl_connect' : 'ftp_connect';
- if($func == 'ftp_connect' && !function_exists('ftp_connect')) {
- $this->raiseError('FTP not supported', JIEQI_ERROR_RETURN);
- return -4; //不支持ftp函数
- }
- if($this->connid = @$func($this->_host, $this->_port, 20)) {
- if($this->_timeout && function_exists('ftp_set_option')) {
- @ftp_set_option($this->connid, FTP_TIMEOUT_SEC, $this->_timeout);
- }
- if($this->ftp_login($this->_user, $this->_pass)) {
- if($this->_pasv) {
- $this->ftp_pasv(TRUE);
- }
- if($this->ftp_chdir($this->_path)) {
- if(!defined('JIEQI_FTP_CONNECTED')) @define('JIEQI_FTP_CONNECTED',true);
- return 1;
- } else {
- $this->ftp_close();
- $this->raiseError('Chdir '.$this->_path,' error', JIEQI_ERROR_RETURN);
- return -3; //设置目录失败
- }
- } else {
- $this->ftp_close();
- $this->raiseError('FTP login failure', JIEQI_ERROR_RETURN);
- return -2; //登录失败
- }
- } else {
- $this->raiseError('Couldn\'t connect to '.$this->_host.':'.$this->_port, JIEQI_ERROR_RETURN);
- return -2; //连接失败
- }
- }
-
- /**
- * 新建目录
- *
- * @param string $directory
- * @access public
- * @return bool
- */
- function ftp_mkdir($directory) {
- $directory = $this->wipespecial($directory);
- return @ftp_mkdir($this->connid, $directory);
- }
-
- /**
- * 删除目录
- *
- * @param string $directory
- * @access public
- * @return bool
- */
- function ftp_rmdir($directory) {
- $directory = $this->wipespecial($directory);
- return @ftp_rmdir($this->connid, $directory);
- }
-
- /**
- * 上传文件
- *
- * @param string $remote_file 远程文件名
- * @param string $local_file 本地文件名
- * @param int $mode 传输方式
- * @param int $startpos 开始位置
- * @access public
- * @return bool
- */
- function ftp_put($remote_file, $local_file, $mode = FTP_BINARY, $startpos = 0 ) {
- $remote_file = $this->wipespecial($remote_file);
- $local_file = $this->wipespecial($local_file);
- $mode = intval($mode);
- $startpos = intval($startpos);
- return @ftp_put($this->connid, $remote_file, $local_file, $mode, $startpos);
- }
-
- /**
- * 取得ftp服务器上文件大小
- *
- * @param string $remote_file
- * @access public
- * @return int
- */
- function ftp_size($remote_file) {
- $remote_file = $this->wipespecial($remote_file);
- return @ftp_size($this->connid, $remote_file);
- }
-
- /**
- * 关闭ftp连接
- *
- * @param void
- * @access public
- * @return bool
- */
- function ftp_close() {
- return @ftp_close($this->connid);
- }
-
- /**
- * 删除文件
- *
- * @param string $path
- * @access public
- * @return bool
- */
- function ftp_delete($path) {
- $path = $this->wipespecial($path);
- return @ftp_delete($this->connid, $path);
- }
-
- /**
- * 下载文件
- *
- * @param string $local_file 本地文件名
- * @param string $remote_file 远程文件名
- * @param int $mode 传输方式
- * @param int $resumepos 开始位置
- * @access public
- * @return bool
- */
- function ftp_get($local_file, $remote_file, $mode = FTP_BINARY, $resumepos = 0) {
- $remote_file = $this->wipespecial($remote_file);
- $local_file = $this->wipespecial($local_file);
- $mode = intval($mode);
- $resumepos = intval($resumepos);
- return @ftp_get($this->connid, $local_file, $remote_file, $mode, $resumepos);
- }
-
- /**
- * ftp登录
- *
- * @param string $username 用户名
- * @param string $password 密码
- * @access public
- * @return bool
- */
- function ftp_login($username, $password) {
- $username = $this->wipespecial($username);
- $password = str_replace(array("\n", "\r"), array('', ''), $password);
- return @ftp_login($this->connid, $username, $password);
- }
-
- /**
- * 主动还是被动模式
- *
- * @param int $pasv
- * @access public
- * @return bool
- */
- function ftp_pasv($pasv) {
- $pasv = intval($pasv);
- return @ftp_pasv($this->connid, $pasv);
- }
-
- /**
- * 改变路径
- *
- * @param string $directory
- * @access public
- * @return bool
- */
- function ftp_chdir($directory) {
- $directory = $this->wipespecial($directory);
- return @ftp_chdir($this->connid, $directory);
- }
-
- /**
- * 向服务器发送 SITE 命令
- *
- * @param string $cmd
- * @access public
- * @return bool
- */
- function ftp_site($cmd) {
- $cmd = $this->wipespecial($cmd);
- return @ftp_site($this->connid, $cmd);
- }
-
- /**
- * 改变文件权限
- *
- * @param int $mode 访问权限
- * @param string $filename 文件名
- * @access public
- * @return bool
- */
- function ftp_chmod($mode, $filename) {
- $mode = intval($mode);
- $filename = $this->wipespecial($filename);
- if(function_exists('ftp_chmod')) {
- return @ftp_chmod($this->connid, $mode, $filename);
- } else {
- return $this->ftp_site($this->connid, 'CHMOD '.$mode.' '.$filename);
- }
- }
-
- /**
- * 文件重命名
- *
- * @param string $oldfile 原文件名
- * @param string $newfile 新文件名
- * @access public
- * @return bool
- */
- function ftp_rename($oldfile, $newfile) {
- return @ftp_rename($this->connid, $oldfile, $newfile);
- }
-
- /**
- * 获得当前路径
- *
- * @param void
- * @access public
- * @return string
- */
- function ftp_pwd() {
- return @ftp_pwd($this->connid);
- }
-
- /**
- * 返回给定目录的文件列表
- *
- * @param string $path
- * @access public
- * @return array
- */
- function ftp_nlist($path) {
- $path = $this->wipespecial($path);
- return @ftp_nlist($this->connid, $path);
- }
-
- /**
- * 删除FTP文件夹及里面文件
- *
- * @param string $path
- * @param bool $flag true表示删除目录本身(默认),false表示清空目录里面内容
- * @access public
- * @return bool
- */
- function ftp_delfolder($path, $flag = true) {
- $path = $this->wipespecial($path);
- if($flag) $ret = $this->ftp_rmdir($path) || $this->ftp_delete($path);
- else $ret = false;
- if (!$ret){
- $files = $this->ftp_nlist($path);
- foreach ($files as $values){
- $values = basename($values); //有的FTP服务器ftp_nlist()返回的是路径+文件名形式的数组
- if(!$this->ftp_delete($path .'/'. $values)){
- $this->ftp_delfolder($path .'/'. $values, true);
- }
- }
- if($flag) return $this->ftp_rmdir($path);
- else return true;
- }else{
- return $ret;
- }
- }
-
- /**
- * 根据给定路径字符串,循环创建目录(当前目录下创建)
- *
- * @param string $path
- * @access public
- * @return bool
- */
- function ftp_mkdirs($path)
- {
- $path = $this->wipespecial($path);
- $path_arr = explode('/',$path); // 取目录数组
- $path_div = count($path_arr); // 取层数
-
- foreach($path_arr as $val) // 创建目录
- {
- if($this->ftp_chdir($val) == FALSE)
- {
- $tmp = $this->ftp_mkdir($val);
- if($tmp == FALSE)
- {
- $this->raiseError('FTP mkdir failure', JIEQI_ERROR_RETURN);
- exit;
- }
- $this->ftp_chdir($val);
- }
- }
- for($i=1;$i<=$path_div;$i++) // 回退到根(创建时的目录)
- {
- @ftp_cdup($this->connid);
- }
- }
-
- }
- ?>
复制代码
本文首发及存档:http://www.xufeng.org/?action=show&id=36 |
|