Laravel: Escape "LIKE" clause?
The other answer forgets about escaping the escape character itself, here is a more robust solution:
/** * Escape special characters for a LIKE query. * * @param string $value * @param string $char * * @return string */function escape_like(string $value, string $char = '\\'): string{ return str_replace( [$char, '%', '_'], [$char.$char, $char.'%', $char.'_'], $value );}
Temporary solution:
$search = Input::query('sSearch', '');if($search !== '') { $escSearch = Util::escapeLike($search); $paginatedBookings->where('first_name', 'LIKE', '%' . $escSearch . '%'); $paginatedBookings->orWhere('last_name', 'LIKE', '%' . $escSearch . '%');}class Util { public static function escapeLike($str) { return str_replace(['\\', '%', '_'], ['\\\\', '\%', '\_'], $str); }}
I was hoping for something database-agnostic and more robust. I think you can change the escape char in MySQL, although I don't know why you would.
This problem occurs especially when we want to query on a polymorphic related table.As an example, I wanted to find a column value named App\Example\Files
by querying with like
. But it failed because of the backslash.
While testing, I found that we need "4 backslashes" for the Laravel side and for the mysql side. For the query to work properly.
I also verified this with the toSql () method. As a result, the output of the mysql query was like this and it worked:
select `file` from `examples` where file like '%App\\\\Example\\\\Files%'
I wrote a little helper function to do the backslash correction
before:
DB::table('examples') ->select('file') ->whereRaw("state like '%App\Example\Files%'") ->toSql();
incorrect output:
select `file` from `examples` where file like '%App\Example\Files%'
after
function handle_backslash($value) :string { return str_replace('\\', '\\\\\\\\', $value);}DB::table('examples') ->select('file') ->whereRaw("file like '%" . handle_backslash('App\Example\Files') . "%'") ->toSql();
correct output:
select `file` from `examples` where file like '%App\\\\Example\\\\Files%'