2011-10-02 88 views
5

目前我正在學習使用的Propel ORM,我想重用性判據兩個稍微不同的查詢:爲什麼我們必須將克隆分配給新變量?

$criteria = ArticleQuery::create() 
     ->filterByIsPublished(true) 
     ->orderByPublishFrom(Criteria::DESC) 
     ->joinWith('Article.Author') 
     ->keepQuery(); 

$this->news = $criteria 
     ->filterByType('news') 
     ->find(); 
$this->articles = $critera 
     ->filterByType('article') 
     ->find(); 

但是,按預期這是不行的,因爲現在的文章查詢將嘗試找到類型既是「新聞」又是「文章」的條目,這當然是不可能的。

因此,我們需要得到這個對象的克隆,和什麼似乎直觀我是簡單地添加內部paranthesis clone關鍵字:

$this->news = (clone $criteria) 
     ->filterByType('news') 
     ->find(); 

Parse error: syntax error, unexpected T_OBJECT_OPERATOR

相反,我們必須把它分配給一個變量,我們才能使用它:

$clonedCritera = clone $criteria; 
$this->news = $clonedCriteria 
     ->filterByType('news') 
     ->find(); 

您與new運算符具有相同的行爲。我看到推進開發者已經通過將
new ArticleQuery()->doOperations()替換爲ArticleQuery::create()->doOperations()來繞過這個限制。

爲什麼PHP語言設計者選擇這樣做?如果你可以直接使用這些表達式的結果,它會使代碼更加流暢,在某些情況下更易於閱讀。

+0

Hrm。我想知道我的哪個答案會是最不合適的...... –

+0

爲什麼?確實是一個很好的問題。 「因爲php不是java」是我收到的答案,當我在一些論壇上詢問有關「新」的類似解析器問題時。在我看來,PHP解析器有很多這樣的缺陷 - 我們只能希望,他們將在未來某一天被修復...... – aurora

+0

@harald我在研究這個時遇到了這個RFC頁面,所以它看起來方法實例調用至少正在討論中的PHP開發人員。 https://wiki.php.net/rfc/instance-method-call – CheeseSucker

回答

4

爲什麼我們必須爲新變量指定一個克隆?

不幸的是,答案是開發人員還沒有開始支持直接解引用通過克隆返回的對象。

在PHP 4中,您不能「取消」任何方法返回的對象。你必須先將它分配給一個虛擬變量。

在下一個版本的PHP中,array dereferencing將被支持。

因此很明顯,開發團隊逐漸將這些功能添加到他們的時間表中。

我可以告訴你的最好的是來自開發團隊的request this functionality

+1

請求發送:https://bugs.php.net/bug.php?id=55833 – CheeseSucker

相關問題