环境:
discuz:
Discuz! 程序版本 | Discuz! X3 Release 20130801 |
UCenter 客户端版本 | UCenter 1.6.0 Release 20110501 |
服务器系统及 PHP | Linux / PHP v5.3.27 |
服务器软件 | nginx/1.1.16 |
服务器 MySQL 版本 | 5.5.34-log |
phpcms:
PHPCMS程序版本:Phpcms V9.5.7 Release 20140625
操作系统:Linux
服务器软件:nginx/1.1.16PHP/5.3.27
MySQL 版本:5.5.34-log
问题:
通过ucenter整合disucz和phpcms,在discuz上修改用户密码,无法通知到phpcms,在ucenter后台的数据列表中查看通知列表,发现通知失败,尝试点击Discuz! Board列下的通知失败链接,返回通知成功,而点击phpcms_v9下的通知失败链接,仍返回通知失败。
原因:
经过逐步调试,发现uc_server/model/note.php文件中的sendone函数下的$response 返回值为空,因此判断问题有可能出现在dfopen2函数上
$response = trim($_ENV['misc']->dfopen2($url, 0, $note['postdata'], '', 1, $app['ip'], UC_NOTE_TIMEOUT, TRUE));
解决办法:
修改uc_server/model/misc.php文件中的dfopen函数(dfopen2函数调用dfopen函数)
找到代码
@fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
把上面这段代码所属的if判断全部替换为下面这一段
if(function_exists('fsockopen')) {
$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
} elseif (function_exists('pfsockopen')) {
$fp = @pfsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
} elseif(function_exists('stream_socket_client')) {
//$fp = @stream_socket_client($ip.':'.$port, $errno, $errstr, $timeout);
$fp = @stream_socket_client("tcp://".$host.":80", $errno, $errstr, $timeout);
} else {
$fp = false;
}
为什么要注释掉
$fp = @stream_socket_client($ip.':'.$port, $errno, $errstr, $timeout);
而要改用
$fp = @stream_socket_client("tcp://".$host.":80", $errno, $errstr, $timeout);
就是因为在点击phpcms_v9下的通知失败链接时,此处无法获取到ip地址,因此改为使用主机名
fsockopen函数和pfsockopen函数因存在安全问题,已被服务器禁用,所以现在一般是用stream_socket_client函数进行代替(可以查看文章PHPCMS无法登录、注册)
另外:
如果在discuz修改密码时,发现通知的密码为空,则修改ucenter客户端(uc_client)的相应代码(uc_client\control\user.php文件下的onedit()函数)
$_ENV['note']->add('updatepw', 'username='.urlencode($username).'&password=');
修改为
$_ENV['note']->add('updatepw', 'username='.urlencode($username).'&password='.$newpw);
同步通知:
若要让phpcms同步更新密码,只需以下两步:
1、修改uc_server/model/base.php
1.1、添加一个函数
function init_note2() {
$this->load('note');
$_ENV['note']->send();
}
1.2、在base()函数中添加
$this->init_note2();
2、修改uc_client/model/base.php
2.1、添加一个函数
function init_note2() {
$this->load('note');
$_ENV['note']->send();
}
两个base.php文件中添加的函数名可以是其他的,但两边必须是一样的名称。
这样在登录账号和退出账号的时候都会进行一次同步通知,虽然通知有点频繁,但是却能够达到效果。