2011-10-30 57 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。