2011-01-07 3 views
5

私はPDOライブラリの初心者です。私は自分のデータベースとしてmysqlを開発環境に取り組んでいます。 "?"を使用している間、準備と実行の機能を使用してクエリを実行することができます。プレースホルダと、名前付きプレースホルダ(例: ":column")を使用している間はbindParamメソッドも使用できます。この後PDOがSQLインジェクションをエスケープしていることは、どのようにわかりますか?

私は、PDOはmysql_real_escape_stringのが行うようクエリをサニタイズするために、任意の引用符を入れることにより、エスケープのいずれかの種類を行うかどうかを確認してみました。私はどのようなクエリの外観を見てしようとしているが、私が得るすべては、準備ステートメントに渡されたが、実行されるクエリではないステートメントです。

私は$ result-> execute()と$ result-> fetch()をvar_dumpしようとしましたが、execute文はplace holderを持つprepare文のsqlを返しますが、fetch文はそのクエリの結果を返します。

実行される検索クエリを表示する方法、またはクエリを実行する前にパラメータがどのように見えるのかがありますか?

私は私の質問ではっきりしていることを願っています。 :|

+1

あなたは、あまり心配。準備文は入力を100%エスケープします。最終的なクエリーの内容を確認する必要がある場合は、データベースクエリーログを設定する必要があります。 – netcoder

+1

@netcoderプリペアドステートメントは何もエスケープしません(互換モードでない限り)。クエリログには何も新しいものはありません。 –

+0

@Col。 Shrapnel:技術的にはそうですが、あなたが望むように言葉で言えます。 「クエリログには何も新しいことはありません」という意味では、意味が分かりません。 – netcoder

答えて

6

「後」を送るので、PDOが要求を脱出していない、mysqlので取り扱うです準備:

$stmt = $pdo->prepare('SELECT * FROM tbl_name WHERE col_name = :col_name;'); 
$stmt->bindValue('col_name', 'some \' value'); 
$stmt->execute(); 

実際のクエリは... SELECT * FROM tbl_name WHERE col_name = :col_name;です。これは、の準備文と呼ばれています。まず、クエリをデータベースに送信し、後でクエリパラメータを送信します。 PDOはクエリとパラメータをマージしません。

おそらくPDOStatement::bindValue()のようなものないことを考えた:

public function bindValue($placeholer, $value, $valueType = PDO::PARAM_STR) { 
    $this->query = str_replace($placeholder, $this->quote($value, $valueType), $this->query); 
} 

をしかし、それはません。 - いくつかの挿入を行う

public function execute() { 
    try { 
     $this->sendQueryToDatabase($this->query); 

     // Query is valid 
     $this->sendParametersToDatabase($this->parameters); 

     return $this->fetchResultSet(); 
    } catch (... $e) { 
     // Query is invalid (eg. syntax error) 
     throw ...; 
    } 
} 

Read more about Prepared Statements

+0

送信されるパラメータが安全であるかどうかはどのようにわかりますか?私たちは手でそれらをチェックする必要がありますか? – macha

+2

パラメータはクエリの一部ではないため、安全ではありません。それらは生データです。 – Crozin

+0

ちょっと高すぎるかもしれないと知っていますが、どのようにクエリを解析するのか、これらのパラメータをプレースホルダでどのように送ったり置換したりするのですか? – macha

1

文はあなたが何か書くとき PDOはリクエストパラメータ

+0

なぜあなたは下降しているのか分かりませんが、これは実際には真実です。 – netcoder

+0

これは実際には当てはまりませんが、PDOは通常、準備されたステートメントをエミュレートします。サーバー側の準備済みステートメントはサポートされているため、一般的には良い考えではありません。 – MarkR

+0

@MarkRは互換モードでのみ使用されています。すでに使用されていません。 –

-1

は、一般クエリログを有効にし、実際にあなたが簡単な文を実行しているサーバーに対して実行されたクエリを見て:

それはより多くのそのような何かをしますたとえば、引用符またはヌルが埋め込まれた文字列を使用します。

+0

彼は何も新しいことを見ないよ –

3

そのままにしてください。

  1. ネイティブモード:

    PDOは、プリペアドステートメントを実行しているの2つのモードがあります。クエリとデータはデータベースse-pa-ra-te-lyに送信されます。つまり、データは決してに追加されます。だから、害はない。これまでクエリは?マーク(しかし?秒でPDOに置き換えられていない名前のプレースホルダ)

  2. 互換モードで、そのままデータベースに送られます。 PDOは、変数名に依存して、プレースホルダをバインドされた変数に置き換えることによって、古いスタイルのクエリを作成します。文字列は引用/エスケープされ、残りはその型にキャストされます。

どちらの方法も完全に安全です。

あなたは変数識別子を持っていたときに本当の危険が始まる...

+0

なぜ可変識別子が危険ですか??データ型を検証することさえあるので安全だと思いましたか? – macha

+0

@machaフィールド名を意味します。たとえば、 'SELECT * FROM table ORDER BY $ column_name'は本当に危険です。 –

+0

大丈夫です!ご回答いただきありがとうございます。 – macha