0

使用するコードの量を節約するために、複数のページで使用できる関数を作成しようとしています。関数パラメータの 1 つで、どの mysql テーブルからすべてのデータを取得するかを関数に指示する必要がありますが、何らかの理由で関数が機能しません。ここに私が持っているものがあります:

function get_data($conn, $type) {
    $stmt = $conn->prepare("SELECT * FROM :type");
    $stmt->bindParam(':type', $type);
    $stmt->execute();
    $results = $stmt->fetchAll();
    return $results ? $results : false;
}

したがって、ページの1つで関数を呼び出すときは、次を使用します。

$conn = connect();
$results = get_data($conn, 'links');

機能が動作しないのはなぜですか?誰でも知っていますか?

4

2 に答える 2

1

@Diego は正しいです。テーブル名、列名、SQL キーワード、値のリスト (IN() 述語など)、またはその他の式に SQL パラメーターを使用することはできません。

SELECT :column FROM table   -- NO, unless you want to select a constant string

SELECT * FROM :table    -- NO

SELECT * FROM table WHERE column IN (:list)  -- NO

SELECT * FROM table ORDER BY :column -- NO

SELECT * FROM TABLE ORDER BY column :asc_or_desc  -- NO

基本的に、次の規則を覚えておいてください。SQL パラメータの代わりに定数値(引用符で囲まれた文字列、日付、または整数など) を配置できる場合、それはパラメータの正当な使用法です。そうでなければ、いいえ。

SELECT :string FROM table -- OK, but returns value of :string for every row

SELECT * FROM table WHERE column = :string  -- OK

SELECT * FROM table WHERE column IN (:x, :y, :z) -- OK, one parameter per value

また、PDO をプログラミングするときは、常に と の戻り値を確認する必要がprepare()ありexecute()ます。これらはエラー時に戻りfalseます。これを検出して適切に応答するコードを記述する必要があります (つまり、エラーをログに記録し、エラー ページを表示し、ユーザーに別の機会を与えるなど)。

$stmt = $conn->prepare("SELECT * FROM :type"); // illegal use of parameter
if ($stmt === false) {
  // check $pdo->errorInfo(), see documentation
}
$stmt->bindParam(':type', $type);
$status = $stmt->execute();
if ($status === false) {
  // check $stmt->errorInfo(), see documentation
}

他の PDO 関数の戻り値を確認することもできます。ドキュメントを参照してください。それらの多くはfalseエラーを返します。

于 2012-11-21T00:19:36.170 に答える
1

私の知る限り、テーブルをパラメーターとして渡すことはできません。したがって、文字列連結を使用してクエリを作成する必要があります。このような場合、外部ソースからのテーブル名を受け入れるべきではないため、SQL インジェクションのリスクはゼロになるはずです。

function get_data($conn, $table_name) {
    // The backticks are used in case table name contains spaces, or it matches a keyword
    $stmt = $conn->prepare('SELECT * FROM `' . $table_name . '`');
    $stmt->bindParam(':type', $type);
    $stmt->execute();
    $results = $stmt->fetchAll();
    return $results ? $results : false;
}

もう 1 つの注意事項
達成したいことは理解できますが、このデータ アクセス方法は非常に非効率的です。まず第一に、アスタリスクを使用します。これは、多くの場合、クエリを実行するときに大きな禁止事項です。次に、このアプローチでは、WHERE、JOIN などの句を追加できません。テーブルから常に無差別にすべてのデータを取得すると、パフォーマンスに重大な問題が発生する可能性があります。

于 2012-11-21T00:16:35.683 に答える