用LIKE进行Doctrine 2查询

AlO*_*l19 40 sql symfony doctrine-orm

我有这个代码用于查询:

$repository = $em->getRepository('AcmeCrawlerBundle:Trainings');
       $query = $repository->createQueryBuilder('p')
               ->where('p.title LIKE :word')
               ->orWhere('p.discription LIKE :word')
               ->setParameter('word', $word)
               ->getQuery();
$trainings = $query->getResult();
Run Code Online (Sandbox Code Playgroud)

问题是:即使存在匹配项,此查询也找不到它们.我用这段代码来查看完整的sql:

print_r(array(
        'sql'        => $query->getSQL(),
        'parameters' => $query->getParameters(),
        ));
Run Code Online (Sandbox Code Playgroud)

我得到了什么:

FROM Trainings t0_ WHERE t0_.title LIKE ? OR t0_.discription LIKE ? [parameters] => Array ( [word] => Spoken ) 
Run Code Online (Sandbox Code Playgroud)

(查询的最后一部分)请告诉我要改变什么?

Eln*_*mov 90

你忘了%这个词周围的标志:

->setParameter('word', '%'.$word.'%')
Run Code Online (Sandbox Code Playgroud)

  • @baquiax它是安全的,因为参数在准备语句时被转义. (8认同)

rob*_*ert 15

选择的答案是错误的。它可以工作,但是并不安全

您应避免在百分号之间插入的术语:

->setParameter('word', '%'.addcslashes($word, '%_').'%')
Run Code Online (Sandbox Code Playgroud)

百分号'%'和下划线符号'_'被解释为通配符LIKE。如果他们不正确转义,攻击者可能构造arbirtarily复杂的查询,可能会导致服务拒绝攻击。同样,攻击者可能会获得他不应该获得的搜索结果。攻击场景更详细的描述可以在这里找到:/sf/answers/552556931/

  • 拜托了伙计们。查看我在答案中链接的stackoverflow帖子。简而言之:setParameter魔术可以防止SQL注入,但不能防止通配符注入。我想指出的是,我本人实际上已经对此进行了测试,并且所有测试都是正确的。我们没有弥补。如果不手动转义%和_,它们将被解释为通配符。同样:setParameter可以防止SQL注入,但不能防止这种通配符注入。 (7认同)
  • 接受的答案使用查询构建器的方式导致生成的 SQL 使用*准备好的语句*,这意味着答案既不是“错误”也不是“不安全”。我会说_this_答案是错误的。 (3认同)