doctrine2 dql, use setParameter with % wildcard when doing a like comparison
Asked Answered
A

2

30

I want to use the parameter place holder - e.g. ?1 - with the % wild cards. that is, something like: "u.name LIKE %?1%" (though this throws an error). The docs have the following two examples: 1.

// Example - $qb->expr()->like('u.firstname', $qb->expr()->literal('Gui%'))
public function like($x, $y); // Returns Expr\Comparison instance

I do not like this as there is no protection against code injection.

2.

// $qb instanceof QueryBuilder

// example8: QueryBuilder port of: "SELECT u FROM User u WHERE u.id = ?1 OR u.nickname LIKE ?2 ORDER BY u.surname DESC" using QueryBuilder helper methods
$qb->select(array('u')) // string 'u' is converted to array internally
   ->from('User', 'u')
   ->where($qb->expr()->orx(
       $qb->expr()->eq('u.id', '?1'),
       $qb->expr()->like('u.nickname', '?2')
   ))
   ->orderBy('u.surname', 'ASC'));

I do not like this because I need to search for terms within the object's properties - that is, I need the wild cards on either side.

Angadresma answered 20/9, 2010 at 21:38 Comment(0)
O
76

When binding parameters to queries, DQL pretty much works exactly like PDO (which is what Doctrine2 uses under the hood).

So when using the LIKE statement, PDO treats both the keyword and the % wildcards as a single token. You cannot add the wildcards next to the placeholder. You must append them to the string when you bind the params.

$qb->expr()->like('u.nickname', '?2')
$qb->getQuery()->setParameter(2, '%' . $value . '%');

See this comment in the PHP manual.

Ostia answered 21/9, 2010 at 15:42 Comment(3)
what happen if $value = '\\'?Agave
Is it safe? Should $value be escaped somehow before?Arawakan
@Arawakan No, it is not secure. See my answer.Arms
A
15

The selected answer is wrong. It works, but it is not secure.

You should escape the term that you insert between the percentage signs:

->setParameter(2, '%'.addcslashes($value, '%_').'%')

The percentage sign '%' and the symbol underscore '_' are interpreted as wildcards by LIKE. If they're not escaped properly, an attacker might construct arbirtarily complex queries that can cause a denial of service attack. Also, it might be possible for the attacker to get search results he is not supposed to get. A more detailed description of attack scenarios can be found here: https://mcmap.net/q/302344/-how-to-escape-like-var-with-doctrine

Arms answered 31/12, 2017 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.