目前我正在学习使用的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语言设计者选择这样做?如果你可以直接使用这些表达式的结果,它会使代码更加流畅,在某些情况下更易于阅读。
Hrm。我想知道我的哪个答案会是最不合适的...... –
为什么?确实是一个很好的问题。 “因为php不是java”是我收到的答案,当我在一些论坛上询问有关“新”的类似解析器问题时。在我看来,PHP解析器有很多这样的缺陷 - 我们只能希望,他们将在未来某一天被修复...... – aurora
@harald我在研究这个时遇到了这个RFC页面,所以它看起来方法实例调用至少正在讨论中的PHP开发人员。 https://wiki.php.net/rfc/instance-method-call – CheeseSucker