我目前是CakePHP的初学者,并且玩过CakePHP 1.3,但最近CakePHP 2.0已经发布。
到目前为止,我喜欢它,但唯一的事情是一个痛苦的事实是,它不返回对象,而只是返回数组。我的意思是,$post[' post ']['id']几乎没有意义。它是(在我看来)更实际的只是做$post->id。现在在谷歌我偶然发现了这个链接,然而,这一直产生错误的索引没有被定义时,使用Form类(猜测这是因为它得到的是物化版本,而不是数组版本)。
我遵循博客教程(已经遵循了1.3版本,但在2.0版本中又重复了一遍)
所以,谁知道如何实现这一点,而不干扰表单类?
Hosh
鲜为人知的事实:Cake确实将它们作为对象返回,或者作为对象的属性返回。数组是语法糖:
// In your View:
debug($this->viewVars);
Shwoing $this
是View对象, viewVars
属性对应控制器动作的$this->set('key', $variable)
或$this->set(compact('data', 'for', 'view'))
。
为了击键而将它们压入$Post->id
的问题是Cake是为什么。Cake被设计成一个沉重的提升器,所以它的内置ORM非常强大,不可避免,用于处理无限关联表的无限行——自动回调、自动数据传递、查询生成等。多维数组的基本深度取决于您的find方法,一旦您使用多个具有多个相关模型的$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);
。
fww, Set::map
可能抛出那些undefined index
错误,因为(猜测)你碰巧试图映射一个编辑动作,不是吗?默认情况下,编辑操作只使用$this->set
来设置与视图相关的模型查找。$this->read的结果被发送给$this->data
。这可能就是Set::map失败的原因。无论哪种方式,您仍然将最终瞄准$Post[0]->id
或$Post->id
(取决于您使用的方法),这并不是很大的改进。
下面是Set::map()属性深度的一些通用示例:
// 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 .
您可以创建额外的对象变量。这样,您就不会干扰Cake的自动操作,但可以使用像$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'添加到Cake已经提供的变量名中。一些映射示例:
Products -> $productsObj
ProductType -> $productTypesObj
我知道这不是完美的,但它基本上可以达到你想要的效果,并且可以在你所有的模型中使用。
虽然我喜欢Moz提出的想法,但对于这个问题有许多现有的解决方案。
我发现最快的一个是https://github.com/kanshin/CakeEntity -但看起来你可能需要重构它为2。X,可能已经有一个2了。
这个问题我也在脑子里想了好几次。现在一些基于Cake的应用程序之后,我看到了能够分支和合并(am, in_array等)结果集的好处,数组比使用对象更方便。$Post->id形式是一个很好的语法糖,但与数组相比并没有真正的好处。
您可以编写一个函数,迭代您的公共属性(参见ReflectionClass::getProperties),并将其保存在数组中(并返回该数组)。
如果你可以访问该类,你可以实现ArrayAccess接口,并轻松地将对象作为数组访问。
注::对不起,我从来没有使用过CakePHP,但我认为对象到数组的转换不一定是框架特定的问题