2011-10-02 86 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

相关问题