2011-10-30 53 views
2

我目前是CakePHP的初学者,并且玩过CakePHP 1.3,但最近CakePHP 2.0已经发布。CakePHP 2.0 Object not Array

到目前为止,我喜欢它,但唯一令人痛苦的事实是,它不返回对象,而只是返回数组。我的意思是,不得不做$ post ['Post'] ['id']。这是(在我看来)做$ post-> id更实用。

现在谷歌之后,我偶然发现了this链接,但是这会导致在使用Form类时没有定义索引的错误(猜测这是因为它获得了对象化版本而不是阵列版本)。

我下面的博客教程(已经在1.3跟随它却又在它去为2.0)

所以任何人都知道如何没有它使用Form类的干扰来实现这一目标?

Hosh

回答

2

您可以创建额外的对象变量。这样你就不会干扰Cake的automagic,但可以使用如下格式访问数据:$ modelNameObj-> id;格式为

首先,在/ app/Controller中创建一个AppController.php,如果你还没有的话。然后创建一个beforeRender()函数。这将在Cake的标准命名约定中查找数据,并从中创建额外的对象变量。

<?php 
App::uses('Controller', 'Controller'); 

class AppController extends Controller { 

    public function beforeRender() { 

    parent::beforeRender(); 

    // camelcase plural of current model 
    $plural = lcfirst(Inflector::pluralize($this->modelClass)); 

    // create a new object 
    if (!empty($this->viewVars[$plural])) {  
     $objects = Set::map($this->viewVars[$plural]); 
     $this->set($plural . 'Obj', $objects);  
    } 

    // camelcase singular of current model 
    $singular = lcfirst(Inflector::singularize($this->modelClass));  

    // create new object 
    if (!empty($this->viewVars[$singular])) {  
     $object = Set::map($this->viewVars[$singular]); 
     $this->set($singular . 'Obj', $object); 
    } 
    } 
} 

然后在你的意见,你可以访问的对象,像这样:

index.ctp

$productsObj; 

view.ctp

$productObj->id; 

所有我们”重做是添加'Obj't o Cake将已经提供的变量名称。一些示例映射:

产品 - >$ productsObj

ProductType - >$ productTypesObj

我知道这是不是完美的,但它本质上会达到你想要什么,并会在所有可用的模型。

+0

这工作!谢谢!它可能不像你所说的那么完美,但是这样我就可以访问数组和对象版本,如果我以某种方式需要它的话!谢谢 –

0

我也在我的脑海中偶尔跑过这个问题。现在几个基于Cake的应用程序,我看到能够更方便地使用数组来分支和合并(am,in_array等)结果集的好处,而不是使用对象。 $ Post-> id表单将是一个甜蜜的语法糖,但不是对数组的真正好处。

+0

欣赏您的输入,但这并不能真正回答我的问题:/ –

+0

我只是想指出您尝试做错了。关联数组是要走的路。 – sibidiba

0

你可以编写一个函数,在你的公共propertys迭代(见ReflectionClass::getProperties),并将其保存在一个数组(和返回数组)。

如果您有权访问该类,则可以实现ArrayAccess Interface并以数组的方式轻松访问您的对象。

PS:对不起,我从来没有使用CakePHP的,但我认为对象到阵列的转换并不一定是一个框架的具体问题

2

虽然我喜欢这个主意莫兹提出有一些现有的解决这个问题。

我发现最快的一个是https://github.com/kanshin/CakeEntity - 但它看起来像你可能需要重构它的2.x - 甚至可能已经是2.x分支或叉,但我没看。

+0

有一个2。0分支已经使用CakePHP 2.0的文件名约定更新了。 – brism

3

鲜为人知的事实:蛋糕DOES将它们作为对象或井对象的属性返回。阵列是语法糖:

// In your View: 
    debug($this->viewVars); 

Shwoing $this是一个视图对象viewVars属性与来自控制器动作$this->set('key', $variable)$this->set(compact('data', 'for', 'view'))对应。

为了击键而将它们压扁为$Post->id的问题是Cake是为什么。 Cake的设计是一个沉重的举手,所以它的内置ORM是非常强大的,不可避免的,并且用于处理无穷大的无穷大关联表 - 自动回调,自动数据传递,查询生成等。多维数组的底层深度取决于在您的查找方法中,只要您处理多个具有多个关联模型的$ Post,例如,您已经将数组引入混合中,并且没有任何回避。

不同的find方法返回不同深度的数组。从默认生成的控制器代码中,您可以看到该索引使用$this->set('posts', $this->paginate()); - 查看使用$this->set('post', $this->Post->read(null, $id));并且编辑不会使用$this->set并附带Post查找 - 它分配$this->data = $this->Post->read(null, $id);

FWIW,Set::map可能会抛出那些undefined index错误,因为(猜测)你碰巧试图映射编辑动作,amirite?默认情况下,编辑操作仅使用$this->set将相关模型查找设置为视图。 $ this-> read的结果将发送到$this->data。这可能是Set :: map失败的原因。无论哪种方式,你仍然最终瞄准$Post[0]->id$Post->id(取决于你找到的方法你使用),这是没有太大的改善。

这里是集::地图()属性深度的这些行动的一些通用的例子:

// In posts/index.ctp 
    $Post = Set::map($posts); 
    debug($Post); 
    debug($Post[0]->id); 

    // In posts/edit/1 
    debug($this-viewVars); 
    debug($this->data); 

    // In posts/view/1 
    debug($this-viewVars); 
    $Post = Set::map($post); 
    debug($Post->id); 

http://api13.cakephp.org/class/controller#method-Controllerset

http://api13.cakephp.org/class/model#method-Modelread

http://api13.cakephp.org/class/model#method-ModelsaveAll

HTH。