Cakephp:appController中的变量数据在Xcontroller子级中不一致


Cakephp: variable data in appController is not consistent in Xcontroller child

我使用的是Cakephp(2.X)框架。

我创建了一个facebook画布应用程序。我把我的facebook对象作为appController中的一个变量。我在构造函数中实例化它。在我的usersController中,我正在尝试使用这个对象。对象就在那里,尽管不是facebook对象中的所有数据都是持久的。

例如,如果我在appController中var dump facebook对象,则所有属性都存在。当我在另一个控制器中转储facebook对象时,一些属性为空/0/不存在。例如"user"、"signedRequest"answers"accessToken"。

目前我的文件是这样的:


appController.php

class AppController extends AppController {
    public $facebook;
    //other vars here
    function __construct($request = null, $response = null) {
        parent::__construct($request, $response);
        App::import('Vendor','fb/src/facebook');
        ...
        $this->facebook = new Facebook(//array with appId and Secret);
        // doing stuff here with $this->facebook
    }           
   //other methods

并且在这个类中的每个方法中都完全定义了facebook对象


UsersController.php

class UsersController extends Controller {
    //some functions
    function useParentsFBvar(){
        //I have tried
        $this->facebook;
        //and I have tried
        parent::facebook;
    }

以上两个都不是完全定义的facebook对象。特别是"user"、"signedRequest"answers"accessToken"。

我甚至尝试在appController中实现一个函数,并从我的UsersController 调用

function getFB() {
    return $this->facebook;
}

但我也有同样的问题。

有什么明显的事情表明我做错了吗?

哦,这是我的第一个问题,我对cakepp和PHP很陌生,所以请对我宽容一点。

如果你需要任何其他信息,请告诉我。我搜索了类似的问题,但没有找到合适的。。。如果这是重复的话,很抱歉。

------------------------编辑--------------------------

这就是我所做的,让它按我想要的方式工作。我做事的原因有人能确认这是否打破了任何模式,或者这是否是可以接受的MVC吗

我所做的是将appController中的facebook对象转换为静态成员。然后,我在检查它是否已经是新的之后,在构造函数中新建它。如果它已经是新的,我什么都不做。一旦我做了这个更改,它就在UsersController中创建了facebook对象。

    <               appController.php      >
App::uses('Controller', 'Controller');
App::import('Vendor','fb/src/facebook');    
class AppController extends Controller {
    public static $facebook = null;
    //other members, components and helpers

    function __construct($request = null, $response = null){
        parent::__construct($request,$response);
        //load the configurations for app
        if(!static::$facebook){
            static::$facebook = new Facebook(
                                array('appId' => $this->app_id,
                                        'secret' => $this->secret,
                                        'cookie'=> true));
        }
      }
      function beforeFilter() {
          //get the user and do some things with static::facebook
      }

然后在UserController.php$this->facebook中给了我一个有效的对象。一旦我完成了这项工作,我认为将逻辑转移到用户模型中是有意义的,所以我创建了一个模型函数来返回使用该应用程序的X个朋友。

    <---------------UsersController.php------------------>
class UsersController extends AppController {
    public $name = 'Users';
    public function friends($count = 5) {
        $this->set('friends', $this->User->getFriendsUsingApp($this->facebook, $count));
    }
}

    <-------------------User.php--------------------------->
class User extends AppModel {
    public function getFriendsUsingApp($facebook, $max = 5) {
        $installedFriends = array();
        try {
            $installedFriends = $facebook->api('/me/friends?fields=installed');
        } catch (FacebookApiException $e) {
            $this->log($e->getMessage());
        }
        //search through the array of all returned friends and search for "ionstalled" field
        $friends = array();
        foreach ($installedFriends['data'] as $friend) {
            if (array_key_exists('installed',$friend) && $friend['installed']) {
                $friends[] = $friend;
            }
        }
        return $friends;
    }
}

这一直很好,我觉得通过将更多的逻辑移动到模型中来遵守MVC(尽管不确定),请告诉我我是否正确。

我认为问题是,当appController首次构建时,它会创建一个新的facebook对象(包含所有有效数据[accessToken和user])。然后,当我的userController实例被构建时,一个新的appController被构建,从而创建了另一个新facebook对象。不知怎的,当对新Facebook(…)的第二次调用被调用时,它返回了某种类型的仅部分有效的对象(appId和secret现在都是数组,并且没有accessToken或User。所以我将Facebook设为静态,现在所有控制器都共享Facebook对象的同一副本。

<-----facebook object dumped in AppController--------->
(
    [appId:protected] => //appId//
    [appSecret:protected] => //secret//
    [user:protected] => //an actual userID//
    [signedRequest:protected] => 
    [state:protected] => //state//
    [accessToken:protected] => //an actual accessToken//
    [fileUploadSupport:protected] => 
)   
<-----facebook object on dump in UsersController--------->
(
    [appId:protected] => array(
                                [0] => //appId//
                                [1] => //appId//
                               )
    [appSecret:protected] => array(
                                [0] => //secret//
                                [1] => //secret//
                               )
    [user:protected] => array|array
    [signedRequest:protected] => 
    [state:protected] => //state//
    [accessToken:protected] => array|array -//though sometimes just blank
    [fileUploadSupport:protected] => 
)

希望这是有道理的。

试试这个:

App::uses('Controller', 'Controller');
// facebook
App::import('Vendor', 'facebook/facebook');
class AppController extends Controller {
    public $facebook;
    public function beforeFilter() {
        $o = array('appId' => '__APP_ID__', 'secret' => '__APP_SECRET__');
        $this->facebook = new Facebook($o);
        // Do stuff with facebook instance here
        // $uid = $this->facebook->getUser();
        // To make instance available in view files
        $this->set('facebook', $this->facebook);
    }
}

beforeFilter方法get在执行任何操作之前被调用。

确保你的facebook课程在/App/Vendor/fiacebook文件夹中。

Facebook实例现在应该可以在任何控制器中通过$this->Facebook访问。如果您在另一个控制器中使用beforeFilter方法,请确保调用

parent::beforeFilter();

此外,您的用户控制器应该如下所示:

class UsersController extends AppController {
    public $name = 'Users';
    public function index() {
        $uid = $this->facebook->getUser();
    }
}

祝好运