ECSHOP后台会员整合,只允许整合一个应用。
如果想整合多个应用,就需要先和UCenter整合,之后再通过UCenter去整合更多的应用。
整合之后工作流程:
1.首先在ini.php文件中使用 ini_user()函数来判断整合插件名称,此函数定义在lib_common.php文件中。
并生成相应的插件对象,方便以后调用。
/**
* 初始化会员数据整合类
*
* @access public
* @return object
*/
function&init_users()
{
$set_modules=false;
static$cls=null;
if ($cls!=null)
{
return$cls;
}
include_once(ROOT_PATH . ‘includes/modules/integrates/’ .$GLOBALS['_CFG']['integrate_code'] . ‘.php’);
$cfg=unserialize($GLOBALS['_CFG']['integrate_config']);
$cls=new$GLOBALS['_CFG']['integrate_code']($cfg);
return$cls;
}
ecshop整合过程将需要整合的应用数据库看做主库。
比如ec和pw整合,就以PW为主库,将ec的会员信息全部导入到pw会员表中。
之后在ecshop登陆的时候,会通过user.php中的$user->login($username, $password)函数,
和integrates/integrate.php中的sync()函数判断该用户是否在ecshop中存在,
如果不存在,则从PW中拷贝一条记录过来。
具体分析从ecshop登陆的过程:
1:检查username是否在pw_members表存在,如果存在,通过if($this->need_sync)判断是否需要同步登陆,
如果需要同步登陆,则调用$this->sync()函数。具体参考login函数.
{
if ($this->check_user($username,$password) >0)
{
if ($this->need_sync)
{
$this->sync($username,$password);
}
$this->set_session($username); //同步登陆成功后,设置session
$this->set_cookie($username); //同步登陆成功后,设置cookie,保存登陆状态。
returntrue;
}
else
{
returnfalse;
}
}
2:同步登陆 sync 函数分析:
首先通过 get_profile_by_name 函数从pw_members表中来获得用户基本信息。
SQL语句如下:
SELECT uid AS user_id,username AS user_name,email AS email,gender AS sex,
bday AS birthday,regdate AS reg_time, password AS password
FROM `phpwind_53`.`pw_members` WHERE username=’测试’;
然后从ecs_users表中根据 username 来获取用户信息,
如果信息为空,则表明ecshop中不存在该用户,就将该用户的信息插入到ecs_users表中。
如果信息不为空,则判断ecs_users表中和pw_members表中的用户信息是否一致,
如果不一致,则以pw_members表中的数据为准,进而需要update下ecs_users表中的信息数据,使其与pw中数据一致。
* 会员同步
*
* @access public
* @param
*
* @return void
*/
function sync ($username,$password=”,$md5password=”)
{
if ((!empty($password)) &&empty($md5password))
{
$md5password=md5($password);
}
$main_profile=$this->get_profile_by_name($username);
if (empty($main_profile))
{
returnfalse;
}
$sql= “SELECT user_name, email, password, sex, birthday”.
” FROM ” .$GLOBALS['ecs']->table(‘users’).
” WHERE user_name = ‘$username’”;
$profile=$GLOBALS['db']->getRow($sql);
if (empty($profile))
{
/* 向商城表插入一条新记录 */
if (empty($md5password))
{
$sql= “INSERT INTO ” .$GLOBALS['ecs']->table(‘users’).
“(user_name, email, sex, birthday, reg_time)”.
” VALUES(‘$username’, ‘” .$main_profile['email'].”‘,’”.
$main_profile['sex'] . “‘,’” .$main_profile['birthday'] . “‘,’” .$main_profile['reg_time'] . “‘)”;
}
else
{
$sql= “INSERT INTO ” .$GLOBALS['ecs']->table(‘users’).
“(user_name, email, sex, birthday, reg_time, password)”.
” VALUES(‘$username’, ‘” .$main_profile['email'].”‘,’”.
$main_profile['sex'] . “‘,’” .$main_profile['birthday'] . “‘,’” .
$main_profile['reg_time'] . “‘, ‘$md5password’)”;
}
$GLOBALS['db']->query($sql);
returntrue;
}
else
{
$values=array();
if ($main_profile['email'] !=$profile['email'])
{
$values[] = “email=’” .$main_profile['email'] . “‘”;
}
if ($main_profile['sex'] !=$profile['sex'])
{
$values[] = “sex=’” .$main_profile['sex'] . “‘”;
}
if ($main_profile['birthday'] !=$profile['birthday'])
{
$values[] = “birthday=’” .$main_profile['birthday'] . “‘”;
}
if ((!empty($md5password)) && ($md5password!=$profile['password']))
{
$values[] = “password=’” .$md5password. “‘”;
}
if (empty($values))
{
returntrue;
}
else
{
$sql= “UPDATE ” .$GLOBALS['ecs']->table(‘users’).
” SET ” .implode(“, “,$values).
” WHERE user_name=’$username’”;
$GLOBALS['db']->query($sql);
returntrue;
}
}
}
3.设置cookies
ECSHOP所需的cookies是通过integrate/integrate.php中的 set_cookies来完成设置
PHPwind所需的是通过整合接口文件phpwind.php中的set_cookies来完成设置
分析登陆过程
$user 为./includes/modules/integrates/ecshop.php 类文件实例化对象
list($uid,$uname,$pwd,$email,$repeat) = uc_call("uc_user_login",array($username,$password)); $user对象会通过uc_call来验证登陆信息是否正确,uc_call(./includes/lib_common.php 3173) 会调用./uc_center/client.php文件中的uc_user_login函数,
./uc_center/client.php 286
function uc_user_login($username,$password,$isuid=0) {
$isuid=intval($isuid);
$return=call_user_func(UC_API_FUNC,'user','login',array('username'=>$username,'password'=>$password,'isuid'=>$isuid));
return UC_CONNECT =='mysql'?$return: uc_unserialize($return);
}
$return=call_user_func(UC_API_FUNC,'user','login',array('username'=>$username,'password'=>$password,'isuid'=>$isuid));会调用由./uc_client/control/user.php 实例化的对象的onlogin($arr)方法,$user=$_ENV['user']->get_user_by_uid($username);通过这种方法验证用户信息
同步操作与uc_center客户端与uc_center的用户信息验证 的同步操作大致相同
$this->ucdata = uc_call("uc_user_synlogin",array($uid));($user对象78)处理通过验证后同步
./uc_center/client.php 292
function uc_user_synlogin($uid) {
return uc_api_post('user','synlogin',array('uid'=>$uid));
}
./uc_center/client.php 58
function uc_api_post($module,$action,$arg=array()) {
$s=$sep='';
foreach($argas$k=>$v) {
if(is_array($v)) {
$s2=$sep2='';
foreach($vas$k2=>$v2) {
$s2.="$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2));
$sep2='&';
}
$s.=$sep.$s2;
} else {
$s.="$sep$k=".urlencode(uc_stripslashes($v));
}
$sep='&';
}
$postdata= uc_api_requestdata($module,$action,$s);
return uc_fopen2(UC_API.'/index.php',500000,$postdata,'',TRUE, UC_IP,20);
}
53-65 行循环将数组编码并以&号连接
69 生成post 数据
function uc_api_requestdata($module,$action,$arg='',$extra='') {
$input= uc_api_input($arg);
$post="m=$module&a=$action&inajax=2&input=$input&appid=".UC_APPID.$extra;
return$post;
}
75 生成url UC_API在./data/config.php中定义为uc_center的连接地址
function uc_api_url($module,$action,$arg='',$extra='') {
$url= UC_API.'/index.php?'.uc_api_requestdata($module,$action,$arg,$extra);
return$url;
}
发出数据
function uc_fopen2($url,$limit=0,$post='',$cookie='',$bysocket=FALSE,$ip='',$timeout=15,$block=TRUE) {
$__times__=isset($_GET['__times__']) ?intval($_GET['__times__']) +1:1;
if($__times__>2) {
return'';
}
$url.= (strpos($url,'?') ===FALSE?'?':'&')."__times__=$__times__";
return uc_fopen($url,$limit,$post,$cookie,$bysocket,$ip,$timeout,$block);
}
function uc_fopen($url,$limit=0,$post='',$cookie='',$bysocket=FALSE,$ip='',$timeout=15,$block=TRUE) {
$return='';
$matches=parse_url($url);
$host=$matches['host'];
$path=$matches['path'] ?$matches['path'].($matches['query'] ?'?'.$matches['query'] :'') :'/';
$port=!empty($matches['port']) ?$matches['port'] :80;
if($post) {
$out="POST $path HTTP/1.0\r\n";
$out.="Accept: */*\r\n";
//$out .= "Referer: $boardurl\r\n";
$out.="Accept-Language: zh-cn\r\n";
$out.="Content-Type: application/x-www-form-urlencoded\r\n";
$out.="User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
$out.="Host: $host\r\n";
$out.='Content-Length: '.strlen($post)."\r\n";
$out.="Connection: Close\r\n";
$out.="Cache-Control: no-cache\r\n";
$out.="Cookie: $cookie\r\n\r\n";
$out.=$post;
} else {
$out="GET $path HTTP/1.0\r\n";
$out.="Accept: */*\r\n";
//$out .= "Referer: $boardurl\r\n";
$out.="Accept-Language: zh-cn\r\n";
$out.="User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
$out.="Host: $host\r\n";
$out.="Connection: Close\r\n";
$out.="Cookie: $cookie\r\n\r\n";
}
$fp= @fsockopen(($ip?$ip:$host),$port,$errno,$errstr,$timeout);
if(!$fp) {
return'';
} else {
stream_set_blocking($fp,$block);
stream_set_timeout($fp,$timeout);
@fwrite($fp,$out);
$status=stream_get_meta_data($fp);
if(!$status['timed_out']) {
while (!feof($fp)) {
if(($header= @fgets($fp)) && ($header=="\r\n"||$header=="\n")) {
break;
}
}
$stop=false;
while(!feof($fp) &&!$stop) {
$data=fread($fp, ($limit==0||$limit>8192?8192:$limit));
$return.=$data;
if($limit) {
$limit-=strlen($data);
$stop=$limit<=0;
}
}
}
@fclose($fp);
return$return;
}
}