在 Laravel 4 中转义原始 SQL 查询
Posted
技术标签:
【中文标题】在 Laravel 4 中转义原始 SQL 查询【英文标题】:Escape raw SQL queries in Laravel 4 【发布时间】:2013-09-27 20:46:39 【问题描述】:如何在 Laravel 4 中转义传递给原始查询的参数?我期待像 DB::escape()
之类的东西(它从 Laravel 3 中敲响了钟声)并且还尝试了 DB::quote()
(我认为可以通过 PDO object 获得)
$query = DB::select("SELECT * FROM users WHERE users.id = " . DB::escape($userId));
我们不能使用带占位符的 select 方法,因为上面只是我们试图实现的一个简化示例。我们有一个大型自定义查询,其中包含一些嵌套的 select 查询,这些查询不能适应查询生成器。
在 Laravel 4 中插入之前转义某些内容的最佳方法是什么?
编辑:
我刚刚发现您可以通过这种方式访问 PDO 对象并在其上使用引用函数。这仍然是最好的方法,还是有更简单的方法来访问此功能?
DB::connection()->getPdo()->quote("string to quote");
【问题讨论】:
谢谢。 +1 包括解决方案(您也可以单独发布它作为答案,并接受它......可以为我们节省一些时间) @J.Bruni,好点子!我现在也将其添加为实际答案,因此应该更容易找到。 【参考方案1】:$value = Input::get("userID");
$results = DB::select( DB::raw("SELECT * FROM users WHERE users.id = :value"), array(
'value' => $value,
));
更多详情HERE
【讨论】:
这并没有回答问题,它表明我不是在寻找带有占位符的解决方案,而是寻找逃避一个变量的适当方法。 @Dwight:没有实际意义。当您转义以将变量值实际编码为 SQL 时,占位符也是如此。 PDO 也是如此。 当心,我在使用这个结合更多where
语句时遇到了问题。查询生成器不会组合 select()
中的占位符和 where
中的其他动态替换。
@hakre 如果我需要转义一堆(可变数量)变量以放入语句的“IN ()”部分怎么办?
@Janis:你会在Can I bind an array to an IN() condition? 中找到这些问题的答案,这是姐妹问答。【参考方案2】:
你也可以试试这个,(Read Documentation)
$results = DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));
【讨论】:
+1 对此答案。使用数组绑定,就像上面的例子,会保护你。更多信息在这里forums.laravel.io/viewtopic.php?id=11068 这并没有回答问题,它表明我不是在寻找带有占位符的解决方案,而是寻找逃避一个变量的适当方法。 @Dwight,这就是array binding/bound params
所做的,安全的,转义的,不能应用 sql 注入,而不仅仅是占位符。只需阅读this answer 即可清除自己。
@Dwight,还注意到第一条评论,它没有澄清你吗?【参考方案3】:
您可以通过 DB
门面以这种方式引用您的字符串。
DB::connection()->getPdo()->quote("string to quote");
当我发现这个答案时,我确实把它放在了我的问题中,但是我现在把它作为一个实际的答案放进去,以便其他人更容易找到。
【讨论】:
谢谢!令人惊讶的是,人们如何坚持回答错误的问题。我需要和你一样的答案,而且参数在我的情况下也不起作用。 有效,但要调用这么长时间! DB::escape() 会很好。【参考方案4】:我在 Laravel 5 的 helpers.php
中使用它:
if ( ! function_exists('esc_sql'))
function esc_sql($string)
return app('db')->getPdo()->quote($string);
然后我可以使用esc_sql
函数来执行原始 SQL 查询的转义。
【讨论】:
【参考方案5】:我在 Laravel 中寻找通用 sql 转义时发现了这个问题。我实际上需要的是表/列名转义。因此,供将来参考:
/**
* 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);
【讨论】:
DB::query()->getGrammar()
可能是一种更直接的方法。防止其他开发人员问太多问题。【参考方案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
外观中内置了不太冗长的解决方案。
首先,value quoting:
// From linked answer
DB::connection()->getPdo()->quote("string to quote");
// In the DB facade
DB::getPdo()->quote('string to quote');
二、identifier quoting(表名和列名):
// From linked answer
DB::table('x')->getGrammar()->wrap('table.column');
// In the DB facade
DB::getQueryGrammar()->wrap('table.column');
【讨论】:
以上是关于在 Laravel 4 中转义原始 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
NamedParameterJdbcTemplate Oracle SQL,如何在命名查询中转义单引号?