情况:我有一个完成的Facebook画布应用程序(PHP / CodeIgniter),我只需要添加与Facebook相关的选项,如分享和邀请朋友。
当前任务:从PHP SDK获取可邀请的朋友列表。
相关文档:https://developers.facebook.com/docs/games/invitable-friends/v2.0
代码:在我的Facebook库中,我创建了以下功能。
/**
* Returns the current user's invitable friends
*/
public function get_invitable_friends() {
if ( $this->session ) {
$request = ( new FacebookRequest( $this->session, 'GET', '/me/invitable_friends' ) )->execute();
$graphObject = $request->getGraphObject();
return $graphObject;
}
return false;
}
条件if($this->session)
是因为如果首先没有Facebook会话,尝试任何事情都没有意义。这将在以后发挥作用。
我尝试过以两种方式调用此功能。第一种方式有效,第二种方式无效。我要介绍两者,然后有人会希望向我解释为什么第二种方式不起作用以及如何解决它,因为我更喜欢使用它。
第一种(工作)方式:
在页面加载时,从main
控制器的index()
方法调用该函数。该函数正确返回了我的朋友列表。
第二种(非工作)方式:
在控制器中创建此功能:
//load list of friends we can invite to play the game
public function load_invitable_friends()
{
$this->load->library('facebook');
$list = $this->facebook->get_invitable_friends();
var_dump($list);
}
然后通过AJAX调用它,如:
function loadInvites(){
$.post(base+"main/load_invitable_friends/",function(resp){
$('#slide_6_inner').html(resp);
});
}
此次调用后,slide_6_inner
div的内容应包含由var_dump
转储的朋友列表。但是,内容为bool(false)
,表示Facebook会话不再存在。
如果我从if( $this->session )
方法中删除条件get_invitable_friends()
,则会发生以下错误:
A PHP Error was encountered
Severity: 4096
Message: Argument 1 passed to Facebook\FacebookRequest::__construct() must be an instance of Facebook\FacebookSession, null given, called in /home/lights/public_html/appname/application/libraries/facebook/Facebook.php on line 125 and defined
Filename: Facebook/FacebookRequest.php
Line Number: 182
最初使用以下代码创建Facebook.php
中的会话。
$this->ci =& get_instance();
// Initialize the SDK
FacebookSession::setDefaultApplication( $api_id, $api_secret) );
$this->helper = new FacebookCanvasLoginHelper();
$this->session = $this->helper->getSession();
总结一下 - 为什么会出现此问题以及如何解决?
答案 0 :(得分:1)
要从服务器端检索会话,您需要先使用FacebookCanvasLoginHelper
创建会话。此类从POST请求中提供来自Facebook的签名请求,并将其交换为FacebookSession
对象。这应该只在用户登录您的应用程序时才能完成:
$helper = new FacebookCanvasLoginHelper();
try {
$session = $helper->getSession();
} catch (FacebookRequestException $ex) {
// When Facebook returns an error
} catch (\Exception $ex) {
// When validation fails or other local issues
}
if ($session) {
// Store this in your PHP session somewhere:
$token = $session->getToken();
}
此后,您应该使用令牌初始化会话:
$token = //GET THIS FROM SESSION
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication('app-id', 'app-secret');
// If you already have a valid access token:
$session = new FacebookSession($token);
// To validate the session:
try {
$session->validate();
} catch (FacebookRequestException $ex) {
// Session not valid, Graph API returned an exception with the reason.
echo $ex->getMessage();
} catch (\Exception $ex) {
// Graph API returned info, but it may mismatch the current app or have expired.
echo $ex->getMessage();
}
答案 1 :(得分:0)
好吧,如果session不存在,只是返回false,你似乎没有做任何事情。问题出现是因为会话已过期/或不存在,因此您必须验证fbToken并再次设置会话或创建新会话。
您可以创建一个检查用户是否已登录的功能,例如:
function CheckFbUser() {
// Check if existing session exists
if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
// Create new session from saved access_token
$session = new FacebookSession($_SESSION['fb_token']);
// Validate token
try {
if (!$session->validate()) {
$session = null;
}
} catch (Exception $e) {
// Catch any exceptions
$session = null;
}
} else {
// No session
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $e) {
// handle it for facebook exceptions
} catch(Exception $e) {
// handle your php exceptions
}
}
// Check if a session exists
if ( isset( $session ) ) {
// Save the session
$_SESSION['fb_token'] = $session->getToken();
// Create session using saved token or the new one we generated at login
$session = new FacebookSession( $session->getToken() );
// USUALLY, here, people show the Logout Button, or anything alike, but you could it
// to return true, and then continue to run your code.
} else {
// No session
// USUALLY, here, people show the Login Button, or anything alike, you could
// use it to return false, or redirect user to login first.
$helper->getLoginUrl();
}
}
这只是一个简单的代码,用于在运行请求之前检查用户是否已登录。