新的FacebookSDK4抛出关于在laravel中活动的PHP会话的异常
我想在我的项目laravel上实现新的facebook API V4.0.0 设置访问我的应用程序所需的所有信息和凭据,何时调用登录功能:新的FacebookSDK4抛出关于在laravel中活动的PHP会话的异常,facebook,laravel-4,facebook-php-sdk,Facebook,Laravel 4,Facebook Php Sdk,我想在我的项目laravel上实现新的facebook API V4.0.0 设置访问我的应用程序所需的所有信息和凭据,何时调用登录功能: $helper = new FacebookRedirectLoginHelper('http://mywebsite.dev'); $loginUrl = $helper->getLoginUrl(); 这给了我一个例外 FaceBookSDK异常“会话未激活,无法存储状态。” 因此,我在这一行深入研究了facebook的SDK类,其中有一个关于会
$helper = new FacebookRedirectLoginHelper('http://mywebsite.dev');
$loginUrl = $helper->getLoginUrl();
这给了我一个例外
FaceBookSDK异常“会话未激活,无法存储状态。”
因此,我在这一行深入研究了facebook的SDK类,其中有一个关于会话的检查:
if (session_status() !== PHP_SESSION_ACTIVE) {
throw new FacebookSDKException(
'Session not active, could not store state.'
);
}
然后我不知道为什么会发生这种情况,所以我试着在一条干净的路线上做同样的检查,看看结果如何
Route::get('test',function() {
if (session_status() !== PHP_SESSION_ACTIVE)
{
return "is not active";
}
return "is active";
});
并且它返回
未激活
为什么会发生这种情况?这样,我就无法将新的facebook API用于laravel?会话状态功能在(PHP>=5.4.0)版本上可用。因此,如果您使用的是旧版本的PHP,请更新它或只是
// change this
if (session_status() !== PHP_SESSION_ACTIVE) {
throw new FacebookSDKException(
'Session not active, could not store state.'
);
}
//into this
if(session_id() === "") {
throw new FacebookSDKException(
'Session not active, could not load state.'
);
}
要解决问题,请调用
session\u启动php函数,然后将facebook重定向登录服务器初始化如下:
会话_start()
$helper=新的FacebookRedirectLoginHelper(“”)
$loginUrl=$helper->getLoginUrl()
我解决了扩展该类和覆盖以下两个需要本机会话的方法的问题
protected function storeState($state)
{
Session::put('facebook.state', $state);
}
protected function loadState()
{
return $this->state = Session::get('facebook.state');
}
我使用Composer执行以下步骤,但遇到了“会话未激活,无法存储状态”的问题,因此会话_start()修复了我的问题
require_once './vendor/autoload.php';
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
session_start();
FacebookSession::setDefaultApplication('apid', 'appscret');
$helper = new FacebookRedirectLoginHelper("callbackurl", $apiVersion = NULL);
try {
$session = $helper->getSessionFromRedirect();
} catch (FacebookRequestException $ex) {
// When Facebook returns an error
} catch (\Exception $ex) {
// When validation fails or other local issues
}
if (isset($session)) {
$request = new FacebookRequest($session, 'GET', '/me');
$response = $request->execute();
$graphObject = $response->getGraphObject();
var_dump($graphObject);
} else {
echo '<a href="' . $helper->getLoginUrl() . '">Login with Facebook</a>';
}
require_once./vendor/autoload.php';
使用Facebook\FacebookSession;
使用Facebook\FacebookRedirectLoginHelper;
使用Facebook\FacebookRequest;
会话_start();
FacebookSession::setDefaultApplication('apid','appscret');
$helper=new FacebookRedirectLoginHelper(“callbackurl”,$apiVersion=NULL);
试一试{
$session=$helper->getSessionFromRedirect();
}捕获(FacebookRequestException$ex){
//当Facebook返回错误时
}捕获(\Exception$ex){
//验证失败或其他本地问题时
}
国际单项体育联合会(isset($届会)){
$request=newfacebookrequest($session,'GET','/me');
$response=$request->execute();
$graphObject=$response->getGraphObject();
var_dump($graphObject);
}否则{
回声';
}
分享我是如何在Laravel 4上实现Facebook SDK V4的
下面是我在default composer.json上添加的内容
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4" : {
"Facebook\\":"vendor/facebook/php-sdk-v4/src/Facebook/"
}
},
在my index.php上添加了Facebook初始化,如下所示:
/*
|--------------------------------------------------------------------------
| Initialized Facebook PHP SDK V4
|--------------------------------------------------------------------------
|
*/
//Initialize
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication(Config::get('facebook.AppId'),Config::get('facebook.AppSecret'));
对于会话,Laravel不使用$\u Session,因此您根本不需要执行Session\u start。为了能够在Facebook PHP SDK V4上使用Laravel会话,需要扩展Facebook的FacebookRedirectLoginHelper类。
下面介绍如何将FacebookRedirectLoginHelper子类化并覆盖会话处理
class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{
protected function storeState($state)
{
Session::put('state', $state);
}
protected function loadState()
{
$this->state = Session::get('state');
return $this->state;
}
protected function isValidRedirect()
{
return $this->getCode() && Input::has('state')
&& Input::get('state') == $this->state;
}
protected function getCode()
{
return Input::has('code') ? Input::get('code') : null;
}
//Fix for state value from Auth redirect not equal to session stored state value
//Get FacebookSession via User access token from code
public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
{
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
return $params;
}
}
还有一步,您需要执行composer命令来重新生成自动加载的文件:
composer dump-autoload -o
好的,如果一切顺利,现在就可以开始使用SDK了,下面是一个示例
以下是我的一个项目课程的摘录:
namespace Fb\Insights;
//Facebook Classes
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\FacebookSDKException;
//Our Facebook Controller
use FbController;
class PagePosts extends \Facebook\GraphObject {
/*
Get Page Posts Impression
https://developers.facebook.com/docs/graph-api/reference/v2.0/insights#post_impressions
*/
public static function getPagePostsImpressions($postid = null) {
$fbctrl = new FbController();
$metricNames = array(
'post_impressions',
'post_impressions_unique',
'post_impressions_paid',
'post_impressions_paid_unique',
'post_impressions_fan',
'post_impressions_fan_unique',
'post_impressions_fan_paid',
'post_impressions_fan_paid_unique',
'post_impressions_organic',
'post_impressions_organic_unique',
'post_impressions_viral',
'post_impressions_viral_unique',
'post_impressions_by_story_type',
'post_impressions_by_story_type_unique',
'post_impressions_by_paid_non_paid',
'post_impressions_by_paid_non_paid_unique'
);
$postsInsights = array();
$batch = array();
$limit = $fbctrl->FacebookGraphDateLimit();
//craft our batch API call
for($i=0; $i<count($metricNames); $i++) {
$batch[] = json_encode(array('method' => 'GET','relative_url' => $postid . '/insights/' . $metricNames[$i] . '?since=' . $limit['since'] . '&until=' . $limit['until'] ));
}
$params = array( 'batch' => '[' . implode(',',$batch ) . ']' );
$session = new FacebookSession($fbctrl->userAccessToken);
try {
$res = (new FacebookRequest($session,'POST','/',$params))
->execute()
->getGraphObject();
} catch(FacebookRequestException $ex) {
//log this error
echo $ex->getMessage();
} catch(\Exception $ex) {
//log this error
echo $ex->getMessage();
}
//Collect data
for($i=0; $i<count($batch); $i++) {
$resdata = json_decode(json_encode($res->asArray()[$i]),true);
$fbctrl->batchErrorDataChecker($resdata,$postsInsights,$metricNames[$i]);
}
return $postsInsights;
}
namespace Fb\Insights;
//Facebook课程
使用Facebook\FacebookSession;
使用Facebook\FacebookRequest;
使用Facebook\FacebookSDKException;
//我们的Facebook控制器
使用FBC控制器;
类PagePosts扩展\Facebook\GraphObject{
/*
获得页面帖子的印象
https://developers.facebook.com/docs/graph-api/reference/v2.0/insights#post_impressions
*/
公共静态函数getPagePostsImpressions($postid=null){
$fbctrl=新的FbController();
$metricNames=数组(
“后期印象”,
“post_impressions_unique”,
“支付后印象”,
“后印象、付费、独特”,
“后印象”,
“博士后印象”\u fan\u独特”,
“后印象费”,
“后印象、粉丝、付费、独一无二”,
“后印象有机”,
“post_impressions_organic_unique”,
“印象后病毒性传播”,
“后印象、病毒、独特”,
“按故事类型发布印象”,
“按故事类型发布印象”,
“由付费或非付费发布的印象”,
“post_impressions_by_paid_non_paid_unique”
);
$postsInsights=array();
$batch=array();
$limit=$fbctrl->FacebookGraphDateLimit();
//精心设计我们的批处理API调用
对于($i=0;$i'GET','relative_url'=>$postid./insights/'.$metricNames[$i].?自='.$limit['since'..&until='.$limit['until']);
}
$params=array('batch'=>'['.内爆(',',$batch)。']');
$session=newfacebooksession($fbctrl->userAccessToken);
试一试{
$res=(新的facebook请求($session、'POST'、'/'、$params))
->执行()
->getGraphObject();
}捕获(FacebookRequestException$ex){
//记录此错误
echo$ex->getMessage();
}捕获(\Exception$ex){
//记录此错误
echo$ex->getMessage();
}
//收集数据
对于($i=0;$iasArray()[$i]),为true);
$fbctrl->batchErrorDataChecker($resdata、$postsInsights、$metricNames[$i]);
}
返回$postsInsights;
}
请随意评论或建议,这样我也可以改进我的代码。
快乐的编码。不久前,kaixersoft的回答确实拯救了我的生命,我通过使用自定义的LaravelFacebookRedirectLoginHelper类按照他的指示完成了所有工作。但今天我去做了一个“作曲家更新”,不知什么原因,它打破了一切。我修改了kaixersoft的LaravelFacebookRedirectLoginHelper类,使其现在可以工作,特别是IsValidDirect方法。以下是更新的类:
class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{
protected function storeState($state)
{
Session::put('state', $state);
}
protected function loadState()
{
$this->state = Session::get('state');
return $this->state;
}
protected function isValidRedirect()
{
$savedState = $this->loadState();
if (!$this->getCode() || !isset($_GET['state'])) {
return false;
}
$givenState = $_GET['state'];
$savedLen = mb_strlen($savedState);
$givenLen = mb_strlen($givenState);
if ($savedLen !== $givenLen) {
return false;
}
$result = 0;
for ($i = 0; $i < $savedLen; $i++) {
$result |= ord($savedState[$i]) ^ ord($givenState[$i]);
}
return $result === 0;
}
protected function getCode()
{
return Input::has('code') ? Input::get('code') : null;
}
//Fix for state value from Auth redirect not equal to session stored state value
//Get FacebookSession via User access token from code
public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
{
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
return $params;
}
}
class LaravelFacebookRedirectLoginHelper扩展\Facebook\FacebookRedirectLoginHelper
{
受保护的函数storeState($state)
{
会话::put('state',$state);
}
受保护的函数loadState()
{
$this->state=Session::get('state');
返回$this->state;
}
受保护的函数isValidDirect()