Конструктор запросов Laravel, selectRaw или select and raw

Какая разница между:

DB::table('some_table')
->selectRaw('COUNT(*) AS result')
->get();

а также:

DB::select(DB::raw(" 
SELECT COUNT(*) AS result
FROM some_table"));

В документации https://laravel.com/docs/5.6/queries говорится об использовании raw()due SQL-инъекция, а с selectRaw то же самое?


person pmiranda    schedule 17.05.2018    source источник
comment
Да это то же самое   -  person Adnan Mumtaz    schedule 17.05.2018
comment
Обратите внимание, что DB::select уже принимает необработанную строку запроса SQL, поэтому внутренний DB::raw во втором примере не нужен и фактически испортит такие вещи, как ведение журнала запросов.   -  person hackel    schedule 07.10.2020


Ответы (2)


Конечный результат у обоих одинаковый, но есть некоторая разница:

Первый:

DB::table('some_table')
    ->selectRaw('COUNT(*) AS result')
    ->get();
  • Возвращает коллекцию объектов PHP,
  • Вы можете плавно вызвать метод коллекций по результату
  • Это чище.

Пока второй:

DB::select(DB::raw(" 
    SELECT COUNT(*) AS result
    FROM some_table"
));
  • Возвращает массив объекта Php.

Хотя у них есть сходство: необработанная строка запроса.

person Oluwatobi Samuel Omisakin    schedule 17.05.2018
comment
Я выбрал этот вариант как правильный, потому что мой вопрос заключался в том, что разница между ними больше, чем в части SQL-инъекции. Спасибо. - person pmiranda; 17.05.2018

Эти два примера дают один и тот же результат, хотя и с разными типами данных.

Использование необработанных запросов действительно может быть вектором атаки, если вы не избегаете значений, используемых в запросе (особенно тех, которые поступают из пользовательского ввода).

Однако это можно очень легко уменьшить, используя привязки, передаваемые в качестве второго параметра любого метода необработанного запроса, как показано в та же документация (selectRaw принимает второй параметр как массив привязок, а также другие необработанные методы из построителя запросов, такие как whereRaw и т. д.). Фактически, в начале страницы документации, на которую вы ссылались, во втором абзаце также говорится следующее:

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

Поэтому, если вы будете осторожны и убедитесь, что все параметры передаются как привязки, а не конкатенируются как простые значения в необработанной строке запроса, вы должны быть в безопасности.

person Bogdan    schedule 17.05.2018
comment
просто интересно - DB::raw не принимает второй параметр - откуда вы взяли эту информацию? Я знаю только selectRaw - этот действительно принимает привязки и действует как приложение. - person jave.web; 10.07.2019
comment
@ jave.web Вы абсолютно правы. DB::raw не принимает второй параметр, так как его основная цель - вернуть запрос Expression, чтобы построитель запросов мог определить, когда параметр следует экранировать, в зависимости от того, является ли он выражением или другим типом данных. Это была моя ошибка. Спасибо, что указали на ошибку, я обновил ответ. - person Bogdan; 10.07.2019