新的Facebook SDK 4在laravel中抛出关于PHP_SESSION_ACTIVE的异常

Fab*_*lio 6 facebook facebook-php-sdk laravel-4

我想在我的项目laravel上实现新的facebook API v 4.0.0.

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

$helper = new FacebookRedirectLoginHelper('http://mywebsite.dev');
$loginUrl = $helper->getLoginUrl();
Run Code Online (Sandbox Code Playgroud)

它给我一个例外

FacebookSDKException'会话未激活,无法存储状态.

所以我在那一行深入了解facebook的SDK类,并且有一个关于会话的检查:

 if (session_status() !== PHP_SESSION_ACTIVE) {
      throw new FacebookSDKException(
        'Session not active, could not store state.'
      );
    }
Run Code Online (Sandbox Code Playgroud)

然后我不知道为什么会发生这种情况所以我试着在干净的路线上进行相同的检查并查看结果

Route::get('test',function() {

   if (session_status() !== PHP_SESSION_ACTIVE)
    {
        return "is not active";
    }

    return "is active";

});
Run Code Online (Sandbox Code Playgroud)

它回归is not active为什么会发生这种情况?这样我就不能用laravel使用新的facebook API了?

小智 13

分享我如何在Laravel 4上实现Facebook SDK V4.

这是我在默认的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/"
    }
},
Run Code Online (Sandbox Code Playgroud)

在我的index.php上添加了Facebook初始化,如下所示:

/*
|--------------------------------------------------------------------------
| Initialized Facebook PHP SDK V4
|--------------------------------------------------------------------------
|
*/

//Initialize
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication(Config::get('facebook.AppId'),Config::get('facebook.AppSecret'));
Run Code Online (Sandbox Code Playgroud)

对于Session,Laravel不使用$ _SESSION,因此您根本不需要执行session_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;
   }


}
Run Code Online (Sandbox Code Playgroud)

还有一步,您需要执行composer命令来重新生成自动加载文件:

composer dump-autoload -o
Run Code Online (Sandbox Code Playgroud)

好的,如果一切正常,您现在可以开始使用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;

    }
Run Code Online (Sandbox Code Playgroud)

随意评论或建议所以我也可以改进我的代码.快乐的编码.


Fab*_*lio 6

我解决了扩展该类并覆盖以下2个需要本机会话的方法的问题.

    protected function storeState($state)
    {
        Session::put('facebook.state', $state);
    }

    protected function loadState()
    {
        return $this->state =  Session::get('facebook.state');
    }
Run Code Online (Sandbox Code Playgroud)