【discuz x3】如何将头像和帖内等附件分离到远程服务器?

一、修改uc_server/control/user.php文件,代码如下:

usercontrol();
	}

	function usercontrol() {
		parent::__construct();
		$this->load('user');
	}

	// -1 未开启
	function onsynlogin() {
		$this->init_input();
		$uid = $this->input('uid');
		if($this->app['synlogin']) {
			if($this->user = $_ENV['user']->get_user_by_uid($uid)) {
				$synstr = '';
				foreach($this->cache['apps'] as $appid => $app) {
					if($app['synlogin']) {
						$synstr .= '';
						if(is_array($app['extra']['extraurl'])) foreach($app['extra']['extraurl'] as $extraurl) {
							$synstr .= '';
						}
					}
				}
				return $synstr;
			}
		}
		return '';
	}

	function onsynlogout() {
		$this->init_input();
		if($this->app['synlogin']) {
			$synstr = '';
			foreach($this->cache['apps'] as $appid => $app) {
				if($app['synlogin']) {
					$synstr .= '';
					if(is_array($app['extra']['extraurl'])) foreach($app['extra']['extraurl'] as $extraurl) {
						$synstr .= '';
					}
				}
			}
			return $synstr;
		}
		return '';
	}

	function onregister() {
		$this->init_input();
		$username = $this->input('username');
		$password =  $this->input('password');
		$email = $this->input('email');
		$questionid = $this->input('questionid');
		$answer = $this->input('answer');
		$regip = $this->input('regip');

		if(($status = $this->_check_username($username)) < 0) {
			return $status;
		}
		if(($status = $this->_check_email($email)) < 0) {
			return $status;
		}

		$uid = $_ENV['user']->add_user($username, $password, $email, 0, $questionid, $answer, $regip);
		return $uid;
	}

	function onedit() {
		$this->init_input();
		$username = $this->input('username');
		$oldpw = $this->input('oldpw');
		$newpw = $this->input('newpw');
		$email = $this->input('email');
		$ignoreoldpw = $this->input('ignoreoldpw');
		$questionid = $this->input('questionid');
		$answer = $this->input('answer');

		if(!$ignoreoldpw && $email && ($status = $this->_check_email($email, $username)) < 0) {
			return $status;
		}
		$status = $_ENV['user']->edit_user($username, $oldpw, $newpw, $email, $ignoreoldpw, $questionid, $answer);

		if($newpw && $status > 0) {
			$this->load('note');
			$_ENV['note']->add('updatepw', 'username='.urlencode($username).'&password=');
			$_ENV['note']->send();
		}
		return $status;
	}

	function onlogin() {
		$this->init_input();
		$isuid = $this->input('isuid');
		$username = $this->input('username');
		$password = $this->input('password');
		$checkques = $this->input('checkques');
		$questionid = $this->input('questionid');
		$answer = $this->input('answer');
		if($isuid == 1) {
			$user = $_ENV['user']->get_user_by_uid($username);
		} elseif($isuid == 2) {
			$user = $_ENV['user']->get_user_by_email($username);
		} else {
			$user = $_ENV['user']->get_user_by_username($username);
		}

		$passwordmd5 = preg_match('/^\w{32}$/', $password) ? $password : md5($password);
		if(empty($user)) {
			$status = -1;
		} elseif($user['password'] != md5($passwordmd5.$user['salt'])) {
			$status = -2;
		} elseif($checkques && $user['secques'] != '' && $user['secques'] != $_ENV['user']->quescrypt($questionid, $answer)) {
			$status = -3;
		} else {
			$status = $user['uid'];
		}
		$merge = $status != -1 && !$isuid && $_ENV['user']->check_mergeuser($username) ? 1 : 0;
		return array($status, $user['username'], $password, $user['email'], $merge);
	}

	function oncheck_email() {
		$this->init_input();
		$email = $this->input('email');
		return $this->_check_email($email);
	}

	function oncheck_username() {
		$this->init_input();
		$username = $this->input('username');
		if(($status = $this->_check_username($username)) < 0) {
			return $status;
		} else {
			return 1;
		}
	}

	function onget_user() {
		$this->init_input();
		$username = $this->input('username');
		if(!$this->input('isuid')) {
			$status = $_ENV['user']->get_user_by_username($username);
		} else {
			$status = $_ENV['user']->get_user_by_uid($username);
		}
		if($status) {
			return array($status['uid'],$status['username'],$status['email']);
		} else {
			return 0;
		}
	}


	function ongetprotected() {
		$protectedmembers = $this->db->fetch_all("SELECT uid,username FROM ".UC_DBTABLEPRE."protectedmembers GROUP BY username");
		return $protectedmembers;
	}

	function ondelete() {
		$this->init_input();
		$uid = $this->input('uid');
		return $_ENV['user']->delete_user($uid);
	}

	function ondeleteavatar() {
		$this->init_input();
		$uid = $this->input('uid');
		$_ENV['user']->delete_useravatar($uid);
	}

	function onaddprotected() {
		$this->init_input();
		$username = $this->input('username');
		$admin = $this->input('admin');
		$appid = $this->app['appid'];
		$usernames = (array)$username;
		foreach($usernames as $username) {
			$user = $_ENV['user']->get_user_by_username($username);
			$uid = $user['uid'];
			$this->db->query("REPLACE INTO ".UC_DBTABLEPRE."protectedmembers SET uid='$uid', username='$username', appid='$appid', dateline='{$this->time}', admin='$admin'", 'SILENT');
		}
		return $this->db->errno() ? -1 : 1;
	}

	function ondeleteprotected() {
		$this->init_input();
		$username = $this->input('username');
		$appid = $this->app['appid'];
		$usernames = (array)$username;
		foreach($usernames as $username) {
			$this->db->query("DELETE FROM ".UC_DBTABLEPRE."protectedmembers WHERE username='$username' AND appid='$appid'");
		}
		return $this->db->errno() ? -1 : 1;
	}

	function onmerge() {
		$this->init_input();
		$oldusername = $this->input('oldusername');
		$newusername = $this->input('newusername');
		$uid = $this->input('uid');
		$password = $this->input('password');
		$email = $this->input('email');
		if(($status = $this->_check_username($newusername)) < 0) {
			return $status;
		}
		$uid = $_ENV['user']->add_user($newusername, $password, $email, $uid);
		$this->db->query("DELETE FROM ".UC_DBTABLEPRE."mergemembers WHERE appid='".$this->app['appid']."' AND username='$oldusername'");
		return $uid;
	}

	function onmerge_remove() {
		$this->init_input();
		$username = $this->input('username');
		$this->db->query("DELETE FROM ".UC_DBTABLEPRE."mergemembers WHERE appid='".$this->app['appid']."' AND username='$username'");
		return NULL;
	}

	function _check_username($username) {
		$username = addslashes(trim(stripslashes($username)));
		if(!$_ENV['user']->check_username($username)) {
			return UC_USER_CHECK_USERNAME_FAILED;
		} elseif(!$_ENV['user']->check_usernamecensor($username)) {
			return UC_USER_USERNAME_BADWORD;
		} elseif($_ENV['user']->check_usernameexists($username)) {
			return UC_USER_USERNAME_EXISTS;
		}
		return 1;
	}

	function _check_email($email, $username = '') {
		if(!$_ENV['user']->check_emailformat($email)) {
			return UC_USER_EMAIL_FORMAT_ILLEGAL;
		} elseif(!$_ENV['user']->check_emailaccess($email)) {
			return UC_USER_EMAIL_ACCESS_ILLEGAL;
		} elseif(!$this->settings['doublee'] && $_ENV['user']->check_emailexists($email, $username)) {
			return UC_USER_EMAIL_EXISTS;
		} else {
			return 1;
		}
	}

	function ongetcredit($arr) {
		$this->init_input();
		$appid = $this->input('appid');
		$uid = $this->input('uid');
		$credit = $this->input('credit');
		$this->load('note');
		$this->load('misc');
		$app = $this->cache['apps'][$appid];
		$apifilename = isset($app['apifilename']) && $app['apifilename'] ? $app['apifilename'] : 'uc.php';
		if($app['extra']['apppath'] && @include $app['extra']['apppath'].'./api/'.$apifilename) {
			$uc_note = new uc_note();
			return $uc_note->getcredit(array('uid' => $uid, 'credit' => $credit), '');
		} else {
			$url = $_ENV['note']->get_url_code('getcredit', "uid=$uid&credit=$credit", $appid);
			return $_ENV['misc']->dfopen($url, 0, '', '', 1, $app['ip'], UC_NOTE_TIMEOUT);
		}
	}

	//返回的内容为保存该文件的临时位置,camera.swf会通过返回的网址来读取图片
	function onuploadavatar() {
		@header("Expires: 0");
		@header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
		@header("Pragma: no-cache");
		//header("Content-type: application/xml; charset=utf-8");
		$this->init_input(getgpc('agent', 'G'));

		$uid = $this->input('uid');
		if(empty($uid)) {
			return -1;
		}
		if(empty($_FILES['Filedata'])) {
			return -3;
		}

		list($width, $height, $type, $attr) = getimagesize($_FILES['Filedata']['tmp_name']);
		if(!in_array($type, array(1,2,3,6))) {
			@unlink($_FILES['Filedata']['tmp_name']);
			return -4;
		}
		$imgtype = array(1 => '.gif', 2 => '.jpg', 3 => '.png');
		$filetype = $imgtype[$type];
		if(!$filetype) $filetype = '.jpg';
		//头像临时存放路径
		$tmpavatar = UC_DATADIR.'./tmp/upload'.$uid.$filetype;
		file_exists($tmpavatar) && @unlink($tmpavatar);
		if(@copy($_FILES['Filedata']['tmp_name'], $tmpavatar) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $tmpavatar)) {
			@unlink($_FILES['Filedata']['tmp_name']);
			list($width, $height, $type, $attr) = getimagesize($tmpavatar);
			if($width < 10 || $height < 10 || $type == 4) {
				@unlink($tmpavatar);
				return -2;
			}
		} else {
			@unlink($_FILES['Filedata']['tmp_name']);
			return -4;
		}
		$avatarurl = UC_DATAURL.'/tmp/upload'.$uid.$filetype;
		//返回临时头像的url路径
		return $avatarurl;
	}

	function onrectavatar() {
		@header("Expires: 0");
		@header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
		@header("Pragma: no-cache");
		header("Content-type: application/xml; charset=utf-8");
		$this->init_input(getgpc('agent'));
		$uid = $this->input('uid');
		if(empty($uid)) {
			return '';
		}
		$home = $this->get_home($uid);//返回头像的三个目录:"00/00/12","/avatar/"."00/00/12"."/45_small.jpg"
		if(!is_dir(UC_DATADIR.'./avatar/'.$home)) {
			$this->set_home($uid, UC_DATADIR.'./avatar/');//如果没有的话,则创建目录
		}
                
		$avatartype = getgpc('avatartype', 'G') == 'real' ? 'real' : 'virtual';
		//UC_DATADIR:d:/wamp/www/discuz3/uc_server/data/
                //获取大中小头像的全路径
		$bigavatarfile = UC_DATADIR.'./avatar/'.$this->get_avatar($uid, 'big', $avatartype);
		$middleavatarfile = UC_DATADIR.'./avatar/'.$this->get_avatar($uid, 'middle', $avatartype);
		$smallavatarfile = UC_DATADIR.'./avatar/'.$this->get_avatar($uid, 'small', $avatartype);
		//getgpc:获取 $_GET、$_POST、$_COOKIE中数据
                $bigavatar = $this->flashdata_decode(getgpc('avatar1', 'P'));//$_POST
		$middleavatar = $this->flashdata_decode(getgpc('avatar2', 'P'));
		$smallavatar = $this->flashdata_decode(getgpc('avatar3', 'P'));
		if(!$bigavatar || !$middleavatar || !$smallavatar) {
			return '';
		}

		$success = 1;
		//写入二进制数据到图片文件,$bigavatar:二进制数据内容
		$fp = @fopen($bigavatarfile, 'wb');
		@fwrite($fp, $bigavatar);
		@fclose($fp);

		$fp = @fopen($middleavatarfile, 'wb');
		@fwrite($fp, $middleavatar);
		@fclose($fp);

		$fp = @fopen($smallavatarfile, 'wb');
		@fwrite($fp, $smallavatar);//将二进制头像数据信息写入头像文件
		@fclose($fp);
                
                /******************************************************************/
                $ftps=new Ftp();//实例化一个ftp对象,下面有这个类的定义
                //上传头像成功的同时将头像同步到远程服务器
                $ftps->connect("127.0.0.1","ftp的用户名","ftp的密码","ftp的端口",true,false);//true-开启了被动模式  false-没有使用ssl连接
                $ftps->put("/domains/goodbaobao.taobao.com/public_html/data/avatar/".$this->get_avatar($uid, 'big', $avatartype),$bigavatarfile);
                $ftps->put("/domains/goodbaobao.taobao.com/public_html/data/avatar/".$this->get_avatar($uid, 'middle', $avatartype),$middleavatarfile);
                $ftps->put("/domains/goodbaobao.taobao.com/public_html/data/avatar/".$this->get_avatar($uid, 'small', $avatartype),$smallavatarfile);
                $ftps->close();
                /******************************************************************/

		$biginfo = @getimagesize($bigavatarfile);
		$middleinfo = @getimagesize($middleavatarfile);
		$smallinfo = @getimagesize($smallavatarfile);
		if(!$biginfo || !$middleinfo || !$smallinfo || $biginfo[2] == 4 || $middleinfo[2] == 4 || $smallinfo[2] == 4) {
			file_exists($bigavatarfile) && unlink($bigavatarfile);
			file_exists($middleavatarfile) && unlink($middleavatarfile);
			file_exists($smallavatarfile) && unlink($smallavatarfile);
			$success = 0;
		}

		$filetype = '.jpg';
		@unlink(UC_DATADIR.'./tmp/upload'.$uid.$filetype);

		if($success) {
			return '';
		} else {
			return '';
		}
	}


	function flashdata_decode($s) {
		$r = '';
		$l = strlen($s);
		for($i=0; $i<$l; $i=$i+2) {
			$k1 = ord($s[$i]) - 48;
			$k1 -= $k1 > 9 ? 7 : 0;
			$k2 = ord($s[$i+1]) - 48;
			$k2 -= $k2 > 9 ? 7 : 0;
			$r .= chr($k1 << 4 | $k2);
		}
		return $r;
	}

}

//ftp类:头像上传成功的同时将头像同步上传到远程服务器
class Ftp {
        
    //FTP 连接资源
    private $link;
    //FTP连接时间
    public $link_time;
    //错误代码
    private $err_code = 0;
    //传送模式{文本模式:FTP_ASCII, 二进制模式:FTP_BINARY}
    public $mode = FTP_BINARY;
        
    /**
     * 连接FTP服务器
     * @param string $host       服务器地址
     * @param string $username   用户名
     * @param string $password   密码
     * @param integer $port       服务器端口,默认值为21
     * @param boolean $pasv        是否开启被动模式
     * @param boolean $ssl      是否使用SSL连接
     * @param integer $timeout     超时时间 
     */
    public function connect($host, $username = '', $password = '', $port = '21', $pasv = false, $ssl = false, $timeout = 30) {
        $start = time();
        if ($ssl) {
            if (!$this->link = @ftp_ssl_connect($host, $port, $timeout)) {
                $this->err_code = 1;
                return false;
            }
        } else {
            if (!$this->link = @ftp_connect($host, $port, $timeout)) {
                $this->err_code = 1;
                return false;
            }
        }
        
        if (@ftp_login($this->link, $username, $password)) {
            if ($pasv)
                ftp_pasv($this->link, true);
            $this->link_time = time() - $start;
            return true;
        } else {
            $this->err_code = 1;
            return false;
        }
        register_shutdown_function(array(&$this, 'close'));
    }
        
    /**
     * 创建文件夹
     * @param string $dirname 目录名,
     */
    public function mkdir($dirname) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        $dirname = $this->ck_dirname($dirname);
        $nowdir = '/';
        foreach ($dirname as $v) {
            if ($v && !$this->chdir($nowdir . $v)) {
                if ($nowdir)
                    $this->chdir($nowdir);
                @ftp_mkdir($this->link, $v);
            }
            if ($v)
                $nowdir .= $v . '/';
        }
        return true;
    }
        
    /**
     * 上传文件
     * @param string $remote 远程存放地址
     * @param string $local 本地存放地址
     */
    public function put($remote, $local) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        $dirname = pathinfo($remote, PATHINFO_DIRNAME);
        if (!$this->chdir($dirname)) {
            $this->mkdir($dirname);
        }
        if (@ftp_put($this->link, $remote, $local, $this->mode)) {
            return true;
        } else {
            $this->err_code = 7;
            return false;
        }
    }
        
    /**
     * 删除文件夹
     * @param string $dirname  目录地址
     * @param boolean $enforce 强制删除
     */
    public function rmdir($dirname, $enforce = false) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        $list = $this->nlist($dirname);
        if ($list && $enforce) {
            $this->chdir($dirname);
            foreach ($list as $v) {
                $this->f_delete($v);
            }
        } elseif ($list && !$enforce) {
            $this->err_code = 3;
            return false;
        }
        @ftp_rmdir($this->link, $dirname);
        return true;
    }
        
    /**
     * 删除指定文件
     * @param string $filename 文件名
     */
    public function f_delete($filename) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        if (@ftp_delete($this->link, $filename)) {
            return true;
        } else {
            $this->err_code = 4;
            return false;
        }
    }
        
    /**
     * 返回给定目录的文件列表
     * @param string $dirname  目录地址
     * @return array 文件列表数据
     */
    public function nlist($dirname) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        if ($list = @ftp_nlist($this->link, $dirname)) {
            return $list;
        } else {
            $this->err_code = 5;
            return false;
        }
    }
        
    /**
     * 在 FTP 服务器上改变当前目录
     * @param string $dirname 修改服务器上当前目录
     */
    public function chdir($dirname) {
        if (!$this->link) {
            $this->err_code = 2;
            return false;
        }
        if (@ftp_chdir($this->link, $dirname)) {
            return true;
        } else {
            $this->err_code = 6;
            return false;
        }
    }
        
    /**
     * 获取错误信息
     */
    public function get_error() {
        if (!$this->err_code)
            return false;
        $err_msg = array(
            '1' => 'Server can not connect',
            '2' => 'Not connect to server',
            '3' => 'Can not delete non-empty folder',
            '4' => 'Can not delete file',
            '5' => 'Can not get file list',
            '6' => 'Can not change the current directory on the server',
            '7' => 'Can not upload files'
        );
        return $err_msg[$this->err_code];
    }
        
    /**
     * 检测目录名
     * @param string $url 目录
     * @return 由 / 分开的返回数组
     */
    private function ck_dirname($url) {
        $url = str_replace('', '/', $url);
        $urls = explode('/', $url);
        return $urls;
    }
        
    /**
     * 关闭FTP连接
     */
    public function close() {
        return @ftp_close($this->link);
    }
        
}

?>


二、uc_server/avatar.php文件代码如下:



 
  

三、后台设置远程附件:

【discuz x3】如何将头像和帖内等附件分离到远程服务器?_第1张图片

四、sql修改:

update pre_forum_attachment_0 set remote = '1';
update pre_forum_attachment_1 set remote = '1';
update pre_forum_attachment_2 set remote = '1';
update pre_forum_attachment_3 set remote = '1';
update pre_forum_attachment_4 set remote = '1';
update pre_forum_attachment_5 set remote = '1';
update pre_forum_attachment_6 set remote = '1';
update pre_forum_attachment_7 set remote = '1';
update pre_forum_attachment_8 set remote = '1';
update pre_forum_attachment_9 set remote = '1';
update pre_portal_article_title set remote=1;
update pre_portal_attachment set remote=1;
update pre_portal_topic_pic set remote=1;
update pre_home_pic set remote=remote+1;

五、效果如下:


【discuz x3】如何将头像和帖内等附件分离到远程服务器?_第2张图片
 
 

你可能感兴趣的:(【discuzx2,x3深入研究】)