I am currently learning to use the Propel ORM, and I want to reuse a critera for two slightly different queries:
$criteria = ArticleQuery::create()
->filterByIsPublished(true)
->orderByPublishFrom(Criteria::DESC)
->joinWith('Article.Author')
->keepQuery();
$this->news = $criteria
->filterByType('news')
->find();
$this->articles = $critera
->filterByType('article')
->find();
However, this won't work as expected, because now the query for articles will try to find entries where the type is both 'news' and 'article', which of course is impossible.
So we need to get a clone of this object, and what seemed intuitive to me was to simply add the clone keyword inside paranthesis:
$this->news = (clone $criteria)
->filterByType('news')
->find();
Parse error: syntax error, unexpected T_OBJECT_OPERATOR
Instead we have to assign it to a variable before we can use it:
$clonedCritera = clone $criteria;
$this->news = $clonedCriteria
->filterByType('news')
->find();
You have the same behaviour with the new
operator. I see the propel developers have circumvented this limitation by replacing:new ArticleQuery()->doOperations()
with ArticleQuery::create()->doOperations()
.
Why did the PHP language designers choose to do it this way? If you could use the result of these expressions directly, it would make the code more fluent and, in some cases, easier to read.
Why must we assign a clone to a new variable?
Unfortunately, the answer is that the developers haven't gotten around to supporting direct dereferencing on objects returned via clone yet.
In PHP 4, you couldn't "dereference" any objects returned by method. You had to assign it to a dummy variable first.
In the next version of PHP, array dereferencing is to be supported.
So, it's clear that the dev team incrementally adds such features on their timetable.
The best I can tell you is to request this functionality from the dev team.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With