Параметрированное привязка запроса в предложении ON для LEFT JOIN в Laravel Eloquent / Query Builder

Скажем, я хочу показать полный список наград с типом = «цвет»:

Awards Type 2013 Winner ====== ==== =========== Blue Award color Tom Red Award color Green Award color Dan 

Для достижения этого результата у меня мог бы быть запрос в Laravel следующим образом:

 $year = '2013'; $awards = DB::table('awards') ->leftJoin('winners', function($join) use ($year) { $join->on('awards.id','=','winners.award_id'); $join->on('winners.year','=',DB::raw("'".$year."'")); } ->where('awards.type','color') ->get(); 

Если вы выведете SQL, который генерирует Laravel, вы увидите, что только параметр WHERE параметризуется, а $ year в предложении ON остается уязвимым для SQL-инъекции, если я получаю его из ненадежного источника. Кроме того, потенциал кэширования запросов уменьшается, потому что $ year будет часто меняться. Примечание . Если вы думаете, что я просто добавляю второе условие левого соединения к WHERE запроса, это не то же самое .

Любые идеи о том, как получить $ year часть запроса параметризованным?

Вот нечетная работа (не хотелось расширять классы Builder и JoinClause):
Примечание. Это нарушит цепочку запросов с помощью -> так заметьте, where было разделено ниже.

 $query = DB::table('awards') ->leftJoin('winners', function($join) { $join->on('awards.id','=','winners.award_id'); $join->on('winners.year','=',DB::raw('?')); } ->setBindings(array_merge($query->getBindings(),array($year))); $query->where('awards.type','color'); $awards = $query->get(); в $query = DB::table('awards') ->leftJoin('winners', function($join) { $join->on('awards.id','=','winners.award_id'); $join->on('winners.year','=',DB::raw('?')); } ->setBindings(array_merge($query->getBindings(),array($year))); $query->where('awards.type','color'); $awards = $query->get(); 

ОБНОВЛЕНИЕ : Тейлор добавил joinWhere , leftJoinWhere … он говорит, что «если у вас есть функция join just use ->where and ->orWhere from the Closure». Я все же должен попробовать это.

Это происходит прямо из документов Laravel:

В построителе запросов Laravel используется привязка параметров PDO для защиты вашего приложения от атак SQL-инъекций. Нет необходимости чистить строки, передаваемые как привязки.

Вам не нужно санировать его вообще. Это должно быть хорошо. Если вас это беспокоит, вы можете использовать класс Validator чтобы проверить его, как хотите.

В настоящее время вы можете использовать $join->where :

 $year = '2013'; $awards = DB::table('awards') ->leftJoin('winners', function($join) use ($year) { $join ->on('awards.id','=','winners.award_id') // "where" instead of "on": ->where('winners.year', '=', $year); } ->where('awards.type','color') ->get();