ThinkPHP與UCenter整合詳解

發表於2019-05-11

最近應公司的要求,要開發一個有點像QQ空間那樣的會員管理中心網站,發現UCenter的很多功能酷似QQ空間,於是選擇了UCenter作為程式的會員管理中心。前臺嘛就選擇我之前基於ThinkPHP3.1.2框架開發的WBlog好了。但是問題又來了:要求在WBlog前臺註冊的會員登入時要與UCenter同步,這就是我這次要解決的問題--ThinkPHP與UCenter的整合。我在網上搜尋了一下,ThinkPHP與UCenter的整合並不少,但是似乎越看越覺得頭暈,不是少這就是少那,到頭來差之毫釐,謬以千里,真夠折騰的。我仔細閱讀了UCenter的開發文件後,經過多次的除錯,終於完成了ThinkPHP與UCenter的整合。感覺這個結果是從苦水裡泡出來的一樣,呵呵。。。現在把整合的記錄分享給需要的童鞋。溫馨提示:在thinphp與UCenter整合中,您需要的基本條件是,有一定的PHP基礎,對ThinkPHP框架有所瞭解,會佈署目錄和配置資料。好了,我們開始吧!下載並安裝下面的程式WBlog3.1.2UCenter_Home_2.0_SC_UTF8UCenter 1.6.0安裝WBlog部落格程式已釋出的WBlog部落格程式還沒有會員中心,本次測試的會員中心是後面才寫的。如果你能等的話要待我整理好WBlog的會員中心程式才釋出,不能等的話也不會影響下面的程式整合,因為你可以找或者自己寫簡單的滿足以下兩個條件的thikphp程式:1、可以註冊會員2、可以登入和退出。這裡我就使用WBlog3.1.2了。在伺服器的根目錄新建目錄wblog1,把下載的WBlog3.1.2解壓得到的WBlog目錄裡的所有檔案複製到wblog1。在瀏覽器輸入http://127.0.0.1/wblog1/install/,安裝WBlog3.1.2。溫馨提示:在整合時最容易搞錯的就是路徑問題,在接下來的整合操作的根目錄都是指wblog1目錄,所以要和伺服器根目錄區別開來。安裝UCenter 1.6.0(簡體UTF-8)這個程式到官方去下載吧。在網站根目錄wblog1新建 ucenter 目錄,解壓UCenter 1.6.0,把解壓得到的upload目錄裡的所有檔案複製到剛才新建的ucenter目錄裡。在瀏覽器輸入http://127.0.0.1/wblog1/ucenter/install/,安裝UCenter 1.6.0。安裝UCenter_Home_2.0_SC_UTF8(簡體中文版)在網站根目錄wblog1新建 uh目錄並解壓UCenter_Home_2.0_SC_UTF8,把解壓得到的upload目錄裡的所有檔案複製到剛才新建的uh目錄裡。在瀏覽器輸入http://127.0.0.1/wblog1/uh/install/,安裝UCenter_Home_2.0_SC_UTF8。需要注意的是,安裝UCenter 1.6.0和UCenter_Home_2.0_SC_UTF8時順序不能顛倒,否則無法安裝。我們安裝完了WBlog3.1.2、UCenter_Home_2.0_SC_UTF8和UCenter 1.6.0三個程式後。接下來找到下載的UCenter 1.6.0,把 advanced 目錄裡面的uc_client 和 examples下面的api 資料夾複製到網站根目錄wblog1下,和ThinkPHP在同一目錄。找到專案W3note的配置資料夾wblog1/ Conf/,在其新建一個UCenter的配置檔案 config_ucenter.php ,然後在WBlog1\W3note\Lib\ORG目錄下新建一個UCenter的通訊處理類檔案UcService.class.php,我們先不要管檔案裡面寫什麼程式碼,後面將會講到。好了到這裡已經把後面要操作的目錄和檔案都佈局好了。為了理清目錄和檔案之間的層次關係,我把目錄和檔案製成目錄樹列出來:wblog1根目錄| – index.php//前臺入口檔案| – admin.php| – W3note//前臺專案| | – Lib| | | – ORG| | | | –UcService.class.php //UCenter的通訊處理類檔案| | – Conf//W3note專案的配置目錄| | | –config_ucenter.php //UCenter的配置檔案| || – Admin| – ThinkPHP //thinkphp3.1.2核心包和一些擴充套件| – install| – api| | – uc.php|| – uc_client| – ucenter| – uh這樣我們就可以一目瞭然了。現在開始api目錄裡面的uc.php 配置了,首先開啟這個檔案,找到36行的位置這一行程式碼
  1. require_once DISCUZ_ROOT.'./config.inc.php';
複製程式碼
把'./config.inc.php'這一部分替換成'./W3note/Conf/config_ucenter.php'往下找還會看到幾處的'./config.inc.php',按照上面的操作全部替換掉。這樣做目的是把前面建的配置檔案config_ucenter.php導進來。 接下來我登入http://127.0.0.1/wblog1/ucenter,在開啟左邊選單“應用管理”這一項,然後新增一個新應用,這時我們發現好多東西要填!照著下面操作就是了。先看應用型別,因為這是我們自己開發的程式,所以就選其它吧,再看應用名稱,隨便填,只要不超過20位元組就行了,我這裡填wblog。接下來是應用的主URL,這裡填網站的主頁http;//127.0.0.1/wblog1,注意了,後面沒有“/”。至於應用的其他URL還有應用IP這兩項就跳過,不用管它了。接下來是通訊金鑰,就按其旁邊的提示填就是了,我這裡填abc123456。往下是應用的物路徑,提示說預設為空,那就留空吧,還有檢視個人資料頁面地址也留空吧。接下來是應用介面檔名稱,預設為uc.php,保持原狀吧。繼續往下看,標籤單條顯示模板還有標籤模板標記說明這兩項也不用理它,跳過。是否開啟同步登入,選是;是否接受通知也選是吧。終於填完了,那就點選提交吧!還記得前面在uc.php匯入的檔案config_ucenter.php嗎,裡面可是一片空白啊,現在我們就來放些配置資訊進去。剛才我們填好的資訊提交後,會在提交按鈕下面的“應用的UCenter配置資訊”下面生成了一些配置資訊,我們直接把它複製,然後粘帖到config_ucenter.php,儲存。網上很多教程到這裡就表示通訊成功了,在這裡我非常驚訝!因為通訊並未成功!我在這裡折騰了一些時間,後來仔細檢了uc.php檔案的程式碼,發現59行:
  1. require_once DISCUZ_ROOT.'./include/db_mysql.class.php';
複製程式碼
我在佈局的目錄中始終找不到db_mysql.class.php,後來發現db_mysql.class.php存UCenter_1.6.0_SC_UTF8\advanced\examples\include目錄中,這就是問題所在!因為我們之前複製的只是UCenter_1.6.0_SC_UTF8\advanced\examples\中的api檔案。解決這一問題的辦法就是把上面的程式碼修改為
  1. require_once DISCUZ_ROOT.'./uc_client/lib/db.class.php';
複製程式碼
匯入的資料庫類檔案變了,那麼我們也要對其所涉及的內容作相應的修改,在uc.php59行的下面如
  1. $GLOBALS['db'] = new dbstuff;
  2. $GLOBALS['db']->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset);
  3. $GLOBALS['tablepre'] = $tablepre;
  4.  修改為
  5. $GLOBALS['db'] = new ucclient_db;
  6. $GLOBALS['db']->connect(UC_DBHOST, UC_DBUSER, UC_DBPW, UC_DBNAME, UC_DBCONNECT, true, UC_DBCHARSET);
  7. $GLOBALS['tablepre'] = UC_DBTABLEPRE;//關鍵
複製程式碼
上面資料庫的連結資訊的靜態變數來自config_ucenter.php。好了,我們回到後臺ucenter重新整理一下頁面,發現什麼---通訊成功了!那麼接下來我們的目標:在thinkphp中會員註冊成功時,UCenter Home也同時註冊成功。首先在專案W3note入口檔案index.php配置一個常量define('WBLOG_ROOT_PATH', rtrim(dirname(__FILE__), '/\\') . DIRECTORY_SEPARATOR);//物理根目錄常量WBLOG_ROOT_PATH是網站根目錄wblog1的物理根目錄,在我本地伺服器列印輸出:D:\phpsever\apache2\htdocs\wblog1\有必要在這裡強調一下,理解WBLOG_ROOT_PATH很重要,因為在除錯過程中路徑最容易出錯。還記得前面我們建的UcService.class.php 檔案嗎?如果忘記了請看一下前面的目錄樹。開啟UcService.class.php檔案,新建一個類UcService,然後寫一個構造方法匯入W3note/Conf/config_ucenter.php和uc_client/client.php兩個檔案。程式碼:
  1. class UcService{
  2.  public function __construct(){
  3. include_once(WBLOG_ROOT_PATH . 'W3note/Conf/config_ucenter.php');
  4. include_once(WBLOG_ROOT_PATH . 'uc_client/client.php');
  5.  }
複製程式碼
接下來我們寫一個會員註冊方法register,如public function register($username, $password, $email){}方法體放什麼程式碼呢?其實很簡單,因為UCenter的開發文件已經為我們準備好了!找到之前下載的UCenter_1.6.0_SC_UTF8,用瀏覽器開啟UCenter_1.6.0_SC_UTF\advanced\document\index.htm,然後在左邊的選單欄找到“使用者介面”,看到使用者註冊示例 (PHP),把其下的程式碼複製過來。如下
  1. /**
  2. * 會員註冊
  3. */
  4.  public function register($username, $password, $email){
  5. $uid = uc_user_register($username, $password, $email);//UCenter的註冊驗證函式
  6.  if($uid <= 0) {
  7.  if($uid == -1) {
  8.  return '使用者名稱不合法';
  9.  } elseif($uid == -2) {
  10.  return '包含不允許註冊的詞語';
  11.  } elseif($uid == -3) {
  12.  return '使用者名稱已經存在';
  13.  } elseif($uid == -4) {
  14.  return 'Email 格式有誤';
  15.  } elseif($uid == -5) {
  16.  return 'Email 不允許註冊';
  17.  } elseif($uid == -6) {
  18.  return '該 Email 已經被註冊';
  19.  } else {
  20.  return '未定義';
  21.  }
  22.  } else {
  23.  return intval($uid);//返回一個非負數
  24.  }
  25.  }
  26.  }
複製程式碼
這個註冊方法register的作用是,在wblog1的會員註冊中成功註冊一個會員時,也會成功註冊UCenter Home的會員中心中。UCenter的註冊方法我們在上面已經寫好了,現在回到thinkphp。我們在前臺W3note專案的控制器MemberAction寫一個註冊方法,程式碼如下:
  1. /*
  2. 使用者名稱:$username,
  3. 密碼:$password,
  4. 郵箱:$email
  5. */
  6.  public function addmember(){
  7.  if($this->isPost()){
  8. $username = $_POST['username'];
  9. $email = $_POST['email'];
  10. $password = trim($_POST['password']);
  11.  import("@.ORG.UcService");//匯入UcService.class.php類
  12. $ucService = new UcService;//例項化UcService類
  13. $uid = $ucService->register($username, $password, $email);//註冊到UCenter
  14.  if($uid){//如果上面註冊成功將返回一個int型別的數字
  15. $M = D('Member');
  16.  if ($vo = $M->create()) {
  17.  if ($M->add()) {
  18. $this->success('註冊成功!');
  19.  } else {
  20. $this->error('註冊失敗!');
  21.  }
  22.  } else {
  23. $this->error();
  24.  }
  25.  }else{
  26.  exit($uid);
  27.  }
  28.  }else{
  29. $this->error('非法資料!');
  30.  }
  31.  }
複製程式碼
我們在thinkphp會員註冊頁面註冊一個帳號,提交表單後,檢視wblog1和UCenter的會員資料表,發現兩張表都存相同的帳號,說明同步註冊已經成功了!有了帳號我們就可以來做同步登入了。開啟UcService.class.php檔案,新增一個UC登入和一個登出的方法,程式碼到UCenter介面開發手冊的使用者介面那裡找使用者登入示例程式碼,把它複製過來,然後稍微更改一下,使其帶有返回值,以便下一步的操作,程式碼如下:
  1. public function uc_login($username, $password){
  2. list($uid, $username, $password, $email) = uc_user_login($username, $password);
  3.  if($uid > 0) {
  4.  return array(
  5.  'uid' => $uid,
  6.  'username' => $username,
  7.  'password' => $password,
  8.  'email' => $email
  9.  );
  10.  } elseif($uid == -1) {
  11.  return '使用者不存在,或者被刪除';
  12.  } elseif($uid == -2) {
  13.  return '密碼錯誤';
  14.  } elseif($uid == -3) {
  15.  return '安全提問錯誤';
  16.  } else {
  17.  return '未定義';
  18.  }
  19.  }
複製程式碼
繼續在使用者介面那裡找到同步登入的程式碼示例,找到“uc_user_synlogin($uid);”其作用是執行同步登入,然後寫成uc_synlogin方法如下:
  1. public function uc_synlogin($uid){
  2.  return uc_user_synlogin($uid);
  3.  }
複製程式碼
到這裡UcService.class.php檔案的登入方法已經寫好,接下來開啟前臺W3note專案的控制器MemberAction.class.php檔案寫一個同步登入的方法,看程式碼:
  1. public function checkLogin() {
  2.  if(!$_POST['username']) $this->error('帳號錯誤!');
  3.  if(!$_POST['password']) $this->error('密碼錯誤!');
  4.  if(empty($_POST['verify'])) $this->error('驗證碼必須!');
  5.  import("@.ORG.UcService");//匯入UcService.class.php類
  6. $ucService = new UcService;
  7. $uidarray = $ucService->uc_login($_POST['username'], $_POST['password']);
  8.  //dump($uidarray);
  9. $loginurl=$ucService->uc_synlogin($uidarray);
  10. echo $loginurl;//輸出同步登入程式碼,否則無法同步登入
  11.  if(!is_string($uidarray)){
  12.  //生成認證條件
  13. $map = array();
  14.  // 支援使用繫結帳號登入
  15. $map['username'] = $_POST['username'];
  16. $map["status"] = array('gt',0);
  17.  if($_SESSION['verify'] != md5($_POST['verify'])) {
  18. $this->error('驗證碼錯誤!');
  19.  }
  20. $memberinfo=$this->Member->where($map)->find();
  21.  if(false === $memberinfo) {
  22. $this->error('帳號不存在或已禁用!');
  23.  }elseif($memberinfo['status']==0){
  24. $this->error('帳號已禁用!');
  25.  }else {
  26. $password = pwdHash($_POST['password']);
  27.  if($memberinfo['password'] != $password) {
  28. $this->error('密碼錯誤!');
  29.  }
  30. session(C('USER_AUTH_KEY'), $memberinfo['id']);
  31. session('email', $memberinfo['email'] );
  32. session('loginUserName', $memberinfo['loginUserName']);
  33. session('lastLoginTime', $memberinfo['lastLoginTime']);
  34. session('loginnum', $memberinfo['loginnum']);
  35. session('lastloginip', $memberinfo['lastloginip']);
  36.  //儲存登入資訊(相當於更新資訊)
  37. $data = array();
  38. $data['id'] = $memberinfo['id'];
  39. $data['lastlogintime'] = time();
  40. $data['loginnum'] = array('exp','loginnum+1');
  41. $data['lastloginip'] = get_client_ip();
  42.  //$data['verify'] = $authInfo['verify'];
  43. $this->Member->save($data);
  44. $this->success('登入成功!',U('Member/index'));
  45.  }
  46.  }
  47.  }
複製程式碼
我們來看一下checkLogin()方法的執行過程。在專案W3note註冊的一個帳號,然後在專案W3note提交登入表單後,首先執行UCenter的登入,前面我們寫了兩個UCenter的登入方法,在呼叫之前需要使用“import("@.ORG.UcService");”把UcService.class.php檔案載入進來,例項化後得到$ucService,然後就可以使用用$ucService訪問UCenterr的登入方法uc_login,返回一個$uidarray值,$uidarray包函什麼資料?使用“dump($uidarray);”列印出來,以便下一步的操作,列印結果如下:
  1. array(4) {
  2.  ["uid"] => string(1) "1"
  3.  ["username"] => string(5) "qqabc"
  4.  ["password"] => string(6) "123456"
  5.  ["email"] => string(9) "qq@qq.com"
  6.  }
複製程式碼
下一步就是以此$uidarray作為引數傳給同步登入方法uc_synlogin($uidarray),最後echo 一下uc_synlogin($uidarray)的返回值$loginurl,就可以實現帳號"qqabc"在UCenter登入了。帳號"qqabc"在UCenter登入成功後程式將繼續往下執行專案W3note的登入,這裡就不多說了。最後的結果是,帳號"qqabc"實現了在UCenter和專案W3note的同步登入!
評論(4)

相關文章