Ucenter实际通信成功但后台显示通信失败解决方案

给呦呦鹿鸣注册站增加了一个单点登陆,整合Ucenter之后,可以正常使用,但是Ucenter后台提示通信失败,结合网上的一些文章,最终解决,整理一下解决过程: 写在前面:本文所将不一定符合所有人的错误环境,只是提供一个思路。 错误描述:使用正常,但是在后台这里出现了通信失败的通知: uc1 此时右单击审查元素(使用具有审查元素功能的浏览器),此时可以看到类似这样的js代码: uc2 点击它,此时你会在页面上看到下面的东西: uc3 document.getElementById('status_4').innerHTML = "通信失败";testlink(); 看下地址栏的地址:
http://你的ucenter域名/admin.php?m=app&a=ping&inajax=1&url=忽略后面的
可以看到是ucenter的admin.php返回的结果,a=ping调用的是onping方法,打开这个php文件,找到onping方法,可以看到这样的关键代码:
function onping() {
		$ip = getgpc('ip');
		$url = getgpc('url');
		$appid = intval(getgpc('appid'));
		$app = $_ENV['app']->get_app_by_appid($appid);
		$status = '';
		if($app['extra']['apppath'] && @include $app['extra']['apppath'].'./api/'.$app['apifilename']) {
			$uc_note = new uc_note();
			$status = $uc_note->test($note['getdata'], $note['postdata']);
		} else {
			$this->load('note');
			$url = $_ENV['note']->get_url_code('test', '', $appid);
			$status = $_ENV['app']->test_api($url, $ip);
		}
		if($status == '1') {
			echo 'document.getElementById(\'status_'.$appid.'\').innerHTML = "'.$this->lang['app_connent_ok'].'";testlink();';
		} else {
			echo 'document.getElementById(\'status_'.$appid.'\').innerHTML = "'.$this->lang['app_connent_false'].'";testlink();';
		}

	}  
可以看到只要$status!=='1'就返回失败,我们在if($status == '1')前面设置断点进行debug,echo "\$url = $url
\n \$status = $status
\n";die();,然后刷新刚才那个错误页面,出现了这样的提示: uc4 可以看到url获取正常,但是$status返回为空,可以从代码中看到$status = $_ENV['app']->test_api($url, $ip);所有我们需要找到test_api这个函数,我也不知道在什么地方,进行文件夹搜索,找到结果,在model/app.php文件中定义: uc5 打开那个文件,找到关键代码:
function test_api($url, $ip = '') {
		$this->base->load('misc');
		if(!$ip) {
			$ip = $_ENV['misc']->get_host_by_url($url);
		}

		if($ip < 0) {
			return FALSE;
		}
		return $_ENV['misc']->dfopen($url, 0, '', '', 1, $ip);
	}
很明显这个函数return为空,继续寻找dfopen函数,如法炮制,找到这个函数,函数代码段比较长,看下关键代码:
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);
		} else {
			$fp = false;
		}
看到这个之后基本搞明白了,fsockopen和pfsockopen这两个函数由于安全限制被php默认disable掉了,编辑php.ini文件,开启:
$sudo vim /usr/local/php/etc/php.ini
打开文件后搜索关键词:allow_url_fopen,找到allow_url_fopen = On确认值为On,然后搜索关键词extension=php_openssl.dll,找到之后确定将前面的分号删除,者两步完成后还不行,最后一步,搜索关键词:disable_function,找到之后删除fsockopen,保存文件,然后重启php:
$sudo service php-fpm restart
重启之后后台通信正常。