2011-12-30 18 views
5
$sql='SELECT phrase,english FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['languagepage'])); 

上記のコードは正常に動作します。しかし、準備文に別の変数を入れる必要があります。私は、次のことを試してみましたが、動作していないよう:PHP PDO +準備文

$sql='SELECT phrase,? FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['language'],$_POST['languagepage'])); 

私は(それを印刷から)$ _POST [「言語」]は唯一の単語「英語」が入っていることがわかっています。 選択のこの部分に準備変数を入れることはできますか?

thx

+0

構文エラーはありませんが、どのようなエラーコードがありますか? – LotusH

+0

エラーはありませんが、むしろDBから値を取得するだけで、私には英語の言葉が与えられます。これは、DB内の列の変数とタイトルの値です。 – Adam

+0

例:{"free": "english"、 "meetsingles": "english"、 "searchprofiles": "english"}単語の英語が異なるところの異なる値... – Adam

答えて

7

クエリパラメータは、列名ではなく定数値の代わりに使用できます。

クエリを準備するときに、すべての列とテーブルの名前を付ける必要があります。列を選択して後続の実行ステップに延期することはできません。

ユーザー入力で列名を決定するには、ホワイトリストマップを使用して、有効な選択肢にユーザー入力を制限します。マップ配列のキーは正当なユーザー入力です。マップ配列の値は、SQLクエリーで使用する文字列です(この場合は列名)。

$lang_col_map = array(
    "DEFAULT" => "english", 
    "en"  => "english", 
    "es"  => "spanish" 
); 
$lang_col = $lang_col_map[ $_POST["language"] ] ?: $lang_col_map[ "DEFAULT" ]; 

$sql='SELECT phrase,$lang_col FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); 
$pds->execute(array($_POST['languagepage'])); 

それが一致しないため、あなたは$のlang_col_mapで唯一の値は、SQLクエリの一部になることができ、ユーザーがHTTP要求にトリッキーな何かを送信しようとした場合、それは無視されますことを確認することができます。この方法その地図の任意のキー。したがって、クエリはSQLインジェクションから安全です。

詳細については、私のプレゼンテーションSQL Injection Myths and Fallaciesを参照してください。

+0

すべての質問/クエリは、尋ねられる前に知っておくべきです。 – Xeoncross

2

プリペアドステートメントは、データベースでサポートされている値のみをサポートします。

2番目の文では、最初の "?"値ではなく列名のプレースホルダです。

代わりに動的SQL文を使用する必要があります。 このためには、SQLインジェクションを防ぐ必要があります。

$language_authorized = array('english', 'french', 'spanish'); 
$language = $_POST['language']; 
if (in_array($language_authorized, $language)) { 
    $sql='SELECT phrase,'.$language.' FROM static_site_language WHERE page=?;'; 
    $pds = $database->pdo->prepare($sql); 
    $pds->execute(array($_POST['languagepage'])); 
}