├── Mmosite用户单点登陆.jpg ├── README.md ├── uc_sso_test.php ├── 应用程序站 ├── UClientSSO.class.php ├── api │ ├── logout_user.php │ └── uc.php ├── client │ ├── client.php │ └── lib │ │ ├── FileCache.class.php │ │ ├── db.class.php │ │ ├── index.htm │ │ ├── uccode.class.php │ │ └── xml.class.php └── config.inc.php └── 用户验证中心 ├── include └── UCenterSSO.class.php ├── lib ├── nusoap.php └── xml.class.php └── port ├── UserSvc.php └── cookie_mgr.php /Mmosite用户单点登陆.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evangui/sso/525a3ad58f596150158e8a1cde66d8d705ea0c3c/Mmosite用户单点登陆.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 简单的调用示例,见uc_sso_test.php 2 | ## 注意:各个子站的用户登陆有效时间,请务必设置成 关闭浏览器就登出的形式。 3 | 4 | # 1. 摘要   5 | 本文主要介绍了利用webservice,session,cookie技术,来进行通用的单点登录系统的分析与设计。具体实现语言为PHP。单点登录,英文名为Single Sign On,简称为 SSO,是目前企业,网络业务的用户综合处理的重要组成部分。而SSO的定义,是在多个应用系统中,用户只需要登陆一次就可以访问所有相互信任的应用系统。 6 | 7 | # 2. 动机   8 | 用过uctenter的全站登录方式的朋友,应该都知道这是典型的观察者模式的解决方案。用户中心作为subject, 其所属observer的注册和删除统一在ucenter的后台进行。而各个子应用站点都对应一个observer。每次用户中心的登录动作,都会触发js脚本回调w3c标准的子站登录接口(api/uc.php)。 9 | 这种方式的缺点,本人认为主要是两点:1. 子站点过多时,回调接口相应增多,这个在分布子站的量的限制上,如何控制来使登录效率不会太低,不好把握; 2. 当某个子站回调接口出现问题时,默认的登录过程会卡住(可以限制登录程序的执行时间,但相应出现问题子站后面的子站的回调接口就调不到了。 10 | 基于以上问题,在实际开发过程中,本人设计了另一套单点登录系统。 11 | 12 | # 3. 登陆原理说明 13 | 单点登录的技术实现机制:当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。 14 | 可以看出,要实现SSO,需要以下主要的功能: 15 | * 所有应用系统共享一个身份认证系统; 16 | * 所有应用系统能够识别和提取ticket信息; 17 | * 应用系统能够识别已经登录过的用户,能自动判断当前用户是否登录过,从而完成单点登录的功能 18 | 19 | 基于以上基本原则,本人用php语言设计了一套单点登录系统的程序,目前已投入正式生成服务器运行。本系统程序,将ticket信息以全系统唯一的 session id作为媒介,从而获取当前在线用户的全站信息(登陆状态信息及其他需要处理的用户全站信息)。 20 | 21 | # 3. 过程说明: 22 | ## 3.1 登陆流程: 23 | ### 3.1.1 第一次登陆某个站: 24 | + 用户输入用户名+密码,向用户验证中心发送登录请求 25 | + 当前登录站点,通过webservice请求,用户验证中心验证用户名,密码的合法性。如果验证通过,则生成ticket,用于标识当前会话的用户,并将当前登陆子站的站点标识符记录到用户中心,最后 26 | + 将获取的用户数据和ticket返回给子站。如果验证不通过,则返回相应的错误状态码。 27 | + 根据上一步的webservice请求返回的结果,当前子站对用户进行登陆处理:如状态码表示成功的话,则当前站点通过本站cookie保存 ticket,并本站记录用户的登录状态。状态码表示失败的话,则给用户相应的登录失败提示。 28 | 29 | ### 3.1.2 登陆状态下,用户转到另一子: 30 | + 通过本站cookie或session验证用户的登录状态:如验证通过,进入正常本站处理程序;否则户中心验证用户的登录状态(发送ticket到用户验证中心),如验证通过,则对返回的用户信息进行本地的登录处理,否则表明用户未登录。 31 | 32 | ## 3.2 登出流程 33 | + 当前登出站清除用户本站的登录状态 和 本地保存的用户全站唯一的随机id 34 | + 通过webservice接口,清除全站记录的全站唯一的随机id。webservice接口会返回,登出其他已登录子站的javascript代码,本站输出此代码。 35 | + js代码访问相应站W3C标准的登出脚本 36 | 37 | ![Image text](https://raw.githubusercontent.com/evangui/sso/master/Mmosite%E7%94%A8%E6%88%B7%E5%8D%95%E7%82%B9%E7%99%BB%E9%99%86.jpg) 38 | 39 | # 4. 代码说明: 40 | 41 | ## 4.1 登陆流程: 42 | 用户从打开浏览器开始,第一个登陆的子站点,必须调用UClientSSO::loginSSO()方法。该方法返回全站唯一的随机id用于标识该用户。该随机id在UClientSSO::loginSSO()中已通过本站cookie保存,即该子站点保留了用户已登陆标识的存根于本站。 43 | ### 4.1.1 UClientSSO::loginSSO()方法如下: 44 | ``` 45 | /** 46 | * 用户验证中心 登陆用户处理 47 | * 48 | * @param string $username - 用户名 49 | * @param string $password - 用户原始密码 50 | * @param boolean $remember - 是否永久记住登陆账号 51 | * @param boolean $alreadyEnc - 传入的密码是否已经经过simpleEncPass加密过 52 | * 53 | * @return array - integer $return['status'] 大于 0:返回用户 ID,表示用户登录成功 54 | * -1:用户不存在,或者被删除 55 | * -2:密码错 56 | * -11:验证码错误 57 | * string $return['username'] : 用户名 58 | * string $return['password'] : 密码 59 | * string $return['email'] : Email 60 | */ 61 | static public function loginSSO($username, $password, $remember=false, $alreadyEnc=false) { 62 | self::_init(); 63 | self::_removeLocalSid(); 64 | $ret = array(); 65 | 66 | // 67 | //1. 处理传入webservice接口的参数 68 | // 69 | $_params = array( 70 | 'username' => $username, 71 | 'password' => $alreadyEnc ? trim($password) : self::simpleEncPass(trim($password)), 72 | 'ip' => self::onlineip(), 73 | 'siteFlag' => self::$site, 74 | 'remember' => $remember 75 | ); 76 | $_params['checksum'] = self::_getCheckSum($_params['username'] . $_params['password'] . 77 | $_params['ip'] . $_params['siteFlag'] . $_params['remember']); 78 | 79 | // 80 | // 2.调用webservice接口,进行登陆处理 81 | // 82 | $aRet = self::_callSoap('loginUCenter', $_params); 83 | 84 | if (intval($aRet['resultFlag']) > 0 && $aRet['sessID']) { 85 | //成功登陆 86 | //设置本地session id 87 | self::_setLocalSid($aRet['sessID']); 88 | 89 | //设置用户中心的统一session id脚本路径 90 | self::$_synloginScript = urldecode($aRet['script']); 91 | 92 | $ret = $aRet['userinfo']; 93 | } else { 94 | 95 | $ret['status'] = $aRet['resultFlag']; 96 | } 97 | 98 | return $ret; 99 | }//end of function 100 | ``` 101 | 102 | ### 4.1.2 用户验证中心的webservice服务程序,接收到登陆验证请求后,调用UCenter::loginUCenter()方法来处理登陆请求。 103 | ``` 104 | /** 105 | * 用户验证中心 登陆用户处理 106 | * 107 | * @param string $username 108 | * @param string $password 109 | * @param string $ip 110 | * @param string $checksum 111 | * @return array 112 | */ 113 | static public function loginUCenter($username, $password, $ip, $siteFlag, $remember=false) { 114 | self::_init(); 115 | session_start(); 116 | $ret = array(); 117 | $arr_login_res = login_user($username, $password, $ip); 118 | $res_login = $arr_login_res['status']; // 119 | $ret['resultFlag'] = $res_login; 120 | 121 | if ($res_login < 1) { 122 | //登陆失败 123 | } else { 124 | //登陆成功 125 | $_SESSION[self::$_ucSessKey] = $arr_login_res; 126 | 127 | $_SESSION[self::$_ucSessKey]['salt'] = 128 | self::_getUserPassSalt($_SESSION[self::$_ucSessKey]['username'], $_SESSION[self::$_ucSessKey]['password']); 129 | 130 | $ret['userinfo'] = $_SESSION[self::$_ucSessKey]; 131 | $ret['sessID'] = session_id(); //生成全站的唯一session id,作为ticket全站通行 132 | 133 | // 134 | //合作中心站回调登陆接口(设置用户中心的统一session id) 135 | // 136 | self::_createCoSitesInfo(); 137 | $uinfo = array(); 138 | $_timestamp = time(); 139 | $_rawCode = array( 140 | 'action' => 'setSid', 141 | 'sid' => $ret['sessID'], 142 | 'time' => $_timestamp, 143 | ); 144 | if ($remember) { 145 | $uinfo = array( 146 | 'remember' => 1, 147 | 'username' => $username, 148 | 'password' => $password 149 | ); 150 | } 151 | 152 | $ret['script'] = ''; 153 | $_rawStr = http_build_query(array_merge($_rawCode, $uinfo)); 154 | 155 | // 156 | // 合作站点的全域cookie设置脚本地址 157 | // 158 | foreach ((array)self::$_coSitesInfo as $_siteInfo) { 159 | $_code = self::authcode($_rawStr, 'ENCODE', $_siteInfo['key']); 160 | $_src = $_siteInfo['url'] . '?code=' . $_code . '&time=' . $_timestamp; 161 | $ret['script'] .= urlencode(''); 162 | } 163 | 164 | // 165 | // 记住已登陆战 166 | // 167 | self::registerLoggedSite($siteFlag, $ret['sessID']); 168 | 169 | unset($ret['userinfo']['salt']); 170 | } 171 | 172 | return $ret; 173 | } 174 | ``` 175 | 176 | ## 4.2 本站登陆成功后,进行本地化的用户登陆处理,其后验证用户是否登陆只在本地验证。(本地存取登陆用户状态的信息,请设置为关闭浏览器就退出) 177 | 178 | ## 4.3 当检测用户登陆状态时,请先调用本地的验证处理,若本地验证不通过,再调用UClientSSO::checkUserLogin()方法到用户中心检测用户的登陆状态。 179 | ### 4.3.1 UClientSSO::checkUserLogin()方法如下: 180 | ``` 181 | /** 182 | * 用户单点登陆验证函数 183 | * 184 | * @return array - integer $return['status'] 大于 0:返回用户 ID,表示用户登录成功 185 | * 0:用户没有在全站登陆 186 | * -1:用户不存在,或者被删除 187 | * -2:密码错 188 | * -3:未进行过单点登陆处理 189 | * -11:验证码错误 190 | * string $return['username'] : 用户名 191 | * string $return['password'] : 密码 192 | * string $return['email'] : Email 193 | */ 194 | public static function checkUserLogin(){ 195 | self::_init(); 196 | $ret = array(); 197 | $_sessId = self::_getLocalSid(); 198 | if (empty($_sessId)) { 199 | //永久记住账号处理 200 | if(isset($_COOKIE[_UC_USER_COOKIE_NAME]) && !empty($_COOKIE[_UC_USER_COOKIE_NAME])) { 201 | // 202 | // 根据cookie里的用户名和密码判断用户是否已经登陆。 203 | // 204 | $_userinfo = explode('|g|', self::authcode($_COOKIE[_UC_USER_COOKIE_NAME], 'DECODE', self::$_authcodeKey)); 205 | 206 | $username = $_userinfo[0]; 207 | $password = isset($_userinfo[1]) ? $_userinfo[1] : ''; 208 | if (empty($password)) { 209 | $ret['status'] = -3; 210 | } else { 211 | return self::loginSSO($username, $password, true, true); 212 | } 213 | 214 | } else { 215 | $ret['status'] = -3; 216 | } 217 | 218 | } else { 219 | // 220 | //本站原先已经登陆过,通过保留的sesson id存根去用户中心验证 221 | // 222 | $_params = array( 223 | 'sessId' => $_sessId, 224 | 'siteFlag' => self::$site, 225 | 'checksum' => md5($_sessId . self::$site . self::$_mcComunicationKey) 226 | ); 227 | $aRet = self::_callSoap('getOnlineUser', $_params); 228 | if (intval($aRet['resultFlag']) > 0) { 229 | //成功登陆 230 | $ret = $aRet['userinfo']; 231 | } else { 232 | $ret['status'] = $aRet['resultFlag']; 233 | } 234 | } 235 | 236 | return $ret; 237 | } 238 | ``` 239 | 240 | ### 4.3.2 用户验证中心的webservice服务程序,接收到检验登陆的请求后,调用UCenter::getOnlineUser()方法来处理登陆请求: 241 | ``` 242 | /** 243 | * 根据sid,获取当前登陆的用户信息 244 | * 245 | * @param string $sessId - 全站唯一session id,用做ticket 246 | * @return array 247 | */ 248 | /** 249 | * 根据sid,获取当前登陆的用户信息 250 | * 251 | * @param string $sessId - 全站唯一session id,用做ticket 252 | * @return array 253 | */ 254 | static public function getOnlineUser($sessId, $siteFlag) { 255 | self::_init(); 256 | session_id(trim($sessId)); 257 | session_start(); 258 | 259 | $ret = array(); 260 | $_userinfo = $_SESSION[self::$_ucSessKey]; 261 | 262 | if (isset($_userinfo['username']) && isset($_userinfo['password']) && 263 | self::_getUserPassSalt($_userinfo['username'], $_userinfo['password'])) { 264 | $ret['resultFlag'] = "1"; 265 | $ret['userinfo'] = $_userinfo; 266 | 267 | self::registerLoggedSite($siteFlag, $sessId); //记住已登陆战 268 | unset($ret['userinfo']['salt']); 269 | } else { 270 | $ret['resultFlag'] = "0"; 271 | } 272 | 273 | return ($ret); 274 | } 275 | ``` 276 | 277 | ## 4.4 单点登出时代码 278 | 调用UClientSSO::logoutSSO()方法。调用成功后,如需其他已登陆站立即登出,请调用 UClientSSO::getSynloginScript()方法获取W3C标准的script,在页面输出。 279 | ### 4.4.1 UClientSSO::logoutSSO()方法如下: 280 | ``` 281 | /** 282 | * 全站单点登出 283 | * - 通过webservice请求注销掉用户的全站唯一标识 284 | * 285 | * @return integer 1: 成功 286 | * -11:验证码错误 287 | */ 288 | public static function logoutSSO(){ 289 | self::_init(); 290 | $_sessId = self::_getLocalSid(); 291 | 292 | // 293 | //本站没有登陆的话,不让同步登出其他站 294 | // 295 | if (empty($_sessId)) { 296 | self::_initSess(true); 297 | return false; 298 | } 299 | $_params = array( 300 | 'sessId' => $_sessId, 301 | 'siteFlag' => self::$site, 302 | 'checksum' => md5($_sessId . self::$site . self::$_mcComunicationKey) 303 | ); 304 | 305 | $aRet = self::_callSoap('logoutUCenter', $_params); 306 | if (intval($aRet['resultFlag']) > 0) { 307 | //成功登出 308 | self::_removeLocalSid(); //移除本站记录的sid存根 309 | self::$_synlogoutScript = urldecode($aRet['script']); 310 | $ret = 1; 311 | } else { 312 | $ret = $aRet['resultFlag']; 313 | } 314 | return intval($ret); 315 | } 316 | ``` 317 | 318 | ### 4.4.2 用户验证中心的webservice服务程序,接收到全站登出请求后,调用UCenter::loginUCenter()方法来处理登陆请求 319 | ``` 320 | /** 321 | * 登出全站处理 322 | * 323 | * @param string - 全站唯一session id,用做ticket 324 | * @return boolean 325 | */ 326 | static public function logoutUCenter($sessId) { 327 | self::_init(); 328 | session_id(trim($sessId)); 329 | session_start(); 330 | 331 | $_SESSION = array(); 332 | return empty($_SESSION) ? true : false; 333 | } 334 | ``` 335 | 336 | # 5. 代码部署:           337 | ## 5.1 用户验证中心设置                 338 | + 用户验证中心向分站提供的webservice服务接口文件,即UserSvc.php部署在hostname/webapps/port/ UserSvc.php中。查看wsdl内容,请访问https://hostname/port/ UserSvc.php?wsdl 339 | + 用户中心用户单点服务类文件为UCenterSSO.class.php,文件路径为在hostname/webapps/include /UCenterSSO.class.php。该文件为用户单点登陆处理 的服务端类,被hostname/webapps/port/ UserSvc.php调用。用于获取用户的登陆信息,是否单点登陆的状态信息,单点登出处理等。 340 | + 用户验证中心通过W3C标准,利用cookie方式记录,删除全站统一的用户唯一随机id 的脚本文件为hostname/webapps/port/cookie_mgr.php. 341 |       342 | ## 5.2 子站点设置                 343 | + 各子站点请将,UClientSSO.class.php部署在用户中心服务客户端目录下。部署好后,请修改最后一行的UClientSSO::setSite('1'); 参数值为用户验证中心统一分配给各站的标识id. 344 | + 在部署的用户中心服务客户端包下的api目录下下,请将logout_sso.php脚本转移到此处,并编写进行本站登出的处理脚本。 345 | + 在子站点验证用户登陆状态的代码部分,额外增加到用户中心的单点登陆验证的处理。 346 | 即在首先通过本站验证用户的登陆状态,如果未通过验证,则去用户中心验证。验证操作要调用UClientSSO::checkUserLogin();接口,接口含义请查看代码注释。 347 | + 在分站的登出处理脚本中,通过UClientSSO::getSynlogoutScript();获取script串输出即可。 348 | 349 | # 6. 扩展功能:       350 | ## 6.1 记录跟踪所有在线用户 351 | 因为所有用户的登录都要经过用户验证中心,所有用户的ticket都在验证中心生成,可以将用户和该ticket(session id)在内存表中建立一个映射表。得到所有在线用户的记录表。 352 | 后期如有必要跟踪用户状态来实现其他功能,只要跟踪这个映射表就可以了。其他功能可以为: 获取在线用户列表,判断用户在线状态,获取在线用户人数等。 353 | 354 | ## 6.2 特殊统计处理 355 | 因为整个系统登录登出要经过用户验证中心,所以可以针对用户的特殊统计进行处理。如用户每天的登录次数,登陆时间,登陆状态失效时间,各时段的在线用户人数走势等。 356 | 357 | # 7. 其他事项:       358 | ## 7.1. 本站登陆状态有效时间问题: 359 | 全站要求用户登陆状态在关闭浏览器时就失效。要求各分站对session或cookie的处理方式按照如下进行: 360 | ### 7.1.1 Session方式记录用户登陆状态的站点 361 | 请在站点公用脚本开始处,添加以下代码 362 | ``` 363 | session_write_close(); 364 | ini_set('session.auto_start', 0); //关闭session自动启动 365 | ini_set('session.cookie_lifetime', 0); //设置session在浏览器关闭时失效 366 | ini_set('session.gc_maxlifetime', 3600); //session在浏览器未关闭时的持续存活时间 367 | ``` 368 | ### 7.1.2 cookie方式记录用户登陆状态的站点 369 | 请在设置用户登陆状态的cookie时,设置cookie有效时间为null. 370 | 371 | ## 7.2 其他:   372 | -------------------------------------------------------------------------------- /uc_sso_test.php: -------------------------------------------------------------------------------- 1 | 53 | 54 | -------------------------------------------------------------------------------- /应用程序站/UClientSSO.class.php: -------------------------------------------------------------------------------- 1 | 33 | * @version $Id: IP2Country.class.php, v 1.0 2009/03/04 $ 34 | * @package systen 35 | * @link http://www.guigui8.com/index.php/archives/34.html 36 | * 37 | * @history 38 | * 1. create the class. (by 桂桂 on 2009.03.04) 39 | * 40 | * 2. 修改在本站未登陆状态下,获取用户全站唯一id的方式。将跳转用户中心获取id的方式 改为设置相应域名的 41 | * 全域cookie来记录,这样避免在ajax等请求时,跳转不正常带来的问题。 42 | * (by 桂桂 on 2009.03.16) 43 | * 44 | * 3. 增加获取当前在线用户详细信息 处理的接口:UClientSSO::getOnlineUserDetail(); 45 | * (by 桂桂 on 2009.03.25) 46 | */ 47 | include_once dirname(__FILE__).'/xml.class.php'; 48 | 49 | //获取站点主机后缀(.com, .tmc or .local etc) 50 | $_aHttpHost = explode('.', $_SERVER['HTTP_HOST']); 51 | $_siteSurfix = $_aHttpHost[count($_aHttpHost) - 1]; 52 | 53 | //设置全站处理需要用到的cookie键名,域名 54 | define('_UC_USER_COOKIE_NAME', 'cookiexxxxxxx'); //永久记住用户信息的的cookie键名 55 | define('_UC_SID_NAME', 'sidxxxxxxxxx'); //全站sid cookie键名 56 | define('_UC_USER_COOKIE_DOMAIN', '.hostname.' . $_siteSurfix); //全域cookie域名 57 | 58 | define('_UC_KEY', 'xxxxxx'); 59 | 60 | 61 | /** 62 | *=------------------------------------------------------------------------= 63 | * class UClientSSO 64 | *=------------------------------------------------------------------------= 65 | * 66 | * 用户单点登陆,登出处理 的客户端类 67 | * 68 | * Copyright(c) 2008 by 桂桂. All rights reserved. 69 | * @author 桂桂 70 | * @version $Id: Model/OrderMgr.php, v 1.0 2008/4/21 $ 71 | * @package systen 72 | */ 73 | class UClientSSO 74 | { 75 | /** 76 | * 站点标志 77 | * 78 | * @var integer 79 | * @access protected 80 | */ 81 | protected static $site = 0; 82 | 83 | /** 84 | * SOAP通信协议[http=>'';https=>'ssl://';] 85 | * 86 | * @var string 87 | * @access protected 88 | */ 89 | protected static $scheme = ''; 90 | 91 | /** 92 | * SOAP主机地址 93 | * 94 | * @var string 95 | * @access protected 96 | */ 97 | protected static $host = 'hostname'; 98 | 99 | /** 100 | * SOAP通信端口[http=>80;https=>443;] 101 | * 102 | * @var integer 103 | * @access protected 104 | */ 105 | protected static $port = 80; 106 | 107 | /** 108 | * SOAP请求CGI 109 | * 110 | * @var string 111 | * @access protected 112 | */ 113 | protected static $cgi = '/port/testMmoUser.php'; 114 | 115 | /** 116 | * SOAP请求限时 117 | * 118 | * @var integer 119 | * @access protected 120 | */ 121 | protected static $stamp = 30; 122 | 123 | /** 124 | * 本站向用户中心获取与设置全站id的链接地址 125 | * 126 | * @var unknown_type 127 | */ 128 | static private $_getSessIdUrl; 129 | 130 | static private $_ucSessKey = '_uc_user'; 131 | 132 | /** 133 | * 与用户验证中心进行webservice请求通信的全局校验串 134 | * 135 | * @var unknown_type 136 | */ 137 | static private $_mcComunicationKey = 'xxxxx'; 138 | 139 | /** 140 | * 本站与用户中心 通过W3C标准,来获取与设置全站唯一id的通信私钥 141 | * 142 | * @var unknown_type 143 | */ 144 | static private $_authcodeKey = 'xxxxx'; 145 | 146 | /** 147 | * 全站登陆script串 148 | * 149 | * @var unknown_type 150 | */ 151 | static private $_synloginScript = null; 152 | 153 | /** 154 | * 全站登出script串 155 | * 156 | * @var unknown_type 157 | */ 158 | static private $_synlogoutScript = null; 159 | 160 | /** 161 | * 当前时间撮 162 | * 163 | * @var unknown_type 164 | */ 165 | static private $_timestamp; 166 | 167 | /** 168 | * 本站是否安装有php soap模块的标记 169 | * 170 | * @var unknown_type 171 | */ 172 | static private $_hasSoapModule; 173 | 174 | 175 | /** 176 | *=-------------------------------------------------------------------= 177 | *=-------------------------------------------------------------------= 178 | * 一. 公共方法定义 179 | *=-------------------------------------------------------------------= 180 | *=-------------------------------------------------------------------= 181 | */ 182 | /** 183 | * 用户验证中心 登陆用户处理 184 | * 185 | * @param string $username - 用户名 186 | * @param string $password - 用户原始密码 187 | * @param boolean $remember - 是否永久记住登陆账号 188 | * @param boolean $alreadyEnc - 传入的密码是否已经经过simpleEncPass加密过 189 | * 190 | * @return array - integer $return['status'] 大于 0:返回用户 ID,表示用户登录成功 191 | * -1:用户不存在,或者被删除 192 | * -2:密码错 193 | * -11:验证码错误 194 | * string $return['username'] : 用户名 195 | * string $return['password'] : 密码 196 | * string $return['email'] : Email 197 | */ 198 | static public function loginSSO($username, $password, $remember=false, $alreadyEnc=false) { 199 | self::_init(); 200 | self::_removeLocalSid(); 201 | $ret = array(); 202 | 203 | // 204 | //1. 处理传入webservice接口的参数 205 | // 206 | $_params = array( 207 | 'username' => $username, 208 | 'password' => $alreadyEnc ? trim($password) : self::simpleEncPass(trim($password)), 209 | 'ip' => self::onlineip(), 210 | 'siteFlag' => self::$site, 211 | 'remember' => $remember 212 | ); 213 | $_params['checksum'] = self::_getCheckSum($_params['username'] . $_params['password'] . 214 | $_params['ip'] . $_params['siteFlag'] . $_params['remember']); 215 | 216 | // 217 | // 2.调用webservice接口,进行登陆处理 218 | // 219 | $aRet = self::_callSoap('loginUCenter', $_params); 220 | 221 | if (intval($aRet['resultFlag']) > 0 && $aRet['sessID']) { 222 | //成功登陆 223 | //设置本地session id 224 | self::_setLocalSid($aRet['sessID']); 225 | 226 | //设置用户中心的统一session id脚本路径 227 | self::$_synloginScript = urldecode($aRet['script']); 228 | 229 | $ret = $aRet['userinfo']; 230 | } else { 231 | 232 | $ret['status'] = $aRet['resultFlag']; 233 | } 234 | 235 | return $ret; 236 | } 237 | 238 | /** 239 | * 获取设置全站登陆的scirpt代码(获取后,请在页面中输出) 240 | * 241 | * @return unknown 242 | */ 243 | public static function getSynloginScript(){ 244 | return self::$_synloginScript; 245 | } 246 | 247 | /** 248 | * 用户单点登陆验证函数 249 | * 250 | * @return array - integer $return['status'] 大于 0:返回用户 ID,表示用户登录成功 251 | * 0:用户没有在全站登陆 252 | * -1:用户不存在,或者被删除 253 | * -2:密码错 254 | * -3:未进行过单点登陆处理 255 | * -11:验证码错误 256 | * string $return['username'] : 用户名 257 | * string $return['password'] : 密码 258 | * string $return['email'] : Email 259 | */ 260 | public static function checkUserLogin(){ 261 | self::_init(); 262 | $ret = array(); 263 | $_sessId = self::_getLocalSid(); 264 | if (empty($_sessId)) { 265 | //永久记住账号处理 266 | if(isset($_COOKIE[_UC_USER_COOKIE_NAME]) && !empty($_COOKIE[_UC_USER_COOKIE_NAME])) 267 | { 268 | 269 | //3. 根据cookie里的用户名和密码判断用户是否已经登陆。 270 | $_userinfo = explode('|g|', self::authcode($_COOKIE[_UC_USER_COOKIE_NAME], 'DECODE', self::$_authcodeKey)); 271 | 272 | $username = $_userinfo[0]; 273 | $password = isset($_userinfo[1]) ? $_userinfo[1] : ''; 274 | if (empty($password)) { 275 | $ret['status'] = -3; 276 | } else { 277 | return self::loginSSO($username, $password, true, true); 278 | } 279 | 280 | } else { 281 | $ret['status'] = -3; 282 | } 283 | 284 | } else { 285 | // 286 | //本站原先已经登陆过,通过保留的sesson id存根去用户中心验证 287 | // 288 | $_params = array( 289 | 'sessId' => $_sessId, 290 | 'siteFlag' => self::$site, 291 | 'checksum' => md5($_sessId . self::$site . self::$_mcComunicationKey) 292 | ); 293 | $aRet = self::_callSoap('getOnlineUser', $_params); 294 | if (intval($aRet['resultFlag']) > 0) { 295 | //成功登陆 296 | $ret = $aRet['userinfo']; 297 | } else { 298 | $ret['status'] = $aRet['resultFlag']; 299 | } 300 | } 301 | 302 | return $ret; 303 | } 304 | 305 | 306 | /** 307 | * 全站单点登出 308 | * - 通过webservice请求注销掉用户的全站唯一标识 309 | * 310 | * @return integer 1: 成功 311 | * -11:验证码错误 312 | */ 313 | public static function logoutSSO(){ 314 | self::_init(); 315 | $_sessId = self::_getLocalSid(); 316 | // 317 | //本站没有登陆的话,不让同步登出其他站 318 | // 319 | if (empty($_sessId)) { 320 | self::_initSess(true); 321 | return false; 322 | } 323 | $_params = array( 324 | 'sessId' => $_sessId, 325 | 'siteFlag' => self::$site, 326 | 'checksum' => md5($_sessId . self::$site . self::$_mcComunicationKey) 327 | ); 328 | 329 | $aRet = self::_callSoap('logoutUCenter', $_params); 330 | if (intval($aRet['resultFlag']) > 0) { 331 | //成功登出 332 | self::_removeLocalSid(); //移除本站记录的sid存根 333 | self::$_synlogoutScript = urldecode($aRet['script']); 334 | $ret = 1; 335 | } else { 336 | $ret = $aRet['resultFlag']; 337 | } 338 | return intval($ret); 339 | } 340 | 341 | /** 342 | * 获取立即登出其他站的script代码 343 | * 注意:如果用UClientSSO::logoutSSO()成功登出,且要立即登出其他站, 344 | * 必须调用本方法来获取登出代码,在页面中输出。 345 | * 346 | * @return unknown 347 | */ 348 | public static function getSynlogoutScript(){ 349 | return self::$_synlogoutScript; 350 | } 351 | 352 | /** 353 | * 用户单点登陆验证函数 + 获取用户详细资料的处理 354 | * 355 | * 注意:获取用户详细资料的处理 是在单点登陆成功后才会有信息返回,否则 356 | * 357 | * @return array - integer $return['status'] 1:表示资料获取成功 358 | * 0:用户没有在全站登陆 359 | * -1:用户不存在,或者被删除 360 | * -3:未进行过单点登陆处理 361 | * -11:验证码错误 362 | * string $return[$specified_field] : 所有指定的field字段内容 363 | */ 364 | public static function getOnlineUserDetail($fields = null){ 365 | self::_init(); 366 | $ret = array(); 367 | $_sessId = self::_getLocalSid(); 368 | if (empty($_sessId)) { 369 | //永久记住账号处理 370 | if(isset($_COOKIE[_UC_USER_COOKIE_NAME]) && !empty($_COOKIE[_UC_USER_COOKIE_NAME])) 371 | { 372 | 373 | //3. 根据cookie里的用户名和密码判断用户是否已经登陆。 374 | $_userinfo = explode('|g|', self::authcode($_COOKIE[_UC_USER_COOKIE_NAME], 'DECODE', self::$_authcodeKey)); 375 | 376 | $username = $_userinfo[0]; 377 | $password = isset($_userinfo[1]) ? $_userinfo[1] : ''; 378 | if (empty($password)) { 379 | $ret['status'] = -3; 380 | } else { 381 | $_loginRes = self::loginSSO($username, $password, true, true); 382 | 383 | //登陆成功,重新向用户中心发送获取详细信息的请求 384 | if ($_loginRes['status'] > 0) { 385 | $_sessId = self::_getLocalSid(); 386 | if (empty($_sessId)) { 387 | $ret['status'] = -3; 388 | } else { 389 | return self::getOnlineUserDetail($fields); 390 | } 391 | 392 | } else { 393 | $ret['status'] = -3; 394 | } 395 | 396 | }// end of remember's login check 397 | 398 | } else { 399 | $ret['status'] = -3; 400 | } 401 | 402 | } else { 403 | // 404 | //本站原先已经登陆过,通过保留的sesson id存根去用户中心验证 405 | // 406 | $_params = array( 407 | 'sessId' => $_sessId, 408 | 'siteFlag' => self::$site, 409 | 'fields' => $fields, 410 | 'checksum' => md5($_sessId . self::$site . self::$_mcComunicationKey) 411 | ); 412 | $aRet = self::_callSoap('getOnlineUserDetail', $_params); 413 | if (intval($aRet['resultFlag']) > 0) { 414 | //成功登陆 415 | $ret = $aRet['userinfo']; 416 | $ret['status'] = 1; 417 | } else { 418 | $ret['status'] = $aRet['resultFlag']; 419 | } 420 | } 421 | 422 | return $ret; 423 | } 424 | 425 | public static function getOnlineList() {} 426 | 427 | public static function getUserCount() {} 428 | 429 | public static function remove() {} 430 | 431 | /** 432 | * 与用户中心通信的可逆 加密方法 433 | * 434 | * @param unknown_type $string 435 | * @param unknown_type $operation 436 | * @param unknown_type $key 437 | * @param unknown_type $expiry 438 | * @return unknown 439 | */ 440 | public static function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { 441 | $string = str_replace(' ', '+', $string); 442 | $ckey_length = 4; 443 | 444 | $key = md5($key ? $key : _UC_KEY); 445 | $keya = md5(substr($key, 0, 16)); 446 | $keyb = md5(substr($key, 16, 16)); 447 | $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; 448 | 449 | $cryptkey = $keya.md5($keya.$keyc); 450 | $key_length = strlen($cryptkey); 451 | 452 | $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; 453 | $string_length = strlen($string); 454 | 455 | $result = ''; 456 | $box = range(0, 255); 457 | 458 | $rndkey = array(); 459 | for($i = 0; $i <= 255; $i++) { 460 | $rndkey[$i] = ord($cryptkey[$i % $key_length]); 461 | } 462 | 463 | for($j = $i = 0; $i < 256; $i++) { 464 | $j = ($j + $box[$i] + $rndkey[$i]) % 256; 465 | $tmp = $box[$i]; 466 | $box[$i] = $box[$j]; 467 | $box[$j] = $tmp; 468 | } 469 | 470 | for($a = $j = $i = 0; $i < $string_length; $i++) { 471 | $a = ($a + 1) % 256; 472 | $j = ($j + $box[$a]) % 256; 473 | $tmp = $box[$a]; 474 | $box[$a] = $box[$j]; 475 | $box[$j] = $tmp; 476 | $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); 477 | } 478 | 479 | if($operation == 'DECODE') { 480 | if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { 481 | return substr($result, 26); 482 | } else { 483 | return ''; 484 | } 485 | } else { 486 | return $keyc.str_replace('=', '', base64_encode($result)); 487 | } 488 | } 489 | 490 | /** 491 | * 取得用户IP 492 | */ 493 | public static function onlineip(){ 494 | if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { 495 | $onlineip = getenv('HTTP_CLIENT_IP'); 496 | } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { 497 | $onlineip = getenv('HTTP_X_FORWARDED_FOR'); 498 | } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { 499 | $onlineip = getenv('REMOTE_ADDR'); 500 | } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { 501 | $onlineip = $_SERVER['REMOTE_ADDR']; 502 | } 503 | return preg_replace("/^([\d\.]+).*/", "\\1", $onlineip); 504 | } 505 | 506 | 507 | public static function simpleEncPass($pass) { 508 | return md5(strtolower($pass)); 509 | } 510 | 511 | public static function setSite($site){ 512 | self::$site = intval($site); 513 | } 514 | 515 | public static function setScheme($scheme){ 516 | self::$scheme = ('HTTP' == strtoupper($scheme)) ? '' : $scheme; 517 | } 518 | 519 | public static function setHost($host){ 520 | self::$host = $host; 521 | } 522 | 523 | public static function setPort($port){ 524 | self::$port = $port; 525 | } 526 | 527 | public static function setCGI($cgi){ 528 | self::$cgi = $cgi; 529 | } 530 | 531 | public static function setStamp($stamp){ 532 | self::$stamp = $stamp; 533 | } 534 | 535 | /** 536 | *=-------------------------------------------------------------------= 537 | *=-------------------------------------------------------------------= 538 | * 一. 私有方法定义 539 | *=-------------------------------------------------------------------= 540 | *=-------------------------------------------------------------------= 541 | */ 542 | /** 543 | * 用cookie方式记录 用户全站的唯一标识 544 | * 545 | * @param unknown_type $sid 546 | */ 547 | private static function _setLocalSid($sid) { 548 | //本地多余设置一次全域cookie,主要是兼容checkUserLogin 中的cookie记录账号 的处理 549 | setcookie(_UC_SID_NAME, $sid, null, '/', _UC_USER_COOKIE_DOMAIN); 550 | } 551 | 552 | /** 553 | * 获取用cookie方式记录 的 用户全站的唯一标识 554 | * 555 | * @return unknown 556 | */ 557 | private static function _getLocalSid() { 558 | return isset($_COOKIE[_UC_SID_NAME]) ? $_COOKIE[_UC_SID_NAME] : ''; 559 | } 560 | 561 | /** 562 | * 获取用cookie方式记录 的 用户全站的唯一标识 563 | * 564 | * @return unknown 565 | */ 566 | private static function _removeLocalSid() { 567 | setcookie(_UC_SID_NAME, '', -1, '/', _UC_USER_COOKIE_DOMAIN); 568 | // setcookie(_UC_USER_COOKIE_NAME, '', -1, '/', _UC_USER_COOKIE_DOMAIN); 569 | } 570 | 571 | private static function _getUserPassSalt($username, $password) { 572 | return md5($username . $password . '#@g!&yS%j'); 573 | } 574 | 575 | /** 576 | * 本静态类 部分方法需要调用的初始化方法 577 | * 578 | */ 579 | private static function _init() { 580 | self::$_timestamp = time(); 581 | self::$_getSessIdUrl = 'http://' . self::$host . '/port/cookie_mgr.php'; 582 | self::$_hasSoapModule = class_exists('SoapClient') ? true : false; 583 | //检测站点域名是否和用户中心域名一致,如一致而且开启了sesion,则会导致webservice调用失败。 584 | self::_initSess(); 585 | } 586 | 587 | /** 588 | * 检测站点域名是否和用户中心域名一致,如一致而且开启了sesion,则会导致webservice调用失败 589 | * 590 | */ 591 | private static function _initSess($start=false) { 592 | if (!$start && isset($_SESSION)) { 593 | session_write_close(); 594 | } else if ($start) { 595 | @session_start(); 596 | } else { } 597 | return; 598 | } 599 | 600 | /** 601 | * 获取与用户中心webservice通信用的加密校验码 602 | * 603 | * @param unknown_type $str 604 | * @param unknown_type $flag 605 | * @return unknown 606 | */ 607 | private static function _getCheckSum($str, $flag=0) { 608 | return md5($str . self::$_mcComunicationKey); 609 | } 610 | 611 | /** 612 | * 简单的soap处理方法封装 613 | * 614 | * @param unknown_type $funcName 615 | * @param unknown_type $params 616 | * @return unknown 617 | */ 618 | private static function _callSoap($funcName, $params=array()) { 619 | if (self::$_hasSoapModule) { 620 | 621 | $params = array_values($params); 622 | $_c = count($params); 623 | $_wsdl = (empty(self::$scheme) ? 'http://' : 'https://') . self::$host . ':'. self::$port . self::$cgi . '?wsdl'; 624 | $_wsdl .= '&t=' . self::$_timestamp; 625 | 626 | try { 627 | $client = new SoapClient( 628 | $_wsdl, 629 | array('encoding'=>'UTF-8', 'exceptions' => true, 'trace' => 1) 630 | ); 631 | switch ($_c) { 632 | case 0 : $xmlStr = $client->$funcName();break; 633 | case 1 : $xmlStr = $client->$funcName($params[0]);break; 634 | case 2 : $xmlStr = $client->$funcName($params[0], $params[1]);break; 635 | case 3 : $xmlStr = $client->$funcName($params[0], $params[1], $params[2]);break; 636 | case 4 : $xmlStr = $client->$funcName($params[0], $params[1], $params[2], $params[3]);break; 637 | case 5 : $xmlStr = $client->$funcName($params[0], $params[1], $params[2], $params[3], $params[4]);break; 638 | case 6 : $xmlStr = $client->$funcName($params[0], $params[1], $params[2], $params[3], $params[4], $params[5]);break; 639 | default: $xmlStr = '';break; 640 | } 641 | } catch (SoapFault $e) { 642 | print "Sorry an error was caught executing your request: {$e->getMessage()}"; 643 | $xmlStr = ''; 644 | } 645 | $aRet = xml_unserialize($xmlStr); 646 | 647 | } else { 648 | $aRet = self::soap($funcName, array(), $params); 649 | } 650 | 651 | self::_initSess(true); 652 | return $aRet; 653 | 654 | } 655 | 656 | /** 657 | * SOAP函数 658 | * 659 | * @param unknown_type $op 660 | * @param unknown_type $head 661 | * @param unknown_type $body 662 | * @return unknown 663 | */ 664 | private static function soap($op, $head, $body) { 665 | $fp = fsockopen((self::$scheme . self::$host), self::$port, $errno, $errstr, self::$stamp); 666 | $return = array( 667 | 'flag' => 0, 668 | 'message' => 'Connect to host error!' 669 | ); 670 | if ($fp) { 671 | $_xml = ''; 672 | $_xml .= ''; 673 | $_xml .= ''; 674 | $_xml .= ''; 675 | $_xml .= ''; 676 | if (is_array($head)) { 677 | foreach ($head as $key => $value) 678 | $_xml .= '<' . $key . '>' . $value . ''; 679 | } 680 | $_xml .= ''; 681 | $_xml .= ''; 682 | $_xml .= ''; 683 | $_xml .= '<' . $op . ' xmlns="http://tempuri.org/">'; 684 | if (is_array($body)) { 685 | foreach ($body as $key => $value) 686 | $_xml .= '<' . $key . '>' . $value . ''; 687 | } 688 | $_xml .= ''; 689 | $_xml .= ''; 690 | $_xml .= ''; 691 | 692 | $_msg = "POST " . self::$cgi . " HTTP/1.1\r\n"; 693 | $_msg .= "Host: " . self::$host . "\r\n"; 694 | $_msg .= "Content-Type: text/xml; charset=utf-8\r\n"; 695 | $_msg .= "Content-Length: " . strlen($_xml) . "\r\n"; 696 | $_msg .= "Connection: Close \r\n"; 697 | $_msg .= "SOAPAction: \"http://tempuri.org/{$op}\"\r\n\r\n"; 698 | $_rs = ''; 699 | if(false !== fwrite($fp, ($_msg . $_xml))){ 700 | while (!feof($fp)) { 701 | $_rs .= fgets($fp, 1024); 702 | } 703 | } 704 | fclose($fp); 705 | 706 | $_rs = htmlspecialchars_decode($_rs); 707 | if(!empty($_rs)){ 708 | preg_match("/<.{1,4}({$op}Response)\s*?.*?>]{4,20}>(.+?)<\/return><\/.{1,4}\\1>/", $_rs, $_matches); 709 | $return = (xml_unserialize($_matches[2])); 710 | } 711 | } 712 | return $return; 713 | } 714 | } 715 | 716 | if ($_siteSurfix == 'com') { 717 | UClientSSO::setScheme('ssl://'); 718 | UClientSSO::setPort(443); 719 | } else { 720 | UClientSSO::setScheme(''); 721 | UClientSSO::setPort(80); 722 | } 723 | 724 | UClientSSO::setHost('hostname'); 725 | UClientSSO::setCGI('/port/UserSvc.php'); 726 | UClientSSO::setSite('1'); 727 | 728 | ?> -------------------------------------------------------------------------------- /应用程序站/api/logout_user.php: -------------------------------------------------------------------------------- 1 | 10 | * @version $Id: port/logout.php, v 1.0 2009/03/05 $ 11 | * @package systen 12 | */ 13 | header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 14 | $cookiedomain = ''; // cookie 作用域 15 | $cookiepath = '/'; // cookie 作用路径 16 | 17 | logout_user(); 18 | 19 | function logout_user() { 20 | global $cookiepath; 21 | !isset($_SESSION) && session_start(); 22 | setcookie('mmo_user[username]', '', -86400, $cookiepath); 23 | setcookie('mmo_user[password]', '', -86400, $cookiepath); 24 | $_SESSION['mmo_user'] = array(); 25 | } 26 | ?> -------------------------------------------------------------------------------- /应用程序站/api/uc.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evangui/sso/525a3ad58f596150158e8a1cde66d8d705ea0c3c/应用程序站/api/uc.php -------------------------------------------------------------------------------- /应用程序站/client/client.php: -------------------------------------------------------------------------------- 1 | 15 | * @version $Id: uc_client/client.php, v 1.0 2008/4/21 $ 16 | * @package systen 17 | */ 18 | 19 | if(!defined('UC_API')) { 20 | exit('Access denied'); 21 | } 22 | error_reporting(0); 23 | 24 | define('IN_UC', TRUE); 25 | define('UC_VERSION', '1.0.0'); 26 | define('UC_RELEASE', '20080429'); 27 | 28 | define('UC_ROOT', substr(__FILE__, 0, -10)); 29 | 30 | define('UC_DATADIR', UC_ROOT.'./data/'); 31 | define('UC_DATAURL', UC_API.'/data'); 32 | 33 | 34 | /** 35 | * 定义ucenter的密码salt串,继承旧中新的$cfg["db"]["password_key"] 36 | */ 37 | define('PASSKEY_SALT', '*63$^@'); 38 | 39 | define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post'); 40 | $GLOBALS['uc_controls'] = array(); 41 | 42 | function uc_addslashes($string, $force = 0, $strip = FALSE) { 43 | !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); 44 | if(!MAGIC_QUOTES_GPC || $force) { 45 | if(is_array($string)) { 46 | foreach($string as $key => $val) { 47 | $string[$key] = uc_addslashes($val, $force, $strip); 48 | } 49 | } else { 50 | $string = addslashes($strip ? stripslashes($string) : $string); 51 | } 52 | } 53 | return $string; 54 | } 55 | 56 | function uc_stripslashes($string) { 57 | !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); 58 | if(MAGIC_QUOTES_GPC) { 59 | return stripslashes($string); 60 | } else { 61 | return $string; 62 | } 63 | } 64 | 65 | function uc_api_post($module, $action, $arg = array()) { 66 | $s = $sep = ''; 67 | foreach($arg as $k => $v) { 68 | if(is_array($v)) { 69 | $s2 = $sep2 = ''; 70 | foreach($v as $k2=>$v2) { 71 | $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2)); 72 | $sep2 = '&'; 73 | } 74 | $s .= $sep.$s2; 75 | } else { 76 | $s .= "$sep$k=".urlencode(uc_stripslashes($v)); 77 | } 78 | $sep = '&'; 79 | } 80 | $postdata = uc_api_requestdata($module, $action, $s); 81 | return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20); 82 | } 83 | 84 | function uc_api_requestdata($module, $action, $arg='', $extra='') { 85 | $input = uc_api_input($arg); 86 | $post = "m=$module&a=$action&inajax=2&input=$input&appid=".UC_APPID.$extra; 87 | return $post; 88 | } 89 | 90 | function uc_api_url($module, $action, $arg='', $extra='') { 91 | $url = UC_API.'/index.php?'.uc_api_requestdata($module, $action, $arg, $extra); 92 | return $url; 93 | } 94 | 95 | function uc_api_input($data) { 96 | $s = urlencode(uc_authcode($data.'&agent='.md5($_SERVER['HTTP_USER_AGENT'])."&time=".time(), 'ENCODE', UC_KEY)); 97 | return $s; 98 | } 99 | 100 | function uc_api_mysql($model, $action, $args=array()) { 101 | global $uc_controls; 102 | 103 | if(empty($uc_controls[$model])) { 104 | include_once UC_ROOT.'./lib/db.class.php'; 105 | include_once UC_ROOT.'./model/base.php'; 106 | include_once UC_ROOT."./control/$model.php"; 107 | eval("\$uc_controls['$model'] = new {$model}control();"); 108 | } 109 | 110 | if($action{0} != '_') { 111 | $args = uc_addslashes($args, 1, TRUE); 112 | $action = 'on'.$action; 113 | return $uc_controls[$model]->$action($args); 114 | } else { 115 | return ''; 116 | } 117 | } 118 | 119 | function uc_serialize($arr, $htmlon = 0) { 120 | include_once UC_ROOT.'./lib/xml.class.php'; 121 | return xml_serialize($arr, $htmlon); 122 | } 123 | 124 | function uc_unserialize($s) { 125 | include_once UC_ROOT.'./lib/xml.class.php'; 126 | return xml_unserialize($s); 127 | } 128 | 129 | function uc_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { 130 | 131 | $ckey_length = 4; 132 | 133 | $key = md5($key ? $key : UC_KEY); 134 | $keya = md5(substr($key, 0, 16)); 135 | $keyb = md5(substr($key, 16, 16)); 136 | $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; 137 | 138 | $cryptkey = $keya.md5($keya.$keyc); 139 | $key_length = strlen($cryptkey); 140 | 141 | $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; 142 | $string_length = strlen($string); 143 | 144 | $result = ''; 145 | $box = range(0, 255); 146 | 147 | $rndkey = array(); 148 | for($i = 0; $i <= 255; $i++) { 149 | $rndkey[$i] = ord($cryptkey[$i % $key_length]); 150 | } 151 | 152 | for($j = $i = 0; $i < 256; $i++) { 153 | $j = ($j + $box[$i] + $rndkey[$i]) % 256; 154 | $tmp = $box[$i]; 155 | $box[$i] = $box[$j]; 156 | $box[$j] = $tmp; 157 | } 158 | 159 | for($a = $j = $i = 0; $i < $string_length; $i++) { 160 | $a = ($a + 1) % 256; 161 | $j = ($j + $box[$a]) % 256; 162 | $tmp = $box[$a]; 163 | $box[$a] = $box[$j]; 164 | $box[$j] = $tmp; 165 | $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); 166 | } 167 | 168 | if($operation == 'DECODE') { 169 | if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { 170 | return substr($result, 26); 171 | } else { 172 | return ''; 173 | } 174 | } else { 175 | return $keyc.str_replace('=', '', base64_encode($result)); 176 | } 177 | } 178 | 179 | function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) { 180 | $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; 181 | if($__times__ > 2) { 182 | return ''; 183 | } 184 | $url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__"; 185 | return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block); 186 | } 187 | 188 | function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) { 189 | $return = ''; 190 | $matches = parse_url($url); 191 | $host = $matches['host']; 192 | $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/'; 193 | $port = !empty($matches['port']) ? $matches['port'] : 80; 194 | if($post) { 195 | $out = "POST $path HTTP/1.0\r\n"; 196 | $out .= "Accept: */*\r\n"; 197 | //$out .= "Referer: $boardurl\r\n"; 198 | $out .= "Accept-Language: zh-cn\r\n"; 199 | $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; 200 | $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; 201 | $out .= "Host: $host\r\n"; 202 | $out .= 'Content-Length: '.strlen($post)."\r\n"; 203 | $out .= "Connection: Close\r\n"; 204 | $out .= "Cache-Control: no-cache\r\n"; 205 | $out .= "Cookie: $cookie\r\n\r\n"; 206 | $out .= $post; 207 | } else { 208 | $out = "GET $path HTTP/1.0\r\n"; 209 | $out .= "Accept: */*\r\n"; 210 | //$out .= "Referer: $boardurl\r\n"; 211 | $out .= "Accept-Language: zh-cn\r\n"; 212 | $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; 213 | $out .= "Host: $host\r\n"; 214 | $out .= "Connection: Close\r\n"; 215 | $out .= "Cookie: $cookie\r\n\r\n"; 216 | } 217 | $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout); 218 | if(!$fp) { 219 | return ''; 220 | } else { 221 | stream_set_blocking($fp, $block); 222 | stream_set_timeout($fp, $timeout); 223 | @fwrite($fp, $out); 224 | $status = stream_get_meta_data($fp); 225 | if(!$status['timed_out']) { 226 | while (!feof($fp)) { 227 | if(($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) { 228 | break; 229 | } 230 | } 231 | 232 | $stop = false; 233 | while(!feof($fp) && !$stop) { 234 | $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); 235 | $return .= $data; 236 | if($limit) { 237 | $limit -= strlen($data); 238 | $stop = $limit <= 0; 239 | } 240 | } 241 | } 242 | @fclose($fp); 243 | return $return; 244 | } 245 | } 246 | 247 | function uc_app_ls() { 248 | $return = call_user_func(UC_API_FUNC, 'app', 'ls', array()); 249 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 250 | } 251 | 252 | function uc_feed_add($icon, $uid, $username, $title_template='', $title_data='', $body_template='', $body_data='', $body_general='', $target_ids='', $images = array()) { 253 | call_user_func(UC_API_FUNC, 'feed', 'add', 254 | array( 'icon'=>$icon, 255 | 'appid'=>UC_APPID, 256 | 'uid'=>$uid, 257 | 'username'=>$username, 258 | 'title_template'=>$title_template, 259 | 'title_data'=>$title_data, 260 | 'body_template'=>$body_template, 261 | 'body_data'=>$body_data, 262 | 'body_general'=>$body_general, 263 | 'target_ids'=>$target_ids, 264 | 'image_1'=>$images[0]['url'], 265 | 'image_1_link'=>$images[0]['link'], 266 | 'image_2'=>$images[1]['url'], 267 | 'image_2_link'=>$images[1]['link'], 268 | 'image_3'=>$images[2]['url'], 269 | 'image_3_link'=>$images[2]['link'], 270 | 'image_4'=>$images[3]['url'], 271 | 'image_4_link'=>$images[3]['link'] 272 | ) 273 | ); 274 | } 275 | 276 | function uc_feed_get($limit = 100) { 277 | $return = call_user_func(UC_API_FUNC, 'feed', 'get', array('limit'=>$limit)); 278 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 279 | } 280 | 281 | function uc_friend_add($uid, $friendid, $comment='') { 282 | return call_user_func(UC_API_FUNC, 'friend', 'add', array('uid'=>$uid, 'friendid'=>$friendid, 'comment'=>$comment)); 283 | } 284 | 285 | function uc_friend_delete($uid, $friendids) { 286 | return call_user_func(UC_API_FUNC, 'friend', 'delete', array('uid'=>$uid, 'friendids'=>$friendids)); 287 | } 288 | 289 | function uc_friend_totalnum($uid, $direction = 0) { 290 | return call_user_func(UC_API_FUNC, 'friend', 'totalnum', array('uid'=>$uid, 'direction'=>$direction)); 291 | } 292 | 293 | function uc_friend_ls($uid, $page = 1, $pagesize = 10, $totalnum = 10, $direction = 0) { 294 | $return = call_user_func(UC_API_FUNC, 'friend', 'ls', array('uid'=>$uid, 'page'=>$page, 'pagesize'=>$pagesize, 'totalnum'=>$totalnum, 'direction'=>$direction)); 295 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 296 | } 297 | 298 | /** 299 | * integer uc_user_register(array $arr_user_info) 300 | * 301 | * 新用户注册. 302 | * - 用户名、密码、Email 为一个用户在 UCenter 的基本数据,提交后 UCenter 会按照注册设置和词语过滤的规则检测用户名和 Email 的格式 303 | * 是否正确合法,如果正确则返回注册后的用户 ID,否则返回相应的错误信息. 304 | * 305 | * @param array $arr_user_info - 包含用户注册的基本资料信息。以key=>value的联合数组形式存放。 306 | * @return integer - 大于 0:返回用户 ID,表示用户注册成功 307 | * -1:用户名不合法 308 | * -2:包含不允许注册的词语 309 | * -3:用户名已经存在 310 | * -4:Email 格式有误 311 | * -5:Email 不允许注册 312 | * -6:该 Email 已经被注册 313 | * 314 | * 用法: 315 | * 316 | $arr_user_info = array(); 317 | $arr_user_info['username'] = 'user1'; 318 | $arr_user_info['password'] = md5('111111'); //请确认password是原始密码经md5加密过的 319 | $arr_user_info['email'] = 'user1@test.com'; 320 | //以上3个参数为必须项,下面的为可选 321 | $arr_user_info['nickname'] = 'user1'; 322 | $arr_user_info['face'] = 'http://image.91.com/m/face1.gif'; 323 | $arr_user_info['sex'] = '1'; 324 | $arr_user_info['location'] = 'China-Hubei-WuHan'; 325 | $arr_user_info['game'] = 'war3'; 326 | $arr_user_info['gameid'] = '2'; 327 | $arr_user_info['referralname'] = 'superMan1'; 328 | $arr_user_info['userbirthday'] = '1984-01-01'; 329 | $arr_user_info['gold'] = '50'; 330 | 331 | $uid = uc_user_register($_POST['username'], $_POST['password'], $_POST['email']); 332 | if($uid <= 0) { 333 | if($uid == -1) { 334 | echo '用户名不合法'; 335 | } elseif($uid == -2) { 336 | echo '包含要允许注册的词语'; 337 | } elseif($uid == -3) { 338 | echo '用户名已经存在'; 339 | } elseif($uid == -4) { 340 | echo 'Email 格式有误'; 341 | } elseif($uid == -5) { 342 | echo 'Email 不允许注册'; 343 | } elseif($uid == -6) { 344 | echo '该 Email 已经被注册'; 345 | } else { 346 | echo '未定义'; 347 | } 348 | } else { 349 | echo '注册成功'; 350 | } 351 | * 352 | * 353 | */ 354 | function uc_user_register($arr_user_info) { 355 | $arr_user_info['password'] = generate_pass($arr_user_info['password']); 356 | return call_user_func(UC_API_FUNC, 'user', 'register', $arr_user_info); 357 | } 358 | 359 | /** 360 | * array uc_user_login(string username , string password [, bool isuid]) 361 | * 362 | * 用户登录 363 | * - 本接口函数用于用户的登录验证,用户名及密码正确无误则返回用户在 UCenter 的基本数据,否则返回相应的错误信息。如果应用程序是升级过来 364 | * 的,并且当前登录用户和已有用户重名,那么返回的数组中 [4] 的值将返回 1 365 | * @param string $username - 用户名 / 用户 ID 366 | * @param string $password - 密码 367 | * @param bool $isuid - 是否使用用户 ID登录(1:使用用户 ID登录;0:(默认值) 使用用户名登录) 368 | * @return array - integer $return['status'] 大于 0:返回用户 ID,表示用户登录成功 369 | * -1:用户不存在,或者被删除 370 | * -2:密码错 371 | * string $return['username'] : 用户名 372 | * string $return['password'] : 密码 373 | * string $return['email'] : Email 374 | * bool $return['merge'] : 用户名是否重名 375 | */ 376 | function uc_user_login($username, $password, $ip, $isuid=0, $all_mode=0) { 377 | $isuid = intval($isuid); 378 | $password = generate_hash_pass($password); 379 | $arr = array('username'=>$username, 'password'=>$password, 'ip'=>trim($ip), 'isuid'=>$isuid, 'all_mode'=>$all_mode); 380 | $return = call_user_func(UC_API_FUNC, 'user', 'login', $arr); 381 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 382 | } 383 | 384 | 385 | function uc_get_user_num() { 386 | return call_user_func(UC_API_FUNC, 'user', 'get_user_num', array()); 387 | } 388 | 389 | /** 390 | * string uc_user_synlogin(integer uid) 391 | * 392 | * 同步登录 393 | * - (如果当前应用程序在 UCenter 中设置允许同步登录,那么本接口函数会通知其他设置了同步登录的应用程序登录,把返回的 HTML 输出在页面中即可完成对其它 394 | * 应用程序的通知。输出的 HTML 中包含执行远程的 javascript 脚本,请让页面在此脚本运行完毕后再进行跳转操作,否则可能会导致无法同步登录成功。 395 | * 同时要保证同步登录的正确有效,请保证其他应用程序的 Cookie 域和 Cookie 路径设置正确) 396 | * 注意:请根据各自应用程序需要,自行更改api/uc.php中的$action == 'synlogin'段的处理代码。 397 | * 398 | * 用法: 399 | * 400 | * list($uid, $username, $password, $email) = uc_user_login($_POST['username'], $_POST['password']); 401 | if($uid > 0) { 402 | echo '登录成功'; 403 | echo uc_user_synlogin($uid); //同步登陆 404 | } elseif($uid == -1) { 405 | echo '用户不存在,或者被删除'; 406 | } elseif($uid == -2) { 407 | echo '密码错'; 408 | } else { 409 | echo '未定义'; 410 | } 411 | * 412 | * 413 | * @param integer $uid - 用户 ID 414 | * @return string - 同步登录的 HTML 代码 415 | */ 416 | function uc_user_synlogin($uid, $remember=false) { 417 | return uc_api_post('user', 'synlogin', array('uid'=>$uid, 'remember'=>intval($remember))); 418 | } 419 | 420 | /** 421 | * string uc_user_synlogout() 422 | * 423 | * 同步退出 424 | * 425 | * @return string - 同步退出的 HTML 代码 426 | */ 427 | function uc_user_synlogout() { 428 | return uc_api_post('user', 'synlogout', array()); 429 | } 430 | 431 | /** 432 | * integer uc_user_edit(string $arr_user_info [, bool ignoreoldpw]) 433 | * 434 | * 用于更新用户资料。更新资料需验证用户的原密码是否正确,除非指定 ignoreoldpw 为 1。 435 | * 如果只修改 Email 不修改密码,可让 newpw 为空;同理如果只修改密码不修改 Email,可让 email 为空 436 | * 437 | * @param array $arr_user_info 438 | * @param bool $ignoreoldpw 439 | * @return integer 1:更新成功 440 | 0:没有做任何修改 441 | -1:旧密码不正确 442 | -4:Email 格式有误 443 | -5:Email 不允许注册 444 | -6:该 Email 已经被注册 445 | -7:没有做任何修改 446 | -8:该用户受保护无权限更改 447 | */ 448 | function uc_user_edit($arr_user_info, $ignoreoldpw = 0) { 449 | $arr_user_info['ignoreoldpw'] = $ignoreoldpw; 450 | if (isset($arr_user_info['password'])) { 451 | $arr_user_info['password'] = generate_pass($arr_user_info['password']); 452 | } 453 | return call_user_func(UC_API_FUNC, 'user', 'edit', $arr_user_info); 454 | } 455 | 456 | /** 457 | * 给指定数字类型字段加上相应值 458 | * - (如没必要,请将$ignorepw置为1,以提高查询速度) 459 | * 460 | * 用法: 461 | * 462 | * $res_add_gold = uc_user_add_fieldnum('guiyj', md5('111111'), 'gold', 39, 1); 463 | * 464 | * 465 | * @param string $username 466 | * @param string $password 467 | * @param string $field_name 468 | * @param integer $num 469 | * @param integer $ignorepw 470 | * @return integer 1:更新成功 471 | 0:没有做任何修改 472 | -1:密码不正确 473 | -2:更新失败 474 | */ 475 | function uc_user_add_fieldnum($username, $password, $field_name, $num = 0, $ignorepw = 0) { 476 | if ($num === 0) 477 | return 0; 478 | $param = array( 479 | 'username' => $username, 480 | 'password' => generate_pass($password), 481 | 'field_name' => $field_name, 482 | 'num' => intval($num), 483 | 'ignorepw' => $ignorepw 484 | ); 485 | $res = call_user_func(UC_API_FUNC, 'user', 'add_fieldnum', $param); 486 | return intval($res); 487 | } 488 | 489 | function uc_user_sub_fieldnum($username, $password, $field_name, $num = 0, $ignorepw = 0) { 490 | if ($num === 0) 491 | return 0; 492 | $param = array( 493 | 'username' => $username, 494 | 'password' => generate_pass($password), 495 | 'field_name' => $field_name, 496 | 'num' => intval($num), 497 | 'ignorepw' => $ignorepw 498 | ); 499 | $res = call_user_func(UC_API_FUNC, 'user', 'sub_fieldnum', $param); 500 | return intval($res); 501 | } 502 | /** 503 | * integer uc_user_add_gold($username, $password[, integer $gold]) 504 | * 505 | * 增加用户在用户中心的金币数 506 | * 507 | * @param string $username - 用户名 508 | * @param string $password - 经过md5加密过的用户密码 509 | * @param integer $gold - 需要增加的金币数 510 | * @return integer 1:更新成功 511 | 0:没有做任何修改 512 | -1:密码不正确 513 | -2:更新失败 514 | * 515 | */ 516 | function uc_user_add_gold($username, $password, $gold = 0) { 517 | if ($gold === 0) 518 | return 0; 519 | $password = generate_pass($password); 520 | $res = call_user_func(UC_API_FUNC, 'user', 'add_gold', array('username'=>$username, 'password'=>$password, 'gold'=>intval($gold))); 521 | return intval($res); 522 | } 523 | 524 | function uc_user_sub_gold($username, $password, $gold = 0) { 525 | if ($gold === 0) 526 | return 0; 527 | $password = generate_pass($password); 528 | $res = call_user_func(UC_API_FUNC, 'user', 'sub_gold', array('username'=>$username, 'password'=>$password, 'gold'=>intval($gold))); 529 | return intval($res); 530 | } 531 | /** 532 | * uc_user_pwd_edit 533 | * 534 | * 更新用户密码 535 | * 536 | * @param unknown_type $username 537 | * @param unknown_type $oldpw 538 | * @param unknown_type $newpw 539 | * @param unknown_type $ignoreoldpw 540 | * @return unknown 541 | */ 542 | function uc_user_pwd_edit($username, $oldpw, $newpw, $ignoreoldpw = 0) { 543 | $oldpw = generate_pass($oldpw); 544 | $newpw = generate_pass($newpw); 545 | return call_user_func(UC_API_FUNC, 'user', 'edit_pwd', array('username'=>$username, 'oldpw'=>$oldpw, 'newpw'=>$newpw, 'ignoreoldpw'=>$ignoreoldpw)); 546 | } 547 | 548 | function uc_user_delete($uid) { 549 | return call_user_func(UC_API_FUNC, 'user', 'delete', array('uid'=>$uid)); 550 | } 551 | /** 552 | * integer uc_user_checkname(string username) 553 | * 554 | * 检查用户输入的用户名的合法性 555 | * 556 | * @param string $username 557 | * @return integer 1:成功 558 | -1:用户名不合法 559 | -2:包含要允许注册的词语 560 | -3:用户名已经存在 561 | */ 562 | function uc_user_checkname($username) { 563 | return call_user_func(UC_API_FUNC, 'user', 'check_username', array('username'=>$username)); 564 | } 565 | 566 | /** 567 | * integer uc_user_nickname(string $nickname) 568 | * 569 | * 检查用户输入的用户呢称的合法性 570 | * 571 | * @param string $username 572 | * @return integer 1:成功 573 | -1:用户呢称不合法 574 | -2:包含要允许注册的词语 575 | -3:呢称已经存在 576 | */ 577 | function uc_user_nickname($nickname) { 578 | return call_user_func(UC_API_FUNC, 'user', 'check_nickname', array('nickname'=>$nickname)); 579 | } 580 | 581 | /** 582 | * integer uc_user_checkemail(string email) 583 | * 584 | * 检查用户输入的 Email 的合法性。 585 | * 586 | * @param string $email 587 | * @return integer 1:成功 588 | -4:Email 格式有误 589 | -5:Email 不允许注册 590 | -6:该 Email 已经被注册 591 | */ 592 | function uc_user_checkemail($email) { 593 | return call_user_func(UC_API_FUNC, 'user', 'check_email', array('email'=>$email)); 594 | } 595 | 596 | function uc_user_addprotected($username, $admin='') { 597 | return call_user_func(UC_API_FUNC, 'user', 'addprotected', array('username'=>$username, 'admin'=>$admin)); 598 | } 599 | 600 | function uc_user_deleteprotected($username) { 601 | return call_user_func(UC_API_FUNC, 'user', 'deleteprotected', array('username'=>$username)); 602 | } 603 | 604 | function uc_user_getprotected() { 605 | $return = call_user_func(UC_API_FUNC, 'user', 'getprotected', array('1'=>1)); 606 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 607 | } 608 | 609 | /** 610 | * array uc_get_user(string username [, string $query_fields] [, bool isuid]) 611 | * 612 | * 获取用户信息(如用户不存在,返回值为 integer 的数值 0) 613 | * 614 | * 用法: 615 | * 616 | * $username = 'guiyj'; 617 | * if($data = uc_get_user($username)) { 618 | * echo "用户$username的相关信息如下:
"; 619 | * echo "邮箱:" . $data['email'] . "
"; 620 | * echo "推荐人:" . $data['referralname'] . "
"; 621 | * } else { 622 | * echo '用户不存在'; 623 | * } 624 | *
625 | * 626 | * @param string $username - 用户名 627 | * @param string $query_fields - 需要获取的用户信息字段(默认为获取所有,否则以'field1, field2, field3'的形式设置此参数) 628 | * @param integer $isuid - 是否使用用户 ID获取(1:使用用户 ID获取;2:用邮箱获取;3:用昵称获取 0:(默认值) 使用用户名获取) 629 | * @return array - 以数据库中用户表字段名为键名,相应字段值为键值的联合数组。 630 | */ 631 | function uc_get_user($username, $query_fields='*', $isuid=0) { 632 | empty($query_fields) && $query_fields = '*'; 633 | $return = call_user_func(UC_API_FUNC, 'user', 'get_user', array('username'=>$username, 'query_fields'=>$query_fields, 'isuid'=>$isuid)); 634 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 635 | } 636 | 637 | function uc_user_merge($oldusername, $newusername, $uid, $password, $email) { 638 | return call_user_func(UC_API_FUNC, 'user', 'merge', array('oldusername'=>$oldusername, 'newusername'=>$newusername, 'uid'=>$uid, 'password'=>$password, 'email'=>$email)); 639 | } 640 | 641 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 642 | // 643 | // PM 相关接口 644 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 645 | 646 | /** 647 | * uc_pm_location 648 | * 649 | * @param string $username - 邮箱所属用户的用户名 650 | * @param integer $newpm - 新邮件数 651 | */ 652 | function uc_pm_location($username, $newpm = 0) { 653 | $hashed_uid = simple_md5($username); 654 | $apiurl = uc_api_url('pm_client', 'ls', "uid=$hashed_uid&username=$username", ($newpm ? '&folder=newbox' : '')); 655 | // $apiurl = uc_api_url('pm_client', 'ls', "uid=$uid", ($newpm ? '&folder=newbox' : '')); 656 | @header("Expires: 0"); 657 | @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); 658 | @header("Pragma: no-cache"); 659 | @header("location: $apiurl"); 660 | } 661 | /** 662 | * uc_pm_location_send 663 | * 664 | * @param string $username - 邮箱所属用户的用户名 665 | * @param string $msgto - 接收人用户名(暂时只支持单人) 666 | */ 667 | function uc_pm_location_send($username, $msgto = '', $fromsite='') { 668 | $hashed_uid = simple_md5($username); 669 | $args = "&from=$fromsite" . ($msgto ? "&msgto=$msgto" : "&msgto="); 670 | $apiurl = uc_api_url('pm_client', 'send', "uid=$hashed_uid&username=$username", $args); 671 | 672 | // $apiurl = uc_api_url('pm_client', 'send', "uid=$hashed_uid&username=$username", ($msgto ? "&msgto=$msgto" : "&msgto=")); 673 | echo ""; 674 | exit(); 675 | @header("Expires: 0"); 676 | @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); 677 | @header("Pragma: no-cache"); 678 | @header("location: $apiurl"); 679 | } 680 | /** 681 | * uc_pm_checknew 682 | * 683 | * 获取新消息的条数 684 | * 685 | * @param string $username - 用户名 686 | * @return unknown 687 | */ 688 | function uc_pm_checknew($username) { 689 | $uid = trim(simple_md5($username)); 690 | return call_user_func(UC_API_FUNC, 'pm', 'check_newpm', array('uid'=>$uid)); 691 | } 692 | 693 | /** 694 | * uc_pm_send 695 | * 696 | * @param string $msgfrom - 发送消息用户的用户名 697 | * @param string $msgto - 接收消息用户的用户名,多个用户中间用','分隔 698 | * @param string $subject - 消息主题 699 | * @param string $message - 消息内容 700 | * @param integer $instantly - 是否立即发送 701 | * @param integer $replypmid - 回复的消息 ID 702 | 大于 0:回复指定的短消息 703 | 0:(默认值) 发送新的短消息 704 | * @return mixed 705 | */ 706 | function uc_pm_send($msgfrom, $msgto, $subject, $message, $instantly = 1, $replypmid = 0) { 707 | if($instantly) { 708 | $replypmid = @is_numeric($replypmid) ? $replypmid : 0; 709 | return call_user_func(UC_API_FUNC, 'pm', 'sendpm', array('msgfrom'=>$msgfrom, 'msgto'=>$msgto, 'subject'=>$subject, 'message'=>$message, 'replypmid'=>$replypmid, 'isusername'=>1)); 710 | } else { 711 | $msgfrom = urlencode($msgfrom); 712 | $subject = urlencode($subject); 713 | $msgto = urlencode($msgto); 714 | $message = urlencode($message); 715 | $replypmid = @is_numeric($replypmid) ? $replypmid : 0; 716 | $replyadd = $replypmid ? "&pmid=$replypmid&do=reply" : ''; 717 | $hashed_uid = simple_md5($msgfrom); 718 | $apiurl = uc_api_url('pm_client', 'send', "uid=$hashed_uid", "&msgto=$msgto&subject=$subject&message=$message$replyadd"); 719 | @header("Expires: 0"); 720 | @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); 721 | @header("Pragma: no-cache"); 722 | @header("location: ".$apiurl); 723 | } 724 | } 725 | 726 | /** 727 | * uc_pm_delete 728 | * 729 | * 删除指定用户指定信箱的消息 730 | * 731 | * @param string $username - 用户名 732 | * @param string $folder 733 | * @param unknown_type $pmids 734 | * @return unknown 735 | */ 736 | function uc_pm_delete($username, $folder, $pmids) { 737 | $uid = simple_md5(trim($username)); 738 | return call_user_func(UC_API_FUNC, 'pm', 'delete', array('uid'=>$uid, 'folder'=>$folder, 'pmids'=>$pmids)); 739 | } 740 | 741 | /** 742 | * uc_pm_change_info 743 | * 744 | * @param string $pmids - 更新的pmid参数, 多个请用逗号分隔 745 | * @param array $arr_updated - 被更新的内容 746 | * @return unknown 747 | */ 748 | function uc_pm_change_info($pmids, $arr_updated) { 749 | $return = call_user_func(UC_API_FUNC, 'pm', 'changeinfo', array('pmids'=>$pmids, 'pm_info'=>$arr_updated)); 750 | return intval($return); 751 | 752 | } 753 | 754 | /** 755 | * uc_pm_get_num 756 | * 757 | * @param string $username - 用户名 758 | * @param string $folder - 短消息所在的文件夹 759 | newbox:新件箱 760 | inbox:(默认值) 收件箱 761 | outbox:发件箱 762 | trashbox:垃圾箱 763 | * @param string $filter - 过滤方式 764 | * newpm:(默认值) 未读消息,folder 为 inbox 和 outbox 时使用 765 | systempm:系统消息,folder 为 inbox 时使用 766 | announcepm:公共消息,folder 为 inbox 时使用 767 | * @return integer - 消息条数 768 | */ 769 | function uc_pm_get_num($username, $folder = 'inbox', $filter = 'newpm') { 770 | $uid = trim(simple_md5($username)); 771 | $return = call_user_func(UC_API_FUNC, 'pm', 'get_num', array('uid'=>$uid, 'folder'=>$folder, 'filter'=>$filter)); 772 | return intval($return); 773 | } 774 | 775 | function uc_pm_list($username, $page = 1, $pagesize = 10, $folder = 'inbox', $filter = 'newpm', $msglen = 0) { 776 | $uid = trim(simple_md5($username)); 777 | $page = intval($page); 778 | $pagesize = intval($pagesize); 779 | $return = call_user_func(UC_API_FUNC, 'pm', 'ls', array('uid'=>$uid, 'page'=>$page, 'pagesize'=>$pagesize, 'folder'=>$folder, 'filter'=>$filter, 'msglen'=>$msglen)); 780 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 781 | } 782 | 783 | function uc_pm_ignore($username) { 784 | $uid = trim(simple_md5($username)); 785 | return call_user_func(UC_API_FUNC, 'pm', 'ignore', array('uid'=>$uid)); 786 | } 787 | 788 | function uc_pm_view($username, $pmid) { 789 | $uid = trim(simple_md5($username)); 790 | $pmid = @is_numeric($pmid) ? $pmid : 0; 791 | $return = call_user_func(UC_API_FUNC, 'pm', 'view', array('uid'=>$uid, 'pmid'=>$pmid)); 792 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 793 | } 794 | 795 | function uc_pm_viewnode($username, $type = 0, $pmid = 0) { 796 | $uid = trim(simple_md5($username)); 797 | $pmid = @is_numeric($pmid) ? $pmid : 0; 798 | $return = call_user_func(UC_API_FUNC, 'pm', 'viewnode', array('uid'=>$uid, 'pmid'=>$pmid, 'type'=>$type)); 799 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 800 | } 801 | 802 | /** 803 | * 在trashbox和inbox间转移pm 804 | * 805 | * @param array $pms - 被转移的pm信息数组,每一pm为一字符串,包括3部分的信息,中间用'|'分隔。 806 | * 这3部分信息依次为:pmid,原pm的trash_status,pm信息是否为该用户发送(即pm是否是在该用户收件箱和垃圾响间转移) 807 | * eg: $pms = array('41|1|1', '42|2|0'); 808 | * @param boolean $in - 是否从其他邮箱转到垃圾箱,true表示是,false表示否,即将邮箱转到inbox或outbox 809 | * @return integer - 被影响的记录条数,其中-1表示$pms格式有误 810 | */ 811 | function uc_pm_move_trashbox($pms, $go_to_trash=true) { 812 | // $pmids = trim($pmids); 813 | if (!is_array($pms) || empty($pms)) { return -1; } 814 | $return = call_user_func(UC_API_FUNC, 'pm', 'move_trashbox', array('pms'=>$pms, 'go_to_trash'=>$go_to_trash)); 815 | return intval($return); 816 | } 817 | 818 | /** 819 | * Enter description here... 820 | * 821 | * @param unknown_type $uid 822 | * @return unknown 823 | */ 824 | function uc_pm_blackls_get($uid) { 825 | $uid = intval($uid); 826 | return call_user_func(UC_API_FUNC, 'pm', 'blackls_get', array('uid'=>$uid)); 827 | } 828 | 829 | function uc_pm_blackls_set($uid, $blackls) { 830 | $uid = intval($uid); 831 | return call_user_func(UC_API_FUNC, 'pm', 'blackls_set', array('uid'=>$uid, 'blackls'=>$blackls)); 832 | } 833 | 834 | function uc_domain_ls() { 835 | $return = call_user_func(UC_API_FUNC, 'domain', 'ls', array('1'=>1)); 836 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 837 | } 838 | 839 | function uc_credit_exchange_request($uid, $from, $to, $toappid, $amount) { 840 | $uid = intval($uid); 841 | $from = intval($from); 842 | $toappid = intval($toappid); 843 | $to = intval($to); 844 | $amount = intval($amount); 845 | return uc_api_post('credit', 'request', array('uid'=>$uid, 'from'=>$from, 'to'=>$to, 'toappid'=>$toappid, 'amount'=>$amount)); 846 | } 847 | 848 | function uc_tag_get($tagname, $nums = 0) { 849 | $return = call_user_func(UC_API_FUNC, 'tag', 'gettag', array('tagname'=>$tagname, 'nums'=>$nums)); 850 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 851 | } 852 | 853 | function uc_avatar($uid) { 854 | $uid = intval($uid); 855 | $uc_input = uc_api_input("uid=$uid"); 856 | $uc_avatarflash = UC_API.'/image/camera.swf?inajax=1&appid='.UC_APPID.'&input='.$uc_input.'&agent='.md5($_SERVER['HTTP_USER_AGENT']).'&ucapi='.urlencode(UC_API); 857 | return ''; 858 | } 859 | 860 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 861 | // 862 | // 用户联系信息接口 863 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 864 | /** 865 | * integer uc_user_concact_info_add(array $arr_user_info) 866 | * 867 | * 添加用户的附属联系资料(资料参数以联合数组形式传递),不需要添加的字段可以不填。 868 | * 869 | * 用法: 870 | * 871 | * $arr_user_info = array( 872 | * 'uid' => 502, 873 | * 'uname' => 'guiyj', 874 | * 'first_name' => 'gui', 875 | * 'last_name' => 'yajun', 876 | * 'address' => 'FuZhou, FuJian, China', 877 | * 'postcode' => '650010', 878 | * 'mobile_phone' => '13056856561', 879 | * 'hostpage' => 'http://www.test.com', 880 | * 'interest' => 'reading book, sleeping...', 881 | * 'msn' => '545565', 882 | * 'icq' => '545565', 883 | * 'aim' => '545565', 884 | * 'skype' => '545565', 885 | * 'google_talk' => '545565' 886 | * ); 887 | * $ret_id = uc_user_concact_info_add($arr_user_info); 888 | * if($ret_id <= 0) { 889 | * if($uid == -1) { 890 | * echo '用户id不合法'; 891 | * } elseif($uid == -2) { 892 | * echo '包含要允许注册的词语'; 893 | * } else { 894 | * echo '未定义'; 895 | * } 896 | * } else { 897 | * echo '添加成功'; 898 | * } 899 | * 900 | * @param array $arr_user_info 901 | * @return integer >0 返回附属资料记录项id 902 | * -1 用户id有误 903 | * -2 已经存在id为$arr_user_info['uid']的记录。 904 | */ 905 | function uc_user_concact_info_add($arr_user_info) { 906 | $res = call_user_func(UC_API_FUNC, 'user', 'add_concact_info', $arr_user_info); 907 | return intval($res); 908 | } 909 | 910 | /** 911 | * integer uc_user_concact_info_update(array $arr_user_info) 912 | * 913 | * 添加用户的附属联系资料(资料参数以联合数组形式传递) 914 | * 915 | * 用法: 916 | * 917 | * $arr_user_info = array( 918 | * 'uid' => 502, 919 | * 'first_name' => 'gui', 920 | * 'last_name' => 'yajun', 921 | * 'address' => 'FuZhou, FuJian, China', 922 | * 'postcode' => '650010', 923 | * 'mobile_phone' => '13056856561', 924 | * 'hostpage' => 'http://www.test.com', 925 | * 'interest' => 'reading book, sleeping...', 926 | * 'msn' => '545565', 927 | * 'icq' => '545565', 928 | * 'aim' => '545565', 929 | * 'skype' => '545565', 930 | * 'google_talk' => '545565' 931 | * ); 932 | * $ret_id = uc_user_concact_info_update($arr_user_info); 933 | * if($ret_id == 0) { 934 | * echo "更新失败"; 935 | * } elseif ($ret_id == 1) { 936 | * echo "更新成功"; 937 | * } elseif ($ret_id == -1) { 938 | * echo "用户id不合法"; 939 | * } else { 940 | * echo "未定义"; 941 | * } 942 | * 943 | * @param array $arr_user_info //需要更新的用户资料信息 944 | * @return integer 0 更新失败 945 | * 1 更新成功 946 | * -1 用户id有误 947 | */ 948 | function uc_user_concact_info_update($arr_user_info) { 949 | $res = call_user_func(UC_API_FUNC, 'user', 'update_concact_info', $arr_user_info); 950 | return intval($res); 951 | } 952 | 953 | /** 954 | * uc_user_concact_info_get 955 | * 956 | * 获取给定用户id号或用户名的用户的附属的联系信息资料 957 | * 958 | * @param mixed $uname - 用户id号或用户名 959 | * @param integer $isuid - 第一参数是否用户id,默认为否 960 | * @return array - 用户的第一类附属资料 961 | */ 962 | function uc_user_concact_info_get($uname, $isuid=0) { 963 | $return = call_user_func(UC_API_FUNC, 'user', 'get_concact_info', array('uname'=>$uname, 'isuid'=>$isuid)); 964 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 965 | } 966 | 967 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 968 | // 969 | // 用户详细信息接口 970 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 971 | /** 972 | * integer uc_user_detail_add(array $arr_user_info) 973 | * 974 | * 添加用户的附属详细资料(资料参数以联合数组形式传递) 975 | * 976 | * 用法: 977 | * 978 | * $arr_user_info = array( 979 | * 'uid' => 502, 980 | * 'uname' => 'guiyj', 981 | * 'hight' => '173', //身高(单位cm) 982 | * 'weight' => '60.18', //体重(单位kg,精确到小数点后2位) 983 | * 'blood_type' => 'AB', 984 | * 'living_situation' => '0', //结婚状况 0=未结婚;1=已结婚 985 | * 'character' => 'unknown', //性格特征 986 | * 'is_smoking' => '1', //是否吸烟 0=否;1=是 987 | * 'is_drinking' => '1', //是否喝酒 0=否;1=是 988 | * 'education' => 'bachelor', //教育程度 989 | * 'career' => 'worker', //职业 990 | * 'income' => '5555', //月收入 991 | * 'fav_music' => 'hiphop', //喜欢的音乐 992 | * 'fav_tv' => 'double heart', //喜欢的电视剧 993 | * 'fav_movie' => 'lalal', //喜欢的电影 994 | * 'fav_book' => '545565', //喜欢的书籍 995 | * 'fav_quote' => 'moveon or fallback' //喜欢的座右铭 996 | * ); 997 | * $ret_id = uc_user_detail_add($arr_user_info); 998 | * if($ret_id <= 0) { 999 | * if($uid == -1) { 1000 | * echo '用户id不合法'; 1001 | * } elseif($uid == -2) { 1002 | * echo '包含要允许注册的词语'; 1003 | * } else { 1004 | * echo '未定义'; 1005 | * } 1006 | * } else { 1007 | * echo '添加成功'; 1008 | * } 1009 | * 1010 | * 1011 | * @param array $arr_user_info 1012 | * @return integer >0 返回附属资料记录项id 1013 | * -1 用户id有误 1014 | * -2 已经存在id为$arr_user_info['uid']的记录。 1015 | */ 1016 | function uc_user_detail_add($arr_user_info) { 1017 | $res = call_user_func(UC_API_FUNC, 'user', 'add_user_detail', $arr_user_info); 1018 | return intval($res); 1019 | } 1020 | 1021 | /** 1022 | * integer uc_user_detail_update(array $arr_user_info) 1023 | * 1024 | * 更新用户的用户详细资料x信息(资料参数以联合数组形式传递) 1025 | * 1026 | * 用法: 1027 | * 1028 | * $arr_user_info = array( 1029 | * 'uid' => 502, 1030 | * 'uname' => 'guiyj', 1031 | * 'hight' => '173', //身高(单位cm) 1032 | * 'weight' => '60.18', //体重(单位kg,精确到小数点后2位) 1033 | * 'blood_type' => 'AB', 1034 | * 'living_situation' => '0', //结婚状况 0=未结婚;1=已结婚 1035 | * 'character' => 'unknown', //性格特征 1036 | * 'is_smoking' => '1', //是否吸烟 0=否;1=是 1037 | * 'is_drinking' => '1', //是否喝酒 0=否;1=是 1038 | * 'education' => 'bachelor', //教育程度 1039 | * 'career' => 'worker', //职业 1040 | * 'income' => '5555', //月收入 1041 | * 'fav_music' => 'hiphop', //喜欢的音乐 1042 | * 'fav_tv' => 'double heart', //喜欢的电视剧 1043 | * 'fav_movie' => 'lalal', //喜欢的电影 1044 | * 'fav_book' => '545565', //喜欢的书籍 1045 | * 'fav_quote' => 'moveon or fallback' //喜欢的座右铭 1046 | * ); 1047 | * $ret_id = uc_user_detail_update($arr_user_info); 1048 | * if($ret_id == 0) { 1049 | * echo "更新失败"; 1050 | * } elseif ($ret_id == 1) { 1051 | * echo "更新成功"; 1052 | * } elseif ($ret_id == -1) { 1053 | * echo "用户id不合法"; 1054 | * } else { 1055 | * echo "未定义"; 1056 | * } 1057 | * 1058 | * @param array $arr_user_info //需要更新的用户资料信息 1059 | * @return integer 0 更新失败 1060 | * 1 更新成功 1061 | * -1 用户id有误 1062 | */ 1063 | function uc_user_detail_update($arr_user_info) { 1064 | $res = call_user_func(UC_API_FUNC, 'user', 'update_user_detail', $arr_user_info); 1065 | return intval($res); 1066 | } 1067 | 1068 | /** 1069 | * uc_user_detail_get 1070 | * 1071 | * 获取给定用户id号或用户名的用户的附属详细信息 1072 | * 1073 | * @param mixed - 用户名或用户id 1074 | * @param integer $isuid - 第一个参数是否为用户id, 默认为否,即根据用户名获取用户详细信息 1075 | * @return array - 用户的附属详细信息 1076 | */ 1077 | function uc_user_detail_get($uname, $isuid=0) { 1078 | $return = call_user_func(UC_API_FUNC, 'user', 'get_user_detail', array('uname'=>$uname, 'isuid'=>$isuid)); 1079 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 1080 | } 1081 | 1082 | //mygame 1083 | /** 1084 | * integer uc_mygame_add(array $arr_game_info) 1085 | * 1086 | * 添加相关用户的游戏信息。(用户名放在做为参数的联合数组$arr_game_info中) 1087 | * 用法: 1088 | * 1089 | * $arr_game_info = array( 1090 | * 'user' => 'guiyj', 1091 | * 'gameid' => '2', 1092 | * 'gamename' => 'world of warcraft', 1093 | * 'server' => 'dianxin1', 1094 | * 'nickname' => 'daemon', 1095 | * 'class' => 'westen', 1096 | * 'level' => '70', 1097 | * 'link' => 'http://www.wowchina.com', 1098 | * 'type' => 'Played', 1099 | * 'status' => 'normal' 1100 | * ); 1101 | * $ret_id = uc_mygame_add($arr_game_info); 1102 | * echo ($ret_id > 0) ? "添加成功" : "添加失败"; 1103 | * 1104 | * 1105 | * @param array $arr_game_info - 记录游戏信息的联合数组 1106 | * @return integer - >1 添加成功,返回新增记录项id 1107 | * -1 用户名有误 1108 | * -2 游戏名有误 1109 | * 0 添加失败 1110 | */ 1111 | function uc_mygame_add($arr_game_info) { 1112 | $res = call_user_func(UC_API_FUNC, 'mygame', 'add', $arr_game_info); 1113 | return intval($res); 1114 | } 1115 | 1116 | /** 1117 | * integer uc_mygame_update(array $arr_game_info) 1118 | * 1119 | * 添加相关用户的游戏信息。(必须字段$arr_game_info['id']) 1120 | * 用法: 1121 | * 1122 | * $arr_game_info = array( 1123 | * 'id' => 51, 1124 | * 'gameid' => '2', 1125 | * 'gamename' => 'world of warcraft', 1126 | * 'server' => 'dianxin1', 1127 | * 'nickname' => 'daemon', 1128 | * 'class' => 'westen', 1129 | * 'level' => '70', 1130 | * 'link' => 'http://www.wowchina.com', 1131 | * 'type' => 'Played', 1132 | * 'status' => 'normal' 1133 | * ); 1134 | * $ret_id = uc_mygame_update($arr_game_info); 1135 | * echo ($ret_id > 0) ? "更新成功" : "更新失败"; 1136 | * 1137 | * 1138 | * @param array $arr_game_info - 需要更新的游戏信息的联合数组 1139 | * @return integer - 大于0 更新成功的记录条数 1140 | * -1 用户名有误 1141 | * -2 游戏名有误 1142 | * 0 添加失败 1143 | */ 1144 | function uc_mygame_update($arr_game_info) { 1145 | $res = call_user_func(UC_API_FUNC, 'mygame', 'update', $arr_game_info); 1146 | return intval($res); 1147 | } 1148 | 1149 | /** 1150 | * integer uc_mygame_delete(string $mygameids) 1151 | * 1152 | * 删除相关的游戏信息。 1153 | * 用法: 1154 | * 1155 | * $mygameids = "5,11,12"; 1156 | * $res_delete = uc_mygame_delete($mygameids); 1157 | * echo ($res_delete == 1) ? "删除成功" : "删除失败"; 1158 | * 1159 | * 1160 | * @param string $mygameids - 需要删除的游戏记录项id串 1161 | * @return integer - 1 删除成功 1162 | * 0 删除失败 1163 | */ 1164 | function uc_mygame_delete($mygameids) { 1165 | $res = call_user_func(UC_API_FUNC, 'mygame', 'delete', array('mygameids'=>$mygameids)); 1166 | return intval($res); 1167 | } 1168 | 1169 | /** 1170 | * integer uc_mygame_totalnum(array $arr) 1171 | * 1172 | * 获取指定用户的游戏数目 1173 | * - 注:$arr参数为查询条件数组 1174 | * 'key'=>'value'将被解释为对应的sql语句为: where `key1` = 'value1' and `key2` = 'value2'... 1175 | * 1176 | * @param array $arr - 需要查找的where子句条件数组: 如获取'lean'的所有游戏,则$arr = array('user'=>simple_md5('lean')) 1177 | * @return integer - 获取到的记录条数 1178 | */ 1179 | function uc_mygame_totalnum($arr = null) { 1180 | $where_conditions = ' 1=1 '; 1181 | if (is_array($arr) && !empty($arr)) { 1182 | foreach ($arr as $key => $value) { 1183 | $where_conditions .= " and `$key`='$value'"; 1184 | } 1185 | } 1186 | $res = call_user_func(UC_API_FUNC, 'mygame', 'totalnum', array('where_conditions'=>$where_conditions)); 1187 | return intval($res); 1188 | } 1189 | 1190 | 1191 | /** 1192 | * uc_mygame_ls 1193 | * 1194 | * 获取指定查询条件,指定起始条数与需要条数的游戏信息。 1195 | * - 注: 1196 | * $arr参数为查询条件数组 1197 | * 'key'=>'value'将被解释为对应的sql语句为: where `key1` = 'value1' and `key2` = 'value2'... 1198 | * 1199 | * 1200 | * 1201 | * @param integer $page - 列表显示的当前页码 1202 | * @param integer $pagesize - 列表当前页需要显示的记录条数 1203 | * @param integer $totalnum - 所有记录条数 1204 | * @param array $arr - 需要查找的where子句条件数组: 如获取'lean'的所有游戏,则$arr = array('user'=>simple_md5('lean')) 1205 | * 1206 | * @return array - 查询到的游戏信息 1207 | */ 1208 | function uc_mygame_ls($page = 1, $pagesize = 10, $totalnum = 10, $arr = null) { 1209 | $where_conditions = ' 1=1 '; 1210 | if (is_array($arr) && !empty($arr)) { 1211 | foreach ($arr as $key => $value) { 1212 | $where_conditions .= " and `$key`='$value'"; 1213 | } 1214 | } 1215 | $return = call_user_func(UC_API_FUNC, 'mygame', 'ls', array('page'=>$page, 'pagesize'=>$pagesize, 'totalnum'=>$totalnum, 'where_conditions'=>$where_conditions)); 1216 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 1217 | } 1218 | 1219 | 1220 | /** 1221 | * uc_mygame_super_ls 1222 | * 1223 | * @param string $select_fields - sql语句select部分的内容 1224 | * @param string $where_conditions - sql语句where部分的内容 1225 | * @param string $group_by - sql语句group by部分的内容 1226 | * @param string $order_by - sql语句order by部分的内容 1227 | * @param string $limit - sql语句limit部分的内容 1228 | * @return array 1229 | * 1230 | * 1231 | // 取得指定游戏(gameid为651)的服务器列表 1232 | $res = uc_mygame_super_ls('id, user, gamename, server', "`gameid`='651'", 'gamename', 'gamename desc', '0,5'); 1233 | var_dump($res); 1234 | * 1235 | */ 1236 | function uc_mygame_super_ls($select_fields='*', $where_conditions='1', $group_by='', $order_by='id', $limit='0,10') { 1237 | $return = call_user_func(UC_API_FUNC, 'mygame', 'super_ls', 1238 | array('select_fields'=>$select_fields, 'where_conditions'=>$where_conditions, 1239 | 'group_by'=>$group_by, 'order_by'=>$order_by, 'limit'=>$limit)); 1240 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 1241 | } 1242 | 1243 | 1244 | //friend_list 1245 | /** 1246 | * integer uc_friendlist_add(array $arr_friends_info) 1247 | * 1248 | * 添加相关用户的好友信息。 1249 | * 注:加用户为黑名单,用该函数处理即可。 1250 | * 1251 | * 用法: 1252 | * 1253 | * $arr_friend_info = array( 1254 | * 'user' => 'a916e4bec77b81a51c6ebaa052520306', //经过hash处理过的用户名 1255 | * 'fuser' => 'ee40b7c379f37620d59ac0853ab80e35', //经过hash处理过的好友名 1256 | * 'fname' => 'friend1', 1257 | * 'fdomain_name' => 'friend1', 1258 | * 'state' => 'accept', 1259 | * 'intro' => 'lalaal' 1260 | * ); 1261 | * $ret_id = uc_friendlist_add($arr_friend_info); 1262 | * echo ($ret_id > 0) ? "添加成功" : "添加失败"; 1263 | * 1264 | * 1265 | * @param array $arr_friends_info - 需要添加的好友信息的联合数组 1266 | * @return integer - >1 添加成功,返回新增记录项id 1267 | * -1 用户名有误 1268 | * -2 好友用户名(fuser)有误 1269 | * -3 user用户已经加fuser为好友了 1270 | * 0 添加失败 1271 | */ 1272 | function uc_friendlist_add($arr_friend_info) { 1273 | $res = call_user_func(UC_API_FUNC, 'friendlist', 'add', $arr_friend_info); 1274 | return intval($res); 1275 | } 1276 | 1277 | /** 1278 | * integer uc_friendlist_update(array $arr_friends_info) 1279 | * 1280 | * 添加相关用户的好友信息。(必须字段uc_friendlist_update['fid']) 1281 | * 1282 | * 用法: 1283 | * 1284 | * $arr_friend_info = array( 1285 | * 'fid' => '51,52', //好友记录id串,如一次修改多条记录,请将多个fid用逗号分隔做为此参数 1286 | * 'state' => 'accept', 1287 | * ); 1288 | * $ret_id = uc_friendlist_update($arr_friend_info); 1289 | * echo ($ret_id == 1) ? "更新成功" : "更新失败"; 1290 | * 1291 | * 1292 | * @param array $arr_game_info - 需要更新的游戏信息的联合数组 1293 | * @return integer - (如果$arr_friend_info[fid]串中只有一个id, 则返回操作是否失败:1表示成功,0表示失败) 1294 | * 如过一次更新多条数据,则retrun含义如下: 1295 | * 大于0 更新成功的记录条数 1296 | * -1 用户名有误 1297 | * -2 好友用户名(fuser)有误 1298 | * 0 更新失败 1299 | */ 1300 | function uc_friendlist_update($arr_friend_info) { 1301 | $res = call_user_func(UC_API_FUNC, 'friendlist', 'update', $arr_friend_info); 1302 | return intval($res); 1303 | } 1304 | 1305 | /** 1306 | * integer uc_friendlist_delete(string $fids) 1307 | * 1308 | * 删除相关的好友信息。 1309 | * 1310 | * 用法: 1311 | * 1312 | * $fids = "5,11,12"; 1313 | * $res_delete = uc_friendlist_delete($fids); 1314 | * echo ($res_delete == 1) ? "删除成功" : "删除失败"; 1315 | * 1316 | * 1317 | * @param string $fids - 需要删除的好友记录项id串 1318 | * @return integer - 1 删除成功 1319 | * 0 删除失败 1320 | */ 1321 | function uc_friendlist_delete($fids) { 1322 | $res = call_user_func(UC_API_FUNC, 'friendlist', 'delete', array('fids'=>$fids)); 1323 | return intval($res); 1324 | } 1325 | 1326 | /** 1327 | * uc_friendlist_totalnum 1328 | * 1329 | * 根据指定查询条件获取好友数量。 1330 | * - 注:$arr参数为查询条件数组 1331 | * 'key'=>'value'将被解释为对应的sql语句为: where `key1` = 'value1' and `key2` = 'value2'... 1332 | * 1333 | * 用法: 1334 | * 1335 | * $arr = array( 1336 | * 'state' => 'black', 1337 | * 'user' => simple_md5('lean') 1338 | * ); 1339 | * $num_friends = uc_friendlist_totalnum($arr); 1340 | * 1341 | * 1342 | * @param array $arr - 查询条件数组(以'查询字段'=>'查询的值'的索引形式表示) 1343 | * @return integer 1344 | */ 1345 | function uc_friendlist_totalnum($arr = null) { 1346 | $where_conditions = ' 1=1 '; 1347 | if (is_array($arr) && !empty($arr)) { 1348 | foreach ($arr as $key => $value) { 1349 | $where_conditions .= " and `$key`='$value'"; 1350 | } 1351 | } 1352 | $res = call_user_func(UC_API_FUNC, 'friendlist', 'totalnum', array('where_conditions'=>$where_conditions)); 1353 | return intval($res); 1354 | } 1355 | 1356 | /** 1357 | * uc_friendlist_ls 1358 | * 1359 | * 获取指定查询条件的好友信息。 1360 | * - 注:$arr参数为查询条件数组 1361 | * 'key'=>'value'将被解释为对应的sql语句为: where `key1` = 'value1' and `key2` = 'value2'... 1362 | * 1363 | * @param integer $page - 列表显示的当前页码 1364 | * @param integer $pagesize - 列表当前页需要显示的记录条数 1365 | * @param integer $totalnum - 所有记录条数 1366 | * @param array $arr - 需要查找的where子句条件数组: 如获取'lean'的好友,则$arr = array('user'=>simple_md5('lean'), 'state'=>'friend') 1367 | * 1368 | * @return array 1369 | */ 1370 | function uc_friendlist_ls($page = 1, $pagesize = 10, $totalnum = 10, $arr = null) { 1371 | $where_conditions = ' 1=1 '; 1372 | if (is_array($arr) && !empty($arr)) { 1373 | foreach ($arr as $key => $value) { 1374 | $where_conditions .= " and `$key`='$value'"; 1375 | } 1376 | } 1377 | $return = call_user_func(UC_API_FUNC, 'friendlist', 'ls', array('page'=>$page, 'pagesize'=>$pagesize, 'totalnum'=>$totalnum, 'where_conditions'=>$where_conditions)); 1378 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 1379 | } 1380 | 1381 | /** 1382 | * uc_friendlist_totalnum_direction 1383 | * 1384 | * 获取给定用户的好友数 1385 | * 1386 | * @param string $user - 用户名 1387 | * @param integer $direction - 被查询方向 1388 | * 0:反向,即查找添加该用户为好友的人 1389 | * 1:正向,即查找该用户已经添加的好友 1390 | * 2:双向,即查找被该用户添加的人,且这个人也添加了该用户为好友 1391 | * 1392 | * @return integer - 查询到的好友数 1393 | */ 1394 | function uc_friendlist_totalnum_direction($user, $direction=2) { 1395 | $user = simple_md5($user); 1396 | $res = call_user_func(UC_API_FUNC, 'friendlist', 'totalnum_with_direction', array('user'=>trim($user))); 1397 | return intval($res); 1398 | } 1399 | 1400 | /** 1401 | * uc_friendlist_ls_direction 1402 | * 1403 | * 获取给定用户的好友列表 1404 | * 1405 | * @param string $user 1406 | * @param integer $page 1407 | * @param integer $pagesize 1408 | * @param integer $totalnum 1409 | * @param integer $direction 1410 | * @return unknown 1411 | */ 1412 | function uc_friendlist_ls_direction($user, $page = 1, $pagesize = 10, $totalnum = 10, $direction=2) { 1413 | $user = simple_md5($user); 1414 | $return = call_user_func(UC_API_FUNC, 'friendlist', 'ls_width_direction', array('page'=>$page, 'pagesize'=>$pagesize, 'totalnum'=>$totalnum, 'user'=>trim($user))); 1415 | return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); 1416 | } 1417 | 1418 | if (!function_exists('simple_md5')) { 1419 | function simple_md5($str){ 1420 | $str = strtolower(trim($str)); 1421 | return md5($str.'f#i=4a-8&rZz=0T'.substr($str,0,1).strlen($str)); 1422 | } 1423 | } 1424 | 1425 | function generate_pass($password) { 1426 | return md5(md5(strtolower(trim($password))) . PASSKEY_SALT); 1427 | } 1428 | 1429 | /** 1430 | * 1431 | * 此函数针对generate_pass修正 1432 | * 差别在generate_pass传入的是明文密码串,此函数传入md5(strtolower($password))的hash串 1433 | */ 1434 | function generate_hash_pass($hash) { 1435 | return md5($hash . PASSKEY_SALT); 1436 | } 1437 | ?> -------------------------------------------------------------------------------- /应用程序站/client/lib/FileCache.class.php: -------------------------------------------------------------------------------- 1 | "; 119 | $dir = dirname($full_file_path); 120 | if(!is_dir($dir)) { 121 | self::_mkdirs($dir, 0777); 122 | } 123 | // $fname = self::$_cacheDir . 'cache_' . $name . '.php'; 124 | self::_writeover($full_file_path, $fcontent); 125 | } 126 | 127 | 128 | 129 | /** 130 | * 建立多级目录 131 | */ 132 | static private function _mkdirs($dir,$mode=0664){ 133 | if(!is_dir($dir)){ 134 | self::_mkdirs(dirname($dir), $mode); 135 | @mkdir($dir,$mode); 136 | } 137 | return ; 138 | } 139 | 140 | static private function _writeover($filename, $data, $method="rb+", $iflock=1, $chmod=1) { 141 | touch($filename); 142 | $handle = fopen($filename, $method); 143 | $iflock && flock($handle, LOCK_EX); 144 | fwrite($handle, $data); 145 | if($method == "rb+") ftruncate($handle, strlen($data)); 146 | fclose($handle); 147 | $chmod && @chmod($filename, 0777); 148 | } 149 | } 150 | 151 | 152 | //now it just assistes 5 mode strategy 153 | //note that: delay method should be added into this class. 154 | class ExpireStrategy 155 | { 156 | 157 | static public function judge($file_path, $mode, $time_param) { 158 | switch (intval($mode)) { 159 | case EXPIRE_MODE_INTEVAL: 160 | return self::_intevalExpire($file_path, $time_param); 161 | break; 162 | case EXPIRE_MODE_YEAR: 163 | return self::_yearExpire($file_path, $time_param); 164 | break; 165 | case EXPIRE_MODE_MONTH: 166 | return self::_monthExpire($file_path, $time_param); 167 | break; 168 | case EXPIRE_MODE_WEEK: 169 | return self::_weekExpire($file_path, $time_param); 170 | break; 171 | case EXPIRE_MODE_DAY: 172 | return self::_dayExpire($file_path, $time_param); 173 | break; 174 | case EXPIRE_MODE_HOUR: 175 | return self::_hourExpire($file_path, $time_param); 176 | break; 177 | case EXPIRE_MODE_MINUTE: 178 | return self::_minuteExpire($file_path, $time_param); 179 | break; 180 | default: 181 | return self::_intevalExpire($file_path, $time_param); 182 | break; 183 | } 184 | } 185 | 186 | 187 | static private function _yearExpire($full_file_path, $timestamp) { 188 | if (!file_exists($full_file_path)) { 189 | return true; 190 | } 191 | //计算年最后一秒时间 192 | $last_timestamp = mktime(23, 59, 59, 12, 31, date('Y', $timestamp)); 193 | if (filemtime($full_file_path) <= $week_last_timestamp) { 194 | return true; 195 | } else { 196 | return false; 197 | } 198 | } 199 | 200 | //$timestamp 为一月中任一时间点(即为被分析月数据的任一时间) 201 | static private function _monthExpire($full_file_path, $timestamp) { 202 | if (!file_exists($full_file_path)) { 203 | return true; 204 | } 205 | //计算这个月最后一秒时间 206 | $last_timestamp = mktime(23, 59, 59, 207 | date('m', $timestamp), date('t', $timestamp), date('Y', $timestamp)); 208 | if (filemtime($full_file_path) <= $week_last_timestamp) { 209 | return true; 210 | } else { 211 | return false; 212 | } 213 | } 214 | 215 | //$timestamp 为一周中任一时间点(即为被分析周数据的任一时间) 216 | static private function _weekExpire($full_file_path, $timestamp) { 217 | if (!file_exists($full_file_path)) { 218 | return true; 219 | } 220 | //计算这个周最后一秒时间 221 | $first = 0; //一周以星期一还是星期天开始,0为星期天,1为星期一 222 | $w = date("w", $timestamp);//取得一周的第几天,星期天开始0-6 223 | $dn = $w ? 6 - ($w - $first) : 0;//要加上的天数 224 | $gdate = date("Y-m-d", $timestamp); 225 | $week_last_timestamp = strtotime("$gdate +".$dn." days") + 86399; 226 | if (filemtime($full_file_path) <= $week_last_timestamp) { 227 | return true; 228 | } else { 229 | return false; 230 | } 231 | } 232 | 233 | static private function _dayExpire($full_file_path, $timestamp) { 234 | if (!file_exists($full_file_path)) { 235 | return true; 236 | } 237 | $last_timestamp = mktime(23, 59, 59, 238 | date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); 239 | if (filemtime($full_file_path) <= $last_timestamp) { 240 | return true; 241 | } else { 242 | return false; 243 | } 244 | } 245 | 246 | static private function _hourExpire($full_file_path, $timestamp) { 247 | if (!file_exists($full_file_path)) { 248 | return true; 249 | } 250 | $last_timestamp = mktime(date('H', $timestamp), 59, 59, 251 | date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); 252 | if (filemtime($full_file_path) <= $last_timestamp) { 253 | return true; 254 | } else { 255 | return false; 256 | } 257 | } 258 | 259 | static private function _minuteExpire($full_file_path, $timestamp) { 260 | if (!file_exists($full_file_path)) { 261 | return true; 262 | } 263 | $last_timestamp = mktime(date('H', $timestamp),date('i', $timestamp), 59, 264 | date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); 265 | if (filemtime($full_file_path) <= $last_timestamp) { 266 | return true; 267 | } else { 268 | return false; 269 | } 270 | } 271 | 272 | static private function _intevalExpire($full_file_path, $expire_inteval) { 273 | if (!file_exists($full_file_path)) { 274 | return true; 275 | } 276 | $cache_mtime = filemtime($full_file_path); 277 | if ($cache_mtime + $expire_inteval < time()) { 278 | return true; 279 | } else { 280 | return false; 281 | } 282 | } 283 | 284 | } 285 | 286 | 287 | /** 288 | * CacheFilePath 289 | * 290 | * 缓存路径策略处理类(策略较简单,所以只用静态类实现) 291 | * (后面再补充2008.10.27, 目前只把简单路径的返回放到get方法中,后面请以该类为抽象工厂生产策略对象,get接口保留) 292 | * 293 | */ 294 | class RelativeCachePath 295 | { 296 | static public function get($flag, $filename) { 297 | $len = strlen(CACHE_FILENAME_SUFFIX); 298 | if (substr($filename, -$len) != CACHE_FILENAME_SUFFIX) { 299 | $filename = $filename . CACHE_FILENAME_SUFFIX; 300 | } 301 | switch ($flag) { 302 | case DIR_MODE_PLAIN: 303 | return $filename; 304 | break; 305 | case DIR_MODE_HASH: 306 | $hased_filename = md5($filename); 307 | return substr($hased_filename, 0, 2) . DIRECTORY_SEPARATOR 308 | . substr($hased_filename, 2, 2) . DIRECTORY_SEPARATOR 309 | . substr($hased_filename, 4, 2) . DIRECTORY_SEPARATOR 310 | . basename($filename); 311 | break; 312 | case DIR_MODE_MIX: 313 | $has_filename_with_dir = false; 314 | if ( (strstr($filename, '/') != false) || (strstr($filename, "\\") != false)) { 315 | $has_filename_with_dir = true; 316 | } 317 | $hased_filename = md5($filename); 318 | return substr($hased_filename, 0, 2) . DIRECTORY_SEPARATOR 319 | . substr($hased_filename, 2, 2) . DIRECTORY_SEPARATOR 320 | . substr($hased_filename, 4, 2) . DIRECTORY_SEPARATOR 321 | . $filename; 322 | break; 323 | default: 324 | return $filename; 325 | break; 326 | } 327 | } 328 | } 329 | 330 | 331 | //设置默认的缓存文件目录 332 | FileCache::setCacheDir(dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR); 333 | //设置默认的缓存路径策略 334 | FileCache::setAdditionalDirMode(DIR_MODE_PLAIN); 335 | //FileCache::setExpireMode(EXPIRE_MODE_DAY, strtotime('2008-11-01')); 336 | 337 | ?> -------------------------------------------------------------------------------- /应用程序站/client/lib/db.class.php: -------------------------------------------------------------------------------- 1 | time = $time; 20 | $this->tablepre = $tablepre; 21 | if($pconnect) { 22 | if(!$this->link = mysql_pconnect($dbhost, $dbuser, $dbpw)) { 23 | $this->halt('Can not connect to MySQL server'); 24 | } 25 | } else { 26 | if(!$this->link = mysql_connect($dbhost, $dbuser, $dbpw, 1)) { 27 | $this->halt('Can not connect to MySQL server'); 28 | } 29 | } 30 | 31 | if($this->version() > '4.1') { 32 | 33 | if($dbcharset) { 34 | mysql_query("SET character_set_connection=".$dbcharset.", character_set_results=".$dbcharset.", character_set_client=binary", $this->link); 35 | } 36 | 37 | if($this->version() > '5.0.1') { 38 | mysql_query("SET sql_mode=''", $this->link); 39 | } 40 | } 41 | 42 | if($dbname) { 43 | mysql_select_db($dbname, $this->link); 44 | } 45 | 46 | } 47 | 48 | function fetch_array($query, $result_type = MYSQL_ASSOC) { 49 | return mysql_fetch_array($query, $result_type); 50 | } 51 | 52 | function result_first($sql) { 53 | $query = $this->query($sql); 54 | return $this->result($query, 0); 55 | } 56 | 57 | function fetch_first($sql) { 58 | $query = $this->query($sql); 59 | return $this->fetch_array($query); 60 | } 61 | 62 | function fetch_all($sql) { 63 | $arr = array(); 64 | $query = $this->query($sql); 65 | while($data = $this->fetch_array($query)) { 66 | $arr[] = $data; 67 | } 68 | return $arr; 69 | } 70 | 71 | function cache_gc() { 72 | $this->query("DELETE FROM {$this->tablepre}sqlcaches WHERE expiry<$this->time"); 73 | } 74 | 75 | function query($sql, $type = '', $cachetime = FALSE) { 76 | $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 'mysql_unbuffered_query' : 'mysql_query'; 77 | if(!($query = $func($sql, $this->link)) && $type != 'SILENT') { 78 | $this->halt('MySQL Query Error', $sql); 79 | } 80 | $this->querynum++; 81 | $this->histories[] = $sql; 82 | return $query; 83 | } 84 | 85 | function affected_rows() { 86 | return mysql_affected_rows($this->link); 87 | } 88 | 89 | function error() { 90 | return (($this->link) ? mysql_error($this->link) : mysql_error()); 91 | } 92 | 93 | function errno() { 94 | return intval(($this->link) ? mysql_errno($this->link) : mysql_errno()); 95 | } 96 | 97 | function result($query, $row) { 98 | $query = @mysql_result($query, $row); 99 | return $query; 100 | } 101 | 102 | function num_rows($query) { 103 | $query = mysql_num_rows($query); 104 | return $query; 105 | } 106 | 107 | function num_fields($query) { 108 | return mysql_num_fields($query); 109 | } 110 | 111 | function free_result($query) { 112 | return mysql_free_result($query); 113 | } 114 | 115 | function insert_id() { 116 | return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0); 117 | } 118 | 119 | function fetch_row($query) { 120 | $query = mysql_fetch_row($query); 121 | return $query; 122 | } 123 | 124 | function fetch_fields($query) { 125 | return mysql_fetch_field($query); 126 | } 127 | 128 | function version() { 129 | return mysql_get_server_info($this->link); 130 | } 131 | 132 | function close() { 133 | return mysql_close($this->link); 134 | } 135 | 136 | function halt($message = '', $sql = '') { 137 | exit($message.'

'.$sql.'
'.mysql_error()); 138 | } 139 | } 140 | 141 | ?> -------------------------------------------------------------------------------- /应用程序站/client/lib/index.htm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /应用程序站/client/lib/uccode.class.php: -------------------------------------------------------------------------------- 1 | uccode = array( 15 | 'pcodecount' => -1, 16 | 'codecount' => 0, 17 | 'codehtml' => '' 18 | ); 19 | } 20 | 21 | function codedisp($code) { 22 | $this->uccode['pcodecount']++; 23 | $code = str_replace('\\"', '"', preg_replace("/^[\n\r]*(.+?)[\n\r]*$/is", "\\1", $code)); 24 | $this->uccode['codehtml'][$this->uccode['pcodecount']] = $this->tpl_codedisp($code); 25 | $this->uccode['codecount']++; 26 | return "[\tUCENTER_CODE_".$this->uccode[pcodecount]."\t]"; 27 | } 28 | 29 | function complie($message) { 30 | $message = htmlspecialchars($message); 31 | if(strpos($message, '[/code]') !== FALSE) { 32 | $message = preg_replace("/\s*\[code\](.+?)\[\/code\]\s*/ies", "\$this->codedisp('\\1')", $message); 33 | } 34 | if(strpos($message, '[/url]') !== FALSE) { 35 | $message = preg_replace("/\[url(=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)([^\[\"']+?))?\](.+?)\[\/url\]/ies", "\$this->parseurl('\\1', '\\5')", $message); 36 | } 37 | if(strpos($message, '[/email]') !== FALSE) { 38 | $message = preg_replace("/\[email(=([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+))?\](.+?)\[\/email\]/ies", "\$this->parseemail('\\1', '\\4')", $message); 39 | } 40 | $message = str_replace(array( 41 | '[/color]', '[/size]', '[/font]', '[/align]', '[b]', '[/b]', 42 | '[i]', '[/i]', '[u]', '[/u]', '[list]', '[list=1]', '[list=a]', 43 | '[list=A]', '[*]', '[/list]', '[indent]', '[/indent]', '[/float]' 44 | ), array( 45 | '', '', '', '

', '', '', '', 46 | '', '', '', '