Исследуйте необработанные SQL-запросы в Laravel 4
Как вы идете об экранировании параметров, переданных в исходный запрос в Laravel 4? Я ожидал чего-то вроде DB::escape()
(который звонит из Laravel 3), а также попытался DB::quote()
(который, как я думал, может быть доступен через объект PDO)
$query = DB::select("SELECT * FROM users WHERE users.id = " . DB::escape($userId));
Мы не можем использовать метод select с заполнителями, поскольку приведенное выше является просто упрощенным примером того, что мы пытаемся достичь. У нас есть большой пользовательский запрос с несколькими вложенными запросами выбора, которые не могут адаптироваться к построителю запросов.
Каков наилучший способ избежать чего-то перед вставкой в Laravel 4?
EDIT:
Я только что обнаружил, что вы можете получить доступ к объекту PDO и использовать здесь функцию quote. Это лучший подход, или есть более простой способ доступа к этой функции?
DB::connection()->getPdo()->quote("string to quote");
Ответы
Ответ 1
Вы можете процитировать ваши строки таким образом, через фасад DB
.
DB::connection()->getPdo()->quote("string to quote");
Я поставил этот ответ в своем вопросе, когда я его обнаружил, однако теперь я ставлю его в качестве фактического ответа, чтобы облегчить поиск других.
Ответ 2
$value = Input::get("userID");
$results = DB::select( DB::raw("SELECT * FROM users WHERE users.id = :value"), array(
'value' => $value,
));
Подробнее ЗДЕСЬ
Ответ 3
Вы также можете попробовать это, (Прочитать документацию)
$results = DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));
Ответ 4
Я нашел этот вопрос, когда искал генерации sql-экранов в Laravel. То, что мне действительно нужно было, это экранирование имени таблицы/столбца. Итак, для справок в будущем:
/**
* Quotes database identifier, e.g. table name or column name.
* For instance:
* tablename -> `tablename`
* @param string $field
* @return string
*/
function db_quote_identifier($field) {
static $grammar = false;
if (!$grammar) {
$grammar = DB::table('x')->getGrammar(); // The table name doesn't matter.
}
return $grammar->wrap($field);
}
Ответ 5
Я использую это в своем helpers.php
в Laravel 5:
if ( ! function_exists('esc_sql'))
{
function esc_sql($string)
{
return app('db')->getPdo()->quote($string);
}
}
Затем я могу использовать функцию esc_sql
, где мне нужно выполнить pergorm escaping для необработанных SQL-запросов.
Ответ 6
Здесь приведен более полный пример, показывающий, как избежать обоих значений и столбцов и расширять конструктор запросов Laravel:
<?php
namespace App\Providers;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;
class DatabaseQueryBuilderMacroProvider extends ServiceProvider {
public function register() {
Builder::macro('whereInSet', function($columnName, $value) {
/** @var \Illuminate\Database\Query\Grammars\Grammar $grammar */
$grammar = $this->getGrammar();
return $this->whereRaw('FIND_IN_SET(?,' . $grammar->wrap($columnName) . ')', [$value]);
});
}
}
Ответ 7
Два ответа здесь, которые я использую, имеют менее подробные решения, встроенные в фасад DB
.
Во-первых, стоимость цитирования:
// From linked answer
DB::connection()->getPdo()->quote("string to quote");
// In the DB facade
DB::getPdo()->quote('string to quote');
Во-вторых, цитирование идентификатора (имена таблиц и столбцов):
// From linked answer
DB::table('x')->getGrammar()->wrap('table.column');
// In the DB facade
DB::getQueryGrammar()->wrap('table.column');