将 QueryBuilder 与表达式一起使用时出现语义错误
Semantical error when using QueryBuilder with an expression
我在使用 expr()
方法函数从数据库中获取数据时遇到问题。我想获取 isPublic = true
和 objectType = $objectType
或 user = $user
和 objectType = $objectType
、 的数据,无论 isPublic
的值是什么.
我收到这个错误:
[Semantical Error] line 0, col 76 near 'user-avatar)': Error: 'user' is not defined.
我在存储库中的代码:
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();
}
其中:$objectType = 'user-avatar'; $user = UserInterface
使用 $qb->expr()->eq()
时,您需要为查询提供准确的值。在这种情况下,您需要将查询更改为如下内容:
$qb->expr()->eq('s.objectType', '"' . $objectType .'"')
这种字符串将在数据库查询中被正确引用。顺便说一句,布尔值也是如此。将 true
转换为字符串将导致 1
。这就是为什么您在这种情况下没有遇到错误。 false
但是会转换为空字符串,这会导致错误。
为了更好地理解发生了什么,下面是将 eq()
表达式转换为查询的代码部分:
/**
* @return string
*/
public function __toString()
{
return $this->leftExpr . ' ' . $this->operator . ' ' . $this->rightExpr;
}
expr()->eq()
会将表达式视为文字,尝试按字面意义使用它们,因为它们出现在方法调用中。
作为 mentioned 库作者:
You are not using parameter binding. Expressions use string concatenation internally, so this outcome is actually expected.
在你的情况下,你应该做类似::
的事情
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();
这样您的代码更易于阅读、更安全、更便携。
我在使用 expr()
方法函数从数据库中获取数据时遇到问题。我想获取 isPublic = true
和 objectType = $objectType
或 user = $user
和 objectType = $objectType
、 的数据,无论 isPublic
的值是什么.
我收到这个错误:
[Semantical Error] line 0, col 76 near 'user-avatar)': Error: 'user' is not defined.
我在存储库中的代码:
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();
}
其中:$objectType = 'user-avatar'; $user = UserInterface
使用 $qb->expr()->eq()
时,您需要为查询提供准确的值。在这种情况下,您需要将查询更改为如下内容:
$qb->expr()->eq('s.objectType', '"' . $objectType .'"')
这种字符串将在数据库查询中被正确引用。顺便说一句,布尔值也是如此。将 true
转换为字符串将导致 1
。这就是为什么您在这种情况下没有遇到错误。 false
但是会转换为空字符串,这会导致错误。
为了更好地理解发生了什么,下面是将 eq()
表达式转换为查询的代码部分:
/**
* @return string
*/
public function __toString()
{
return $this->leftExpr . ' ' . $this->operator . ' ' . $this->rightExpr;
}
expr()->eq()
会将表达式视为文字,尝试按字面意义使用它们,因为它们出现在方法调用中。
作为 mentioned 库作者:
You are not using parameter binding. Expressions use string concatenation internally, so this outcome is actually expected.
在你的情况下,你应该做类似::
的事情 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();
这样您的代码更易于阅读、更安全、更便携。