3

これのさまざまな側面をほぼ無限にテストした後、PDO接続が機能し(簡単なクエリを実行して結果を表示できる)、ステートメントが正常に準備され、値が適切にバインドされていることを確認しました。 。何らかの理由で、ステートメントは実行されません。かわいくするために、私はすべてのバインドされた変数を削除して静的クエリを実行しようとしましたが、それも機能しません。

コード:

$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

$sth = $dbh->prepare( "SELECT * FROM :table WHERE :field = :value" );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":table", $table ) ) TCDebug( "table true" );
if( $sth->bindValue( ":field", $field ) ) TCDebug( "field true" );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();

if( $flag === true ) {
    TCDebug( 'flag = true' );
} else if( $flag === false ) {
    TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();

foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
    return $result;
} else {
    return null;
}

'prepared''table true''field true''value true''flag = false'のデバッグテキストを一貫してエコーします。これは、準備とバインドが機能することを通知しますが、実行すると、$ resultは空になり、関数はnullを返します。

私は恐ろしく明白な何かを見落としているかもしれません、そして私は完全に頭をぶら下げる準備ができています。前もって感謝します...

アップデート

ああ、連結-今日の私の友達。動作するコードは次のとおりです。

$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

$prepare_str = "SELECT * FROM ". $table ." WHERE ". $field ." = :value";

$sth = $dbh->prepare( $prepare_str );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();

if( $flag === true ) {
    TCDebug( 'flag = true' );
} else if( $flag === false ) {
    TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();

foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
    return $result;
} else {
    return null;
}

$table$fieldはシステムによって生成され、ユーザー入力を介してアクセスすることはできないため、この場合は安全です。$valueのみが公開されます。

StackOverflowに感謝します!あなたは私のお気に入り!:)

4

1 に答える 1

8

次のようなパラメータ化されたクエリがある場合:

SELECT * FROM :table WHERE :field = :value

:table、、、:fieldおよびの値を置き換えると、次のよう:valueものが得られます(実際には、これは過度の単純化ですが、要点を示しています)。

SELECT * FROM 'sometable' WHERE 'somefield' = 'somevalue'

なぜなら:table、と:field同じ意味処理を取得するから:valueです。それらは文字列として扱われます。通常、パラメーター化されたクエリを使用してテーブル名と列名をパラメーター化することはできません。アプローチを少し考え直す必要があります。プリペアドステートメント文字列を動的に構築して、クエリのテーブル名と列名の部分をPDOでバインドするのではなく、単純な連結にすることを検討してください。ただし、PDOはそのレベルでのSQLインジェクションからユーザーを保護しないため、テーブル名と列名の検証/サニタイズには十分注意する必要があります。

于 2011-06-21T04:00:31.447 に答える