├── 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 | 
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 桂桂
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 | '', '', '', '
', '', '' 48 | ), preg_replace(array( 49 | "/\[color=([#\w]+?)\]/i", 50 | "/\[size=(\d+?)\]/i", 51 | "/\[size=(\d+(\.\d+)?(px|pt|in|cm|mm|pc|em|ex|%)+?)\]/i", 52 | "/\[font=([^\[\<]+?)\]/i", 53 | "/\[align=(left|center|right)\]/i", 54 | "/\[float=(left|right)\]/i" 55 | ), array( 56 | "", 57 | "", 58 | "", 59 | "", 60 | "
",
61 | ""
62 | ), $message));
63 | if(strpos($message, '[/quote]') !== FALSE) {
64 | $message = preg_replace("/\s*\[quote\][\n\r]*(.+?)[\n\r]*\[\/quote\]\s*/is", $this->tpl_quote(), $message);
65 | }
66 | if(strpos($message, '[/img]') !== FALSE) {
67 | $message = preg_replace(array(
68 | "/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies",
69 | "/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies"
70 | ), array(
71 | "\$this->bbcodeurl('\\1', '')",
72 | "\$this->bbcodeurl('\\3', '
')"
73 | ), $message);
74 | }
75 | for($i = 0; $i <= $this->uccode['pcodecount']; $i++) {
76 | $message = str_replace("[\tUCENTER_CODE_$i\t]", $this->uccode['codehtml'][$i], $message);
77 | }
78 | return nl2br(str_replace(array("\t", ' ', ' '), array(' ', ' ', ' '), $message));
79 | }
80 |
81 | function parseurl($url, $text) {
82 | if(!$url && preg_match("/((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)[^\[\"']+/i", trim($text), $matches)) {
83 | $url = $matches[0];
84 | $length = 65;
85 | if(strlen($url) > $length) {
86 | $text = substr($url, 0, intval($length * 0.5)).' ... '.substr($url, - intval($length * 0.3));
87 | }
88 | return ''.$text.'';
89 | } else {
90 | $url = substr($url, 1);
91 | if(substr(strtolower($url), 0, 4) == 'www.') {
92 | $url = 'http://'.$url;
93 | }
94 | return ''.$text.'';
95 | }
96 | }
97 |
98 | function parseemail($email, $text) {
99 | if(!$email && preg_match("/\s*([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+)\s*/i", $text, $matches)) {
100 | $email = trim($matches[0]);
101 | return ''.$email.'';
102 | } else {
103 | return ''.$text.'';
104 | }
105 | }
106 |
107 | function bbcodeurl($url, $tags) {
108 | if(!preg_match("/<.+?>/s", $url)) {
109 | if(!in_array(strtolower(substr($url, 0, 6)), array('http:/', 'https:', 'ftp://', 'rtsp:/', 'mms://'))) {
110 | $url = 'http://'.$url;
111 | }
112 | return str_replace(array('submit', 'logging.php'), array('', ''), sprintf($tags, $url, addslashes($url)));
113 | } else {
114 | return ' '.$url;
115 | }
116 | }
117 |
118 | function tpl_codedisp($code) {
119 | return '
'.$code.'
\\1