Reputation: 47
I have a problem with getting data from the database using the expr()
method function. I would like to get data where isPublic = true
and objectType = $objectType
OR user = $user
and objectType = $objectType
, no matter what the value of isPublic
is.
I'm getting this error:
[Semantical Error] line 0, col 76 near 'user-avatar)': Error: 'user' is not defined.
My code in repository:
public function findByObjectType($objectType, $user)
{
$qb = $this->createQueryBuilder('s');
return $qb->where($qb->expr()->andX(
$qb->expr()->eq('s.isPublic', true),
$qb->expr()->eq('s.objectType', $objectType)
))
->orWhere($qb->expr()->andX(
$qb->expr()->eq('s.user', $user->getId()),
$qb->expr()->eq('s.objectType', $objectType)
))
->getQuery()
->getResult();
}
where: $objectType = 'user-avatar'; $user = UserInterface
Upvotes: 1
Views: 317
Reputation: 47359
expr()->eq()
will treat the expression as literals, trying to use them literally as they appear on method call.
As mentioned by the library author:
You are not using parameter binding. Expressions use string concatenation internally, so this outcome is actually expected.
In your case, you should be doing something like::
return $qb->where($qb->expr()->andX(
$qb->expr()->eq('s.isPublic', ':true'),
$qb->expr()->eq('s.objectType', ':objectType')
))
->orWhere($qb->expr()->andX(
$qb->expr()->eq('s.user', ':userId'),
$qb->expr()->eq('s.objectType', ':objectType')
))
->setParameter('true', true)
->setParameter('userId', $user->getId())
->setParameter('objectType', $objectType)
->getQuery()
->getResult();
This way your code is easier to read, safer and more portable.
Upvotes: 1
Reputation: 1722
When using $qb->expr()->eq()
you will need supply the exact value for the query. In this case you need to change your query to something like this:
$qb->expr()->eq('s.objectType', '"' . $objectType .'"')
This way to string will be correctly quoted in the db query. The same goes for booleans by the way. Casting true
to a string will result in 1
. That's why you didn't encounter an error in this case. false
however gets cast to an empty string, which would result in an error.
To better understand what's going on, here is the part of code that converts the eq()
expression to the query:
/**
* @return string
*/
public function __toString()
{
return $this->leftExpr . ' ' . $this->operator . ' ' . $this->rightExpr;
}
Upvotes: 0