下面是我有的代码摘录
$column_name = "ipAddress";
$qb = EntityManagerContainer::get()->createQueryBuilder();
$qb->select('u')
->from(BlacklistedIps::class, 'u');
if($search_term)
{
$clause = $qb->expr()->like("u.".$column_name, "'%$search_term%'");
$qb->where($clause);
}
$query = $qb->getQuery();
$result = $query->getResult();
它工作得非常好(尽管它对SQL注入开放,但那是另一回事)。
我的问题是需要"'%$search_term%'"
。如果没有这组额外的单引号,查询将失败
未捕获异常"Doctrine\ORM\Query\QueryException",带有消息'从Orm\Entity\BlacklistedIps u WHERE u.ipAddress LIKE中选择u%123%ORDER BY u.reason desc'in***
我不完全确定我的做法是否正确。因为如果我这样做了,那么Doctrine2中就有一个bug(mssing功能?)。当我做时
$qb->expr()->like("u.".$column_name, "%$search_term%");
那么我绝对确信我在处理一根绳子。当整数、布尔值或浮点值等相互比较时,会使用不同的运算符,但绝对不是LIKE。LIKE仅在处理字符串时使用,因此在DQL中引用字符串是唯一可能的->LIKE方法用例。
请告诉我我做错了什么。我只使用Doctrine2几天了,对它很着迷。但我不喜欢字符串不能自动引用。
这看起来像是如何使用querybuilder的问题。你应该这样做:
$qb ->where($qb->expr()->orX($qb->expr()->like('u.'.$column_name, $qb->expr()->literal("%$searchTerm%"))))
或
$qb->where($qb->expr()->like("u.".$column_name, array("%$searchTerm%")));
同样为了避免sql注入,一个好的做法是不在任何querybuilder方法中传递用户输入,使用setParameter与?或者:相反。
$qb->where('u.'.$column_name.' LIKE :searchTerm')
$qb->setParameter('searchTerm', '%'.$searchTerm.'%')
或者类似的东西:
$qb->expr()->like('u.'.$column_name, '?1')
$qb->getQuery()->setParameter(1, '%' . $searchTerm . '%');
注意以下内容:
-
我如何分解查询以提高数据库的安全性。
-
我在构建的整个查询中使用了"andWhere">
-
我是如何将已执行查询的值分配给$result 的
public function findPending($id) { $qb = $this->createQueryBuilder('o') ->addSelect('s') ->leftJoin('MyApp\Model\Entity\Shipment', 's') ->orderBy('o.date_sent', 'DESC'); // Order has been sent and was not cancelled $qb ->andWhere($qb->expr()->andX( $qb->expr()->eq('o.date_cancelled','0000-00-00 00:00:00'), $qb->expr()->neq('o.date_sent','0000-00-00 00:00:00') )); $qb ->andWhere($qb->expr()->orX( // Order doesn't have a shipment $qb->expr()->isNull('s.order'), // OR Order has a shipment $qb->expr()->orX( // Shipment has not been sent $qb->expr()->eq('s.date_sent','0000-00-00 00:00:00'), // OR Shipment has been sent AND it was cancelled $qb->expr()->andX( $qb->expr()->neq('s.date_sent','0000-00-00 00:00:00'), $qb->expr()->eq('s.date_cancelled','0000-00-00 00:00:00') ) ) )); $qb ->setMaxResults(6); $result = $qb->getQuery() ->getResult(); return $result; }
要查看您创建的查询,请在"$result"之前添加此项
$qb->getQuery():