整合symfony项目到康盛ucenter系列产品中
September 9, 2009 – 6:28 pm最近开发一个使用symfony框架的产品,并且需要把这个项目作为一个应用添加到ucenter系列产品中,以前做过的都是康盛家族产品的整合和二次开发,还没有试验过把php框架开发的项目整合到ucenter中,整合的过程就记录在这里了。
(以下实验基于symfony1.2.7,ucenter1.0,uchome1.5版本)
康盛官方提供了一个ucenter开发包,里面包含一份电子版手册,一个uc客户端软件包,还有一个实例程序包。实际上我们现在要整合symfony项目到ucenter中,就是把实例程序改写成symfony框架程序格式,然后调用uc客户端软件包即可实现。那么首先,我们分析一下ucenter的通讯机制。
登录ucenter管理界面,只要你点击了“应用管理”选项卡,ucenter就会分别发出对应的请求给应用项目来测试通讯是否通畅。例如,我们安装了ucenter和uchome两个产品,那么ucenter就发出一个请求给uchome,uchome项目里的通讯客户端程序接受请求并返回一个常量API_RETURN_SUCCEED,如此即为我们看到的“通讯成功”。具体可以通过抓包分析并阅读ucenter的源代码查看细节。
以登录同步为例,假如我们安装了ucenter、uchome和discuz三个产品,现在我们访问uchome并登录,同步登录机制会同时让discuz的用户会话写入,即我们看到的同步登录实现。访问实例程序并抓包试验一下,原来客户端软件包在登录时通过与ucenter通讯获取了js代码,来发送登录请求给其他项目,即uchome登录时,uchome自己写入了会话,同时通js发送请求给discuz的通讯客户端程序,discuz的通讯客户端程序在验证是同步登录请求后,把会话写入了当前浏览器,由此实现了同步登录。
明白了这些基本原理,我们后面的工作就是把这套实现机制引入symfony程序了。
开发流程:
1.定义symfony路由规则
在routing.yml里加入如下代码:
url: /api/uc.php
param: { module: sync, action: ping }
url: /login
param: { module: sync, action: login }
2.构建module和action
创建sync模块和两个动作ping和login
3.加入uc客户端软件包,加入相应类文件
把client通讯包拷贝到项目lib目录下,把以下配置代码加到client.php中:
- // 与 UCenter 的通信密钥, 要与 UCenter 保持一致
- define('UC_KEY', sfConfig::get('app_ucenter_key'));
- // UCenter 的 IP
- define('UC_IP', '');
- //同步登录 Cookie 设置
- define('UC_CHARSET', 'utf8');// UCenter 的字符集
- $cookiedomain = '';// cookie 作用域
- $cookiepath = '/';// cookie 作用路径
- //center的url地址
- define('UC_API',sfConfig::get('app_center_url'));
把实例程序包api/uc.php中的方法authcode()封装成一个类放到apps/frontend/lib下,注意通讯密钥要被authcode()访问到
4.开发动作代码
首先写通讯代码,pingAction.class.php代码如下:
- <?php
- class pingAction extends sfAction
- {
- public function execute($request)
- {
- $code = $request->getParameter('code');
- $uc = new ucenter();
- parse_str($uc->authcode($code, 'DECODE'), $get);
- if(time() - $get['time'] > 3600)
- {
- exit('Authracation has expiried');
- }
- if(empty($get))
- {
- exit('Invalid Request');
- }
- $action = $get['action'];
- if ("test" == $action)
- {
- $this->test();
- }
- elseif ("synlogin" == $action)
- {
- $this->synlogin($get['uid']);
- }
- exit();
- }
- private function test()
- {
- return $this->renderText(sfConfig::get('app_ping_succeed'));
- }
- private function synlogin($uid)
- {
- return $this->getUser()->setAttribute('memberID',$uid);
- }
- }
清除symfony缓存后访问center,即可看到通讯成功,如图片:
继续写同步登录代码,loginAction.class.php代码如下:
- <?php
- class loginAction extends sfAction
- {
- public function execute($request)
- {
- if ($request->getMethod == "POST")
- {
- $loginName = $request->getParameter('loginName');
- $passwd = $request->getParameter('passwd');
- include_once(sfConfig::get('sf_lib_dir')."/client/client.php");
- list($uid, $username, $password, $email) = uc_user_login($loginName, $passwd);
- if ($uid > 0)
- {
- $this->getUser()->setAttribute('memberID',$uid);
- $ucsynloginCode = uc_user_synlogin($uid);
- echo '登录成功';
- echo $ucsynloginCode;
- echo '<a href="/login">继续</a>';
- }
- elseif ($uid == -1)
- {
- echo "登录用户名不存在";
- echo '<a href="/login">重新登录</a>';
- }
- elseif ($uid == -2)
- {
- echo "密码不正确";
- echo '<a href="/login">重新登录</a>';
- }
- else
- {
- echo "其他情况";
- }
- exit();
- }
- return sfView::SUCCESS;
- }
- }
模板loginSuccess.php代码如下:
<?php if ($sf_user->hasAttribute(’memberID’)): ?>
登录成功!
<?php else: ??>
<form method=”POST” action=”/login”>
<input type=”text” name=”loginName” />
<input type=”password” name=”passwd” />
<input type=”submit” value=”登录” />
</from>
<?php endif; ?>
测试一下,当symfony程序登录后,通过center同步登录机制,uchome也实现了同步登录,同理,你从。其他例如登出,注册,短消息操作均可以参考center开发手册进行。
分析一下康盛center同步登录机制,如果只有三五个项目在通过center实现同步登录,那么此技术结构应该是可以接受的,不过如果有十个以上的项目需要进行同步登录,这套技术结构就显得有点效率低,我们就需要想别的方法实现通行证方案了。
