web-dev-qa-db-ja.com

Laravel 4で生のSQLクエリをエスケープする

Laravel 4の生のクエリに渡されたパラメータをどのようにエスケープしますか? DB::escape()(Laravel 3からベルを鳴らす)のようなものを期待し、DB::quote()PDOオブジェクトを通じて利用できると思った)も試みました。

$query = DB::select("SELECT * FROM users WHERE users.id = " . DB::escape($userId));

上記は達成しようとしているものの単純化された例に過ぎないため、プレースホルダーで選択メソッドを使用することはできません。いくつかのネストされた選択クエリを持つ大きなカスタムクエリがあります。クエリビルダーに適合させることはできません。

Laravel 4に挿入する前に何かをエスケープする最良の方法は何ですか?

編集:

PDOオブジェクトにアクセスし、この方法でquote関数を使用できることを発見しました。これは依然として最善のアプローチですか、またはこの機能にアクセスする簡単な方法はありますか?

DB::connection()->getPdo()->quote("string to quote");
31
Dwight

DBファサードを使用して、この方法で文字列を引用できます。

DB::connection()->getPdo()->quote("string to quote");

見つけたときにこの答えを質問に入れましたが、他の人が見つけやすいように実際の答えとして入れました。

56
Dwight
$value = Input::get("userID");

$results = DB::select( DB::raw("SELECT * FROM users WHERE users.id = :value"), array(
   'value' => $value,
 ));

詳細 [〜#〜] here [〜#〜]

19
Arun Kumar M

これを試すこともできます( ドキュメントを読む

$results = DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));
9
The Alpha

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);
}
4
Rafał G.

私はこれをhelpers.phpでLaravel 5で使用しています:

if ( ! function_exists('esc_sql'))
{
    function esc_sql($string)
    {
        return app('db')->getPdo()->quote($string);
    }
}

その後、esc_sql関数を使用して、生のSQLクエリのエスケープを許可する必要があります。

3
J. Bruni

ここで使用する2つの答えは、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');
0
Sonny

以下は、値と列の両方をエスケープし、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]);
        });
    }
}
0
mpen