很早就對開發微博應用有興趣了,不過苦於沒有idea,所以一直擱置著。碰巧前幾天看到烏雲說微博的提醒介面可以查看任意使用者的未讀資訊數,因此決定開發一個相關應用練手,用了兩天時間開發。當然這不可能是正常的應用,畢竟不知這是否漏洞,新浪會否修複,況且這應用也沒什麼用……
首先如果要使用微博介面,必須要建立應用,相關地址:http://open.weibo.com/development 建立一個站內應用就可以了。既然是站內應用,我也要有一個屬於自己的網站,因此我使用新浪SAE搭建了自己的伺服器,相關地址:http://sae.sina.com.cn/?m=appwizard 。建立網站前要要先安裝一款應用或架構,然後就可以通過上傳檔案或SVN管理網站,也可以管理資料庫和線上編輯檔案。在市集中安裝一款開發架構後,這樣就擁有一個已經包含DEMO的網站,並且也包含了一些微博類和資料庫操作類。直接include_once( 'saetv2.ex.class.php' );就可以通過這個類調用微博API了,關於API文檔請瀏覽 http://open.weibo.com/wiki/API%E6%96%87%E6%A1%A3_V2。SAE裡也可以安裝web應用例如WP,不過我認為那不是用來開發微博應用的,並且安裝時消耗較多的記憶體和磁碟空間,因此安裝架構才能真正搭建自己打造的網站。詳細關於建立SAE網站和微博應用請參考文章末尾的相關連結)
然後在應用的基本資料中設定應用實際地址為剛剛搭建的網站地址,在進階資訊中添加測試使用者。最後修改DEMO輸出 $_SESSION['oauth2']['oauth_token'] 的值,這個值也稱為access_token,說明該測試使用者授權給你的應用,通過這個值就可以使用OAuth2.0調用微博API了。因此有了access_token就可以把測試環境設定在本地而不浪費SAE資源。不過注意OAuth2.0中的access_token預設到期時間是1天,也就是說只要在程式中直接使用這個值就可以讓任何人不授權也能使用應用,不過有效時間為一天。
注意,以上直接使用方法不是正常應用使用的方法,正常應用開發完成後,應該提交並審核,通過後其它微博使用者就能授權並且使用這個應用,不同的使用者授權獲得不同的access_token,通過這個值使用API就能查看對應使用者的資訊或者進行各種操作了。程式中只要直接使用$_SESSION['oauth2']['oauth_token']作為微博類的構造參數即可。簡而言之,我的這個應用之所以免授權,原理是通過添加的測試使用者授權而得到access_token然後手工賦值,最後才能給別人試用的。
而微博未讀資訊提醒介面的說明在 http://open.weibo.com/wiki/2/remind/unread_count ,由於要輸入uid作為參數,而查詢使用者輸入的是微博暱稱,因此需要進行轉換,所以用到了這個介面 http://open.weibo.com/wiki/2/users/show 。
剩下的就是介面設計、資料庫設計和編寫代碼。我只用了一個指令碼,並且與DEMO的檔案無關除了設定檔,說一下要注意的地方吧。
include設定檔和微博設定access_token,並且使用htmlspecialchars處理輸入資料。
- include_once( 'config.php' );
- include_once( 'saetv2.ex.class.php' );
-
- $access_token = "2.00SaOjjC2PrzYBc99be8c025xsHYpB";
- $name = htmlspecialchars( trim($_POST['username']) );
由於這是免授權應用,因此要手動設定$access_token並作為參數輸入,SaeTClientV2包含在saetv2.ex.class.php中,通過這個類就可以調用微博API了。show_user_by_name()能通過微博暱稱擷取使用者資訊。
- $c = new SaeTClientV2( WB_AKEY , WB_SKEY , $access_token ,'' );
- $users = $c->show_user_by_name( strval($name) );
表單的製作也很簡單,就一個輸入框和按鈕。由於表單設定成POST給自身,因此必須添加一個hidden,以此判斷是否提交表單,譬如使用if( $_POST['action'] == 'unread' )。特別當輸入空值時能分清是剛開啟頁面還是已經提交了表單不過輸入為空白。另外輸入空值和輸入空白字元是不同概念。
- <div style="padding: 10px;background: #e9e9e9;text-align: center;">
- <form action="" method="POST">
- 使用者暱稱:<input type="text" id="username" name="username" class="input" maxlength="32" value="<?=$name?>"/>
- <input type="submit" value="查詢" class="bt"/>
- <input type="hidden" name="action" value="unread" />
- </form></div>
如果通過users/show介面順利獲得使用者ID,就再使用該ID調用remind/unread_count介面擷取並顯示。否則出現錯誤就通過返回的error_code判斷錯誤原因,暫時知道以下四個錯誤。
- if( isset($users['id']) ){
- //這裡就是輸出查詢結果,代碼省略
- }
- elseif( isset($users['error_code']) ){
- if( $users['error_code'] == 10006 )//source paramter(appkey) is missing
- p("此應用已到期,如需繼續使用,請聯絡作者,謝謝!");
- elseif( $users['error_code'] == 10008 )
- p("請輸入使用者暱稱!");
- elseif( $users['error_code'] == 20003 )
- p("使用者“".$name."”不存在!");
- elseif( $users['error_code'] == 21327 )//expired_token
- p("access_token已到期,如需繼續使用,請聯絡作者,謝謝!");
- else
- p("出現錯誤:".$users['error_code']);
- $result = json_encode($users);
- }
- else {
- p("出現未知錯誤,請重新進行查詢!");
- $result = json_encode($users);
- }
為了提高使用者體驗,最後使用JS把輸入焦點設定在輸入框,方便使用者輸入和多次查詢。
- <script type="text/javascript">
- document.getElementById('username').focus();
- </script>
關於資料庫操作使用SAE封裝好的類來操作,而資料表早已通過SAE設計好。主鍵id自增,name如果查詢成功是微博暱稱否則是使用者輸入的名字,uid如果查詢成功返回微博使用者ID否則為0此資料除了避免使用者改暱稱,還可以分辨查詢操作是否成功),ip判斷使用人數,time是必須的而我使用時間戳來記錄可讀性不強,result就是介面返回的json結果,無論成功與否都會記錄下來。
- $mysql = new SaeMysql();
- $mysql->runSql("INSERT INTO {$dbtable} (id, name, uid, ip, time, result) VALUES ('', '$name', '$uid', '$ip', '$timestamp', '$result')");
- $mysql->closeDb();
最後是該應用的示範,介面比較簡潔,通過兩個介面擷取的訊息也不多。
650) this.width=650;" border="0" alt="" src="http://www.bkjia.com/uploads/allimg/131228/134K44306-0.jpg" />
編寫代碼總結:
表單要通過hidden的input判斷進行何種操作;
要處理好使用者的任何輸入並且及時反饋;
每次使用函數都要注意失敗的情況;
關於介面置中問題,主div使用margin: 0 auto;置中,它指的是讓容器自己置中。表單和標題使用text-align: center;,它指的是讓容器中的元素置中。當然可以對塊狀元素使用margin: 0 auto;置中,不過前提是這個塊的寬度小於父容器,並且不代表塊內元素會置中。
如果SaeTClientV2類沒有新介面的相關函數譬如unread_count未讀提醒介面),可以直接使用SaeTOAuthV2類的get()函數,為了統一變數,因此其實以下代碼才是我實際上的寫法,而不是像上面所說那樣使用SaeTClientV2類。
- $o = new SaeTOAuthV2( WB_AKEY, WB_SKEY, $access_token, NULL );
-
- //通過$_POST['action']判斷是否提交表單,而不是判斷$_POST['username']是否為空白
- if( $_POST['action'] == 'unread' ){
- $showparams = array();
- $showparams['screen_name'] = strval($name);
- $users = $o->get('users/show', $showparams);
-
- if( isset($users['id']) ){
- $unreadparams = array();
- $unreadparams['uid'] = $users['id'];;
- $remind = $o->get('remind/unread_count', $unreadparams);
- if($remind){
- //輸出查詢結果
最後是在微博公開應用,時間是2月9日21:16,經過24小時後統計了一些資訊。
使用次數353,包括測試資料若干:
- SELECT count(*) FROM `temp_unread` WHERE time < 1328879760
使用人數33:
- SELECT count(*) FROM ( SELECT DISTINCT ip FROM `temp_unread` WHERE time < 1328879760 ) AS t
被搜尋的名字一共有87個,包括輸入錯誤情況:
- SELECT count(*) FROM ( SELECT DISTINCT name FROM `temp_unread` WHERE time < 1328879760 ) AS t
不包括錯誤情況,共有74個:
- SELECT count(*) FROM ( SELECT DISTINCT uid FROM `temp_unread` WHERE time < 1328879760 AND uid != 0 ) AS t
通過資料庫的記錄,發現兩個不同使用者同時使用這個應用時,有可能返回null,我不知這是新浪的問題還是我程式不夠完善,也不知如何應付這種情況。
其它統計資訊:
HTTP流入354.01 KB
HTTP流出1.27 MB
MySQL磁碟消耗7.35 KB
SAE資源消耗0.29雲豆。
相關文檔:
站內應用開發指南
SAE入門指引
Oauth2說明
SaeTOAuthV2類說明
SaeTClientV2類說明
SaeMysql類說明
本文出自 “LuckyHJH的技術部落格” 部落格,請務必保留此出處http://luckyhjh.blog.51cto.com/2977099/776791