web-dev-qa-db-ja.com

CodeIgniterで準備済みステートメントを使用するには

こんにちは私のサイトでPrepared Statementsを使用するために必要なすべてのこと。これを使ってみた

$sql = "SELECT * FROM tbl_user WHERE uid=:id and activation_key=:key";
$query = $this->db->query( 
    $sql, 
    array( ':id' => $uid ,':key' => $activation_key)
);

しかし、これは機能していません。 :idおよび:keyから?その働き。

25
Pramod

CodeIgniterはPrepared Statementsをサポートしていません。 CIのDatabaseクラスのソースコードを見ると、疑問符を渡された配列のデータで置き換えるだけで、バインディングが解決されていることがわかります。

名前のないプレースホルダーを使用したクエリバインディングのみをサポートします。 を参照してくださいhttp://ellislab.com/codeigniter/user-guide/database/queries.html

クエリバインディング

バインディングを使用すると、システムがクエリをまとめて、クエリ構文を簡略化できます。次の例を考えてみます。

$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));

クエリの疑問符は、クエリ関数の2番目のパラメーターの配列の値に自動的に置き換えられます。

および http://ellislab.com/forums/viewthread/105112/#528915

CIは準備済みステートメントをサポートしていませんが、クエリバインディングをサポートしています。準備されたステートメントでは、何らかのタイプのprepare()関数を呼び出してから、何らかのタイプのexecute()関数を呼び出す必要があります。クエリバインディングでは、1つの関数を呼び出すだけでよく、基本的に同じことを行います。このため、準備されたステートメントよりもクエリバインディングの方が好きです。

傍注では、?:fooは、名前のないバインディングから名前の付いたバインディングに変更されているだけです(CIは明らかにどちらもサポートしていません)。どちらかを使用したからといって、ステートメントを準備しているという意味ではありません。

40
Gordon

私は同様の問題に直面してこの質問に出くわしました。正解は、CIが準備済みステートメントをサポートしていないことです。ただし、これはが準備済みステートメントを使用できないことを意味するわけではありません

次の例では、接続クラスとしてPDOを使用していますが、次のコードが機能します。

_$q = $this->db->conn_id->prepare('SELECT * FROM tbl_user WHERE uid=? and activation_key=?');
$q->execute(array($param1,$param2));
print_r($q->fetchAll());
_

conn_idは、準備されたステートメントを実行できるPDOオブジェクトです。

ただし、これで許可されないのは、ネイティブCI関数が許可するクエリ文字列を取得することです。そのためには、 Get Last Executed Query in PHP PDO )のようなものが必要になります。

さらに、ただし、これによってクエリビルダーを使用してステートメントを作成し、PDO準備で使用できるようになるわけではありません。例えば ​​-

_$db->where('uid = ?',null,false);
$db->where('activation_key = ?',null,false);
$q = $this->db->conn_id->prepare($db->get_compiled_select('tbl_user'));
_

クエリを作成し、$db->get_compiled_select('tbl_user');を出力すると、基本的なクエリを表示できるようになります

8
Antony