【问题标题】:Escape raw SQL queries in Laravel 4在 Laravel 4 中转义原始 SQL 查询
【发布时间】: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,好点子!我现在也将其添加为实际答案,因此应该更容易找到。

标签: php mysql pdo laravel laravel-4


【解决方案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');
      

      【讨论】:

        猜你喜欢
        • 2021-09-13
        • 2018-10-11
        • 1970-01-01
        • 2019-02-03
        • 2021-01-16
        • 1970-01-01
        • 2018-04-28
        • 2021-07-27
        • 2021-12-05
        相关资源
        最近更新 更多