以用户登录为例介绍,其它注销,改密码,消息,头像,好友均类同。
得益于uc设计的精巧过程,整个过程,用户完全感觉不到ucenter的存在。这是整合程序历史上的创新。
以下为Supesite的uc_client和ucenter登录通信过程的一个例子:
1、登录入口index.php?action=login
//系统频道 if($_SGET['action'] != 'index') { if(empty($channels['menus'][$_SGET['action']]['upnameid']) && $channels['menus'][$_SGET['action']]['upnameid'] != 'news') { $scriptfile = S_ROOT.'./'.$_SGET['action'].'.php'; } else { $scriptfile = S_ROOT.'./news.php'; } //echo $scriptfile; if(file_exists($scriptfile)) { include_once($scriptfile); exit(); } }
提交登录action:batch.login.php?action=login
2、登录处理地址batch.login.php?action=login
include_once(S_ROOT.'./uc_client/client.php'); // 登录操作及其中涉及到的一些函数: $password = $_POST['password']; $username = $_POST['username']; // 去ucenter进行远程登录验证 $ucresult = uc_user_login($username, $password, $loginfield == 'uid');
如果登录成功,则查本地用户信息。如果有更新本地信息,如果没有插入新的用户数据保持与ucenter进行同步。
然后同步其他子系统登录信息:
$msg = $lang['login_succeed'].uc_user_synlogin($members['uid']); function uc_user_synlogin($uid) { $uid = intval($uid); $return = uc_api_post('user', 'synlogin', array('uid'=>$uid)); return $return; }
下面是一些程序代码与注释:
1 /** 2 * dfopen 方式取指定的模块和动作的数据 3 * 4 * @param string $module 请求的模块 5 * @param string $action 请求的动作 6 * @param array $arg 参数(会加密的方式传送) 7 * @return string 8 */ 9 function uc_api_post($module, $action, $arg = array()) { 10 $s = $sep = ''; 11 foreach($arg as $k => $v) { 12 $k = urlencode($k); 13 if(is_array($v)) { 14 $s2 = $sep2 = ''; 15 foreach($v as $k2 => $v2) { 16 $k2 = urlencode($k2); 17 $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2)); 18 $sep2 = '&'; 19 } 20 $s .= $sep.$s2; 21 } else { 22 $s .= "$sep$k=".urlencode(uc_stripslashes($v)); 23 } 24 $sep = '&'; 25 } 26 $postdata = uc_api_requestdata($module, $action, $s); 27 28 return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20); 29 } 30 31 /** 32 * 构造发送给用户中心的请求数据 33 * 34 * @param string $module 请求的模块 35 * @param string $action 请求的动作 36 * @param string $arg 参数(会加密的方式传送) 37 * @param string $extra 附加参数(传送时不加密) 38 * @return string 39 */ 40 function uc_api_requestdata($module, $action, $arg='', $extra='') { 41 $input = uc_api_input($arg); 42 $post = "m=$module&a=$action&inajax=2&release=".UC_CLIENT_RELEASE."&input=$input&appid=".UC_APPID.$extra; 43 return $post; 44 } 45 46 function uc_api_url($module, $action, $arg='', $extra='') { 47 $url = UC_API.'/index.php?'.uc_api_requestdata($module, $action, $arg, $extra); 48 return $url; 49 } 50 51 function uc_api_input($data) { 52 $s = urlencode(uc_authcode($data.'&agent='.md5($_SERVER['HTTP_USER_AGENT'])."&time=".time(), 'ENCODE', UC_KEY)); 53 return $s; 54 } 55 56 /** 57 * 远程打开URL 58 * @param string $url 打开的url, 如 http://www.baidu.com/123.htm 59 * @param int $limit 取返回的数据的长度 60 * @param string $post 要发送的 POST 数据,如uid=1&password=1234 61 * @param string $cookie 要模拟的 COOKIE 数据,如uid=123&auth=a2323sd2323 62 * @param bool $bysocket TRUE/FALSE 是否通过SOCKET打开 63 * @param string $ip IP地址 64 * @param int $timeout 连接超时时间 65 * @param bool $block 是否为阻塞模式 66 * @return 取到的字符串 67 */ 68 function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) { 69 $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; 70 if($__times__ > 2) { 71 return ''; 72 } 73 $url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__"; 74 return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block); 75 } 76 77 function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) { 78 $return = ''; 79 $matches = parse_url($url); 80 !isset($matches['host']) && $matches['host'] = ''; 81 !isset($matches['path']) && $matches['path'] = ''; 82 !isset($matches['query']) && $matches['query'] = ''; 83 !isset($matches['port']) && $matches['port'] = ''; 84 $host = $matches['host']; 85 $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/'; 86 $port = !empty($matches['port']) ? $matches['port'] : 80; 87 if($post) { 88 $out = "POST $path HTTP/1.0\r\n"; 89 $out .= "Accept: */*\r\n"; 90 //$out .= "Referer: $boardurl\r\n"; 91 $out .= "Accept-Language: zh-cn\r\n"; 92 $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; 93 $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; 94 $out .= "Host: $host\r\n"; 95 $out .= 'Content-Length: '.strlen($post)."\r\n"; 96 $out .= "Connection: Close\r\n"; 97 $out .= "Cache-Control: no-cache\r\n"; 98 $out .= "Cookie: $cookie\r\n\r\n"; 99 $out .= $post; 100 } else { 101 $out = "GET $path HTTP/1.0\r\n"; 102 $out .= "Accept: */*\r\n"; 103 //$out .= "Referer: $boardurl\r\n"; 104 $out .= "Accept-Language: zh-cn\r\n"; 105 $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; 106 $out .= "Host: $host\r\n"; 107 $out .= "Connection: Close\r\n"; 108 $out .= "Cookie: $cookie\r\n\r\n"; 109 } 110 $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout); 111 if(!$fp) { 112 return '';//note $errstr : $errno \r\n 113 } else { 114 stream_set_blocking($fp, $block); 115 stream_set_timeout($fp, $timeout); 116 @fwrite($fp, $out); 117 $status = stream_get_meta_data($fp); 118 if(!$status['timed_out']) { 119 while (!feof($fp)) { 120 if(($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) { 121 break; 122 } 123 } 124 125 $stop = false; 126 while(!feof($fp) && !$stop) { 127 $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); 128 $return .= $data; 129 if($limit) { 130 $limit -= strlen($data); 131 $stop = $limit <= 0; 132 } 133 } 134 } 135 @fclose($fp); 136 return $return; 137 } 138 }
远程同步登录子系统操作之后:
//显示信息 function showmessage($message, $url_forward='', $second=3, $vars=array()) { global $_SGLOBAL, $_SCONFIG, $_SC, $channels; if(empty($_SGLOBAL['inajax']) && $url_forward && empty($second)) { //直接301跳转 obclean(); header("HTTP/1.1 301 Moved Permanently"); header("Location: $url_forward"); } else { if(!defined('IN_SUPESITE_ADMINCP')) { $tpl_file = 'showmessage'; $fullpath = 0; include_once(S_ROOT.'./language/message.lang.php'); if(!empty($mlang[$message])) $message = $mlang[$message]; } else { $tpl_file = 'admin/tpl/showmessage.htm'; $fullpath = 1; include_once(S_ROOT.'./language/admincp_message.lang.php'); if(!empty($amlang[$message])) $message = $amlang[$message]; } if(isset($_SGLOBAL['mlang'][$message])) $message = $_SGLOBAL['mlang'][$message]; foreach ($vars as $key => $val) { $message = str_replace('{'.$key.'}', $val, $message); } //显示 obclean(); if(!empty($url_forward)) { $second = $second * 1000; $message .= "<script>setTimeout(\"window.location.href ='$url_forward';\", $second);</script><ajaxok>"; } include template($tpl_file, $fullpath); ob_out(); } exit(); }