2017-02-09 21 views
1

私はPDOを使い始めており、MySQLiの手続き的に構造化されたPHPコードをオブジェクト指向のPDO構造に変更しようとしています。私はちょうど準備、実行、bindParam/bindValueなどを成功の程度まで学んでいます。サブクエリを使用したPDOの準備

私の質問は、ユーザーのサブミット値がそのクエリのサブクエリにあるときに、どのようにクエリを準備するのですか?

私は、phpのサブクエリとして変数を使用しています($ playerOne、$ playerTwoはユーザが提出した値です)。

$sqlPlayerOne = "(SELECT * FROM players WHERE Player_name = $playerOne)"; 
$sqlPlayerTwo = "(SELECT * FROM players WHERE Player_name = $playerTwo)"; 

これは、これらのプレーヤーのすべてのレコードを取得するためです。私は、例として、彼らがプレイしたゲームをお互いに比較することができます。

$sqlWith = "SELECT * FROM $sqlPlayerOne s1 
WHERE EXISTS (SELECT * FROM $sqlPlayerTwo s2 WHERE s1.Team_name = s2.Opposing_team) 

注:SELECT *は、ここでより読みやすくするために使用されています。

$pdoWith = $db->prepare($sqlWith)を実行するだけで十分ですか、それとも$sqlPlayerOneを準備する必要がありますか?

サブクエリをコピーする必要があるすべてのメインクエリの中にサブクエリをコピーして貼り付けることができたと思います。

EDIT:明快さのために申し訳ありません。これを変更する前に、これは私のコードの一部でした。私はそれをどうやって変更しなければならないのか分かりませんでした。私がちょうどそれを@JC FORESTが指摘した方法に似を行う必要がありますようだ:

$dsn = "mysql:host=localhost;dbname=database"; 
$username = "user"; 
$password = "pass"; 
$db = new PDO($dsn, $username, $password); 

$stmt = $db->prepare("SELECT * FROM (SELECT * FROM players WHERE Player_name = :playerone) 
s1 WHERE EXISTS (SELECT * FROM (SELECT * FROM players WHERE Player_name = :playertwo) s2 
WHERE s1.Team_name = s2.Opposing_team)"); 

$stmt->bindValue(':playerone', $playerOne); 
$stmt->bindValue(':playertwo, $playerTwo); 
$stmt->execute(); 
+0

あなたは何をしようとしていますか、私は事を理解していません。あなたがやっていることは許されていません。これらの3つのクエリで何をしたいのかを意識する必要があり、サブクエリがあっても1つのクエリを準備するだけです – 131

+1

PDOの準備文が実際にどのように機能するのか分かりますか? **プレースホルダ**は何ですか?あなたの$ sqlPlayerOne変数は、 "bindParam/bindValueなどで"使用されていることの兆候を表示しません。 –

+0

これは混乱しています。質問を編集して、何か違うものを尋ねた後、元のコードの何が間違っているかを説明したり、PDOの構文について説明したりすることはできません。 –

答えて

1

パラメータとして$ playerOne、$ playerTwoをプリペアドステートメントにバインドする必要があります。http://php.net/manual/en/mysqli.prepare.php

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world'); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

/* create a prepared statement */ 
$stmt = $mysqli->prepare("SELECT * FROM (SELECT * FROM players WHERE Player_name = ?) s1 
WHERE EXISTS (SELECT * FROM (SELECT * FROM players WHERE Player_name = ?) s2 WHERE s1.Team_name = s2.Opposing_team)") 

    /* bind parameters for markers */ 
    $stmt->bind_param("ss", $playerOne, $playerTwo); 

    /* execute query */ 
    $stmt->execute(); 
0

準備文の全体的なメカニズムは、それをサポートするすべてのデータベースの拡張機能でも同じです:

  • 番号を交換してくださいSQL内でポジションベースの?または名前付き:usernameのいずれかを使用してSQL内で文字列リテラル(およびリテラルを意味します(ランダムなコードではない))
  • パラメータとしてSQLを受け取る適切な関数
  • はあなたが右のmysqliの中でそれをやっているのであれば

paremeterとして値を受け取る適切な機能(複数可)を呼び出すことによって作成したクエリを実行し、PDOへのスイッチは、あなたのロジックの変更を必要としません。しかし、あなたのコードサンプルは、を提案します。はプレースホルダを持たず、別のチャネルにデータがありません... variable interpolation in double quoted stringsが表示されますが、これはSQL機能ではなくPHP機能です。したがって、コードとデータを分離してSQLインジェクションを防止することは全く役に立たない。

私は、PHPとSQLのやり取りの根本的な誤解が完全にはわかっていないと考えています。答えは、そうではないということです。彼らはまったく異なるコンピュータ言語であり、全く異なるプログラムによって実行されます。唯一の関係は、後者を生成するために前者を使用することです。あなたが何をしていても、結局は文字列(つまりプレーンテキスト)をデータベースサーバーに送信するだけです。文字列にメモリがないため、そのテキストをどのように生成するかは関係ありません。

関連する問題