你现在的位置:首页 > PHP网站建设知识库 > UCenter Home > 正文

如何使用外部程序整合Ucenter

Ucenter整合原理:

无论是discuz!,uchome,或是其它应用程序,都是依靠api 文件夹下的uc.php来接收uc server发来的消息。所以api和uc_client在应用程序下是必须的。

网上也有很多文章说明Ucenter整合的原理了,虽然很容易明白,但毕竟Ucenter这个模式还是做得比较有心思的,值得其它程序参考。这里就不啰嗦地再说一遍了。

以同步登陆为例,通过uc_user_login函数和uc_user_synlogin进行登陆,
list($uid, $username, $password, $email) = uc_user_login($_POST['user_name2'], $_POST['user_pwd2']);
if($uid > 0) {
$_SESSION["dxc_user_name"]=$user_name2;
echo $str=uc_user_synlogin($uid); //同步 必须要输出
}

我们查看一下输出的结果:

 

\

 

其实就是Ucenter生成上面js代码,遍历访问各个应用程序 接口来实现登陆。

FAQ

F:为什么按官方给出的例子整合,会出现应用程序 通信失败?

其实这个完全是康盛的技术员问题。因为例子给出的api文件夹下的uc.php完全是按discuz!论坛来修改的,并没有考虑到其它应用程序

第59行中:
require_once DISCUZ_ROOT.'./include/db_mysql.class.php'; //问题出在这里了,这个文件中有很多地方都是这样包含,难道康盛的人以为这个文件夹下一定会有db_mysql.class.php这个文件?

解决方法就是根据uc.php里面的内容,检查你同目录下有没有相关的文件,没有就从论坛拷一个过去。
并且在config.inc.php文件中:把discuz!的定义数据库代码也拷进来(或者自己修改。因为程序定义用的变量就是论坛的变量)

$dbhost = 'localhost'; // 数据库服务器
$dbuser = 'root'; // 数据库用户名
$dbpw = ''; // 数据库密码
$dbname = 'dxc'; // 数据库名
$pconnect = 0; // 数据库持久连接 0=关闭, 1=打开
 
而且我见这个问题从09年开始一直都有人提出,但康盛居然还一直用的都是这个例子。真无言

F:uchome 原来通信正常的,转移服务器和环境后,就通信失败了 ? 
     Q:这个和文件进制有关,,把uchome的source文件夹全部重新上传一次就行了

F:通信一切正常,但就是无法同步登陆? 
      Q:这是连接 UCenter 的方式没有选择对。如果要同步的话,那配置代码里的连接方式就不要用mysql,同时要指定UC_IP。

define('UC_CONNECT', ''); // 连接 UCenter 的方式: mysql/NULL, 默认为空时为 fscoketopen()
define('UC_IP', '127.0.0.1');

F:BBS第一次要激活才能同步,可以不激活就同步吗? 
Q:这是可以的,discuz!论坛里的zsheihei同学直接给出了方法,可以参考一下:
第一步:在论坛目录中找到./api/uc.php文件打开。
第二步:在uc.php大概216行找到如下代码段

function synlogin($get, $post) {
$uid = $get['uid'];
$username = $get['username'];
if(!API_SYNLOGIN) {
return API_RETURN_FORBIDDEN;
}
require_once $this->appdir.'./forumdata/cache/cache_settings.php';
$cookietime = 2592000;
$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
$uid = intval($uid);
$query = $this->db->query("SELECT username, uid, password, secques FROM ".$this->tablepre."members WHERE uid='$uid'");
if($member = $this->db->fetch_array($query)) {
_setcookie('sid', '', -86400 * 365);
_setcookie('cookietime', $cookietime, 31536000);
_setcookie('auth', _authcode("$member[password]/t$member[secques]/t$member[uid]", 'ENCODE', $discuz_auth_key), $cookietime);
} else {
_setcookie('cookietime', $cookietime, 31536000);
_setcookie('loginuser', $username, $cookietime);
_setcookie('activationauth', _authcode($username, 'ENCODE', $discuz_auth_key), $cookietime);
}
}


第三步:将上述代码替换成如下代码

function synlogin($get, $post) {
$uid = $get['uid'];
$username = $get['username'];
if(!API_SYNLOGIN) {
return API_RETURN_FORBIDDEN;
}
require_once $this->appdir.'./forumdata/cache/cache_settings.php';
$cookietime = 2592000;
$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
$uid = intval($uid);
$query = $this->db->query("SELECT username, uid, password, secques FROM ".$this->tablepre."members WHERE uid='$uid'");
if($member = $this->db->fetch_array($query)) {
_setcookie('sid', '', -86400 * 365);
_setcookie('cookietime', $cookietime, 31536000);
_setcookie('auth', _authcode("$member[password]/t$member[secques]/t$member[uid]", 'ENCODE', $discuz_auth_key), $cookietime);
} else {
require_once DISCUZ_ROOT.'./uc_client/client.php';
if($data = uc_get_user($username)) {
$password = md5(random(10));
$ip = $_SERVER['REMOTE_ADDR'];
$time = time();
$this->db->query("INSERT INTO ".$this->tablepre."members(uid,username,password,email,groupid,regip,regdate,lastip,lastvisit,lastactivity,pmsound,newsletter,timeoffset) VALUES ($uid,'$username','$password','$data[email]',10,'{$ip}',{$time},'{$ip}',{$time},{$time},1,1,9999)");
$this->db->query("INSERT INTO ".$this->tablepre."memberfields (uid) VALUES ({$uid})");
$query = $this->db->query("SELECT username, uid, password, secques FROM ".$this->tablepre."members WHERE uid='$uid'");
if($member = $this->db->fetch_array($query)) {
_setcookie('sid', '', -86400 * 365);
_setcookie('cookietime', $cookietime, 31536000);
_setcookie('auth', _authcode("$member[password]/t$member[secques]/t$member[uid]", 'ENCODE', $discuz_auth_key), $cookietime);
}else{
_setcookie('cookietime', $cookietime, 31536000);
_setcookie('loginuser', $username, $cookietime);
_setcookie('activationauth', _authcode($username, 'ENCODE', $discuz_auth_key), $cookietime);
}
}
}
}


第四步:将如下代码添加到uc.php文件的最后

function random($length, $numeric = 0) {
PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
if($numeric) {
$hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
} else {
$hash = '';
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
$max = strlen($chars) - 1;
for($i = 0; $i < $length; $i++) {
$hash .= $chars[mt_rand(0, $max)];
}
}
return $hash;
}

F:可以一注册,就马上同步登陆uchome吗? 
Q:uchome默认注册后要登陆一次以后才能同步登陆。因为uc只负责把会员注册好,并没有管到uchome里的事,而uchome开发要开通个人空间,用户其它资料这些表。
所以,在注册时同时把uchome的这两个表也开通了,(主要是uchome_space和uchome_spacefield两个表),并设置好cookie,就可以第一次也同时登陆了。