Facebook PHP SDK 升級以往都是安排個半天寫好、測試,沒想到這次一行 code 的位置問題,追了三天才搞定,寫個簡單的範例出來,希望大家不會踩到同樣的問題。
- Facebook 官方說明:Easily upgrade to Graph API v2.x with no code changes
- Facebook Platform Upgrade Guide
- Upgrading your apps to Graph API v2.x
Facebook v4.4 PHP SDK 升級範例
Facebook 於 2015/4月底 強迫大家一定需要升級到 PHP SDK v4 and Graph API 2.0,然後 SDK 第一行如下:
The Facebook SDK for PHP v4 requires PHP 5.4 or greater.
Facebook SDK PHP v4 的基本環境要求是 PHP 5.4 以上,所以若使用 Ubuntu Linux 12.04 以下的,也藉此機會升級到 14.04 以上吧~ (泣~~)
註:用 5.3 以下跑的,error log 會直接看到此訊息:
PHP Fatal error: Uncaught exception 'Exception' with message 'The Facebook SDK v4 requires PHP version 5.4 or higher.
Facebook API 升級的前置環境設定
設定 Test 的環境,先到此網址:https://developers.facebook.com/apps/[YOUR-APP-ID]/settings/migrations/,再依照下述兩張圖建立測試環境
- 建立測試 APP
- 設定測試 APP 使用 Graph API 2.0
註1:如果沒有上述兩張圖的 Use Graph API v2.0 by default 可以選,就不需要做此設定(代表你的是近年建立的,可以同時相容新、舊版,直接改程式即可。)
註2:上線時,記得上完 code 後,要將正式環境切換成 Graph API v2.0。
上述環境設定完成後,再下來改程式才會動。
Facebook PHP SDK upgrade step by step
文件:Getting started with the Facebook SDK for PHP
- 請於上述文件網址下載 SDK:https://github.com/facebook/facebook-php-sdk-v4/archive/4.0-dev.zip
- unzip facebook-php-sdk-v4-4.0-dev.zip
- 再來範例程式可見:https://github.com/tsung/facebook-v4-example
- 請依照範例程式修改即可,裡面的程式如下:
- login.php:單純只要使用 Facebook 登入,第一次需要抓取 Email 等相關資料,可以參考這隻。
- advlogin.php:使用 Facebook 登入後,每個頁面都需要另外抓取其它資料的用這隻。
註:上述程式我是直接把現有程式拔出來貼上,未經測試,若有問題請通報我再來修(註:被搞了三天,暫時不想測試了)
- 到此修改完程式,就可以準備上線 + 切換 App 設定即可,下述內容可以不用看,下述是我遇到的問題說明。
Facebook v4.4 程式注意事項
上述程式的順序要注意一下,這邊說明要注意的位置(我遇到的問題):(下述說明的程式,請參照 facebook v4 example: login.php)
一般程式會寫這樣子,產生 fb redirect helper 後,直接設定權限來取得 login url。
<?php $redirect_uri = 'http://YOUR_DOMAIN/login.php?from=' . urlencode($from); $fbrdhelper = new \Facebook\FacebookRedirectLoginHelper($redirect_uri); $fb_login_url = $fbrdhelper->getLoginUrl(array('email')); ?>
但是這樣子寫的話,在程式下面要生 fb session 的部分,會永遠生不出來,需要將 $fb_login_url = $fbrdhelper->getLoginUrl(array('email')); 移到最下面才可以。
主要原因如下:
Facebook redirect 回來會需要兩個參數:$_GET['code'] 和 $_GET['state'],用途分別如下:
- $code 是加密過的 token
- $state 是用來避免 oauth2 的 中間人的攻擊用的(所以 state 會需要依照時間生成亂數(可由 getLoginUrl 等 code 去看到)
如果順序不對,或者值被修改,getSession() 要驗證就會失敗,所以 $fbsession (FacebookSession object) 就產生不出來。
於程式裡面都會看到下述:
<?php $_SESSION[$this->sessionPrefix . 'state'] = $state; ?>
若有遇到此問題時,可以於程式內容都做 var_dump($_SESSION);,就會看到原始 $_SESSION['FBRLH_state'] 的值如下:
array(1) { ["FBRLH_state"]=> string(32) "9404ad643c26d108631e8105bf87ec4a" }
跑過 $fb_login_url = $fbrdhelper->getLoginUrl(array('email')); 後,$_SESSION['FBRLH_state'] 的值如下:
array(1) { ["FBRLH_state"]=> string(32) "749911c43980a1a69fe1e9903500e586" }
因為 $state 的值被修改,所以 FacebookSession object 就會無法產生,不管使用下述任何物件都無法產生(下述於 FB 文件說明:)
// Use one of the helper classes to get a FacebookSession object.
// FacebookRedirectLoginHelper
// FacebookCanvasLoginHelper
// FacebookJavaScriptLoginHelper
// or create a FacebookSession with a valid access token:
$session = new FacebookSession('access-token-here');
所以解法就是將產生 URL 的程式往下移動,就可以避開此問題。
測試程式
<?php $fbrdhelper = new \Facebook\FacebookRedirectLoginHelper(); // $fb_login_url = $fbrdhelper->getLoginUrl(array('email')); $fbsession = new \Facebook\FacebookSession($_SESSION['fbtoken']); $req = (new \Facebook\FacebookRequest($fbsession, 'GET', '/me', array(), 'v2.0'))->execute(); $data = json_decode($req->getRawResponse(), true); print_r($data); ?>
註:上述問題是完全不相干的物件,而且應該可以使用兩個不同 Session 值解決,不知為何一定要設成同一個值,造成此問題。
相關網頁
- Facebook SDK 4.0.0 for PHP: A working sample to get started.
- Facebook SDK 4.0.0 for PHP: A working sample to manage sessions
- Facebook SDK PHP v4 — a complete guide!
- Facebook API: PHP SDK Updated to v4.0.0
- Facebook開始升級到Graph API v2,應用程式存取個人資訊更嚴格
Save