in 技术与思考

Yii初步整合UCenter

下午偷空做了Yii和UCenter的整合。我不得不说,UCenter的开发者太不负责了!

前置工作:安装好ucenter和yii。下载ucenter的php开发包

然后我就按他们的操作进行了。

复制一份接口开发手册里面的 client/ 目录到你程序的根目录下。
然后复制一份开发手册里面样例程序 examples/ 目录中的 api/ 子目录到你程序的根目录下。
如果您的应用程序的根目录有 config.inc.php 文件,在此文件里定义以 UC_ 开头的常量,具体常量内容可以参考手册中“了解 UCenter”章节。
此时,你需要在 UCenter 的“应用管理”->“+添加新应用”选择“自定义安装”,“接口 URL”填写你程序的 URL 地址,通信密钥可随意填写,如“12345”,“应用类型”选择“其他”,然后创建新应用,记录下新应用的 ID 。然后在 config.inc.php 中的 UC_APPID 常量填写新应用的 ID,UC_KEY 填写刚才填写的通信密钥“12345”。这时回到应用管理,如果此时提示此应用“通信成功”,说明您的准备工作已完成。如果你的程序的配置文件不是 config.inc.php 其自行修改代码 api/uc.php 中的内容。

按ucenter的说明开始操作,首先在ucenter中添加应用。
然后把开发包中根目录下的client复制到yii的web根目录中。然后把开发包example下的api目录复制到yii根目录中。
因为我没有config.inc.php,所以我在yii的web根目录下创建了config.inc.php,并把从ucenter添加完应用之后,在页面底部提示的代码段复制到config.inc.php中。
按理这时候配置工作就完毕了。但回到ucenter中查看时候,发现通信失败。这应该是一个绝大多数应用开发者碰到的第一个问题。

在找了discuz论坛发现无果之后。开始了我的检查之路。用firebug检查“通信失败”的产生者,最后发现是ucenter中的/control/admin/app.php中的onping()方法引起。
而onping则会调用yii根目录下的/api/uc.php,如果此时uc.php输出是1,就是通信正常了。但此时uc.php这个页面输出空白,所以可能问题是在uc.php。

uc.php中的常量定义第一个就雷到我了。

define(‘IN_DISCUZ’, TRUE);

我没有在discuz的什么目录下,为什么还要设它为true呢?查了一下uc.php,也没有什么地方用到它。多余的常量。
然后在第30行左右有一个:

if(!defined(‘IN_UC’)) {

这个也很脑残,对第三方应用来说,不会有碰到这个IN_UC常量,所以这里和if(true)是一回事。也不知道IN_UC是做什么用的。现在就看这个if里的逻辑就好了。
在第55行左右

require_once DISCUZ_ROOT.’./uc_client/lib/xml.class.php';

和第59行左右

require_once DISCUZ_ROOT.’./include/db_mysql.class.php';

这是哪个傻子写的代码,DISCUZ指向了uc.php的上级目录,也就是yii的根目录。对uc.php来说,它能保证这下面一定会有/uc_client/lib/xml.class.php和/include/db_mysql.class.php吗?

这里uc_client是指最开始的时候从ucenter开发包复制到yii目录下的client目录,而/include/db_mysql.class.php则是discuz下的相应文件。

而且这里一定要连接数据库。从uc.php的60到62行:

$GLOBALS[‘db’] = new dbstuff;
$GLOBALS[‘db’]->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset);
$GLOBALS[‘tablepre’] = $tablepre;

这些$dbhost, $dbuser什么的去哪里取啊?根据他们现有的文档,根本不能正常执行。

解决方法

  1. 将uc.php中的/uc_client修改为相应的/client目录
  2. 从discuz安装文件中提取db_mysql.class.php,放到/client下的任意地方(比如/client/lib/db_mysql.class.php),然后将/include/db_mysql.class.php路径改为对应的位置
  3. 从开发包的example目录下的config.inc.php的尾部复制配置到yii的config.inc.php中去。当然要做一些修改。
    $dbhost = ‘localhost';            // 数据库服务器
    $dbuser = ‘root';            // 数据库用户名
    $dbpw = ”;                // 数据库密码
    $dbname = ‘ucenter';            // 这里应该是yii的数据库名
    $pconnect = 0;                // 数据库持久连接 0=关闭, 1=打开
    $tablepre = ‘example_';           // 表名前缀, 同一数据库安装多个论坛请修改此处
    $dbcharset = ‘gbk';            // MySQL 字符集, 可选 ‘gbk’, ‘big5′, ‘utf8′, ‘latin1′, 留空为按照论坛字符集设定

修改完之后,再看ucenter中的通信状态,正常了。

写一个ucenter.php放到Yii的protected/vendors下:

$path = dirname(__FILE__).’/../../client/';
require_once($path.’../config.inc.php’);
require_once($path.’client.php’);

然后在controller中测试获取app列表,正常。说明整合初步成功。

结论:UCenter的文档和示例程序没有考虑到第三方应用开发者的开发过程,导致出现这些不该有的麻烦。在uc.php中连接数据库,估计是为了同步一些用户的信息来用的。具体的还要再挖掘一下。像同步用户登录之类的,应该还需要uc.php中的相关cookie配置段。

您还可能喜欢:

Write a Comment

Comment

  1. 同意了.我研究了半天同步登录.同步退出的问题.
    现在问题是这样的.比如UCENTER整合了UCHOME和我做的DAOHANG.

    从DAOHANG登录时.DAOHANG推出时.UCHOME正常

    但从UCHOME登录,再到DAOHANG退出时.DAOHANG无法清除同步登录生成的COOKIE…

  2. 嗯,同步登录和退出的还没玩到。估计是用js去触发各个站的的uc.php吧。

  3. 你好,我也遇到这样的问题。不过按照你的方法。我没有解决。能进一步与你了解下这方面的问题吗?
    我的QQ是1047984536