新的FacebookSDK4抛出关于在laravel中活动的PHP会话的异常

新的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类,其中有一个关于会

我想在我的项目laravel上实现新的facebook API V4.0.0

设置访问我的应用程序所需的所有信息和凭据,何时调用登录功能:

$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()