2017-02-09 3 views
1

Ich bin ziemlich neu in PDO und versuche, meinen MySQLi prozedural strukturierten PHP-Code in eine objektorientierte PDO-Struktur zu ändern. Ich lerne gerade über das Vorbereiten, Ausführen, BindParam/BindValue und dergleichen, zu einem gewissen Grad an Erfolg.PDO mit Unterabfragen vorbereiten

Meine Frage ist, wie ich eine Abfrage vorbereiten, wenn der Benutzer Wert in einer Unterabfrage dieser Abfrage eingereicht hat?

Ich habe eine Variable als Unterabfrage in PHP verwendet (wobei $ playerOne, $ playerTwo vom Benutzer übergebene Werte sind).

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

Dies ist es, alle Datensätze für diese Spieler zu erhalten. Ich kann dann als Beispiel vergleichen, welche Spiele sie gegeneinander gespielt haben, z.

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

Hinweis: SELECT * wird nur verwendet, um es hier besser lesbar zu machen.

Ist es genug zu tun $pdoWith = $db->prepare($sqlWith) oder sollte ich die $sqlPlayerOne zuerst vorbereiten, da dies der Benutzer Wert eingereicht hat?

Ich weiß, ich konnte nur die Unterabfrage innerhalb jeder einzelnen Hauptabfrage kopieren, die es brauchte, aber wenn ich nicht muss, würde ich lieber nicht.

EDIT: Sorry für den Mangel an Klarheit. Dies war ein Teil meines Codes, bevor ich ihn änderte, da ich nicht sicher war, wie ich ihn ändern müsste. Es scheint, ich will nur, um es ähnlich zu tun haben, wie @JC WALD wies darauf hin:

$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

Was versuchst du zu tun, ich verstehe nichts. Was Sie tun, ist nicht erlaubt. Sie müssen genau wissen, was Sie mit diesen 3 Abfragen tun möchten, und Sie müssen nur eine Abfrage vorbereiten, auch wenn sie Unterabfragen enthält. – 131

+1

Wissen Sie, wie die PDO-vorbereitete Anweisung tatsächlich funktioniert? Hast du eine Idee, was ein ** Platzhalter ** ist? Ihre $ sqlPlayerOne-Variable zeigt kein Anzeichen dafür, dass sie mit "bindParam/bindValue und ähnlichem" verwendet wird. –

+0

Dies wurde verwirrend. Sie haben die Frage bearbeitet, um etwas anderes zu fragen, und dann eine Antwort angenommen, die weder erklärt, was mit dem ursprünglichen Code nicht stimmt, noch die PDO-Syntax erklärt. Ich hoffe, du hast die Grundlagen der vorbereiteten Aussagen verstanden und nicht einfach blind den Code in dein Projekt eingefügt ;-) –

Antwort

1

Sie müssen $ playerOne, $ playerTwo an Ihre vorbereitete Anweisung als Parameter binden.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

Der Gesamtmechanismus der vorbereiteten Anweisungen ist das gleiche in allen Datenbank-Erweiterungen, die es unterstützen:

  • ersetzen Nummer oder String-Literale (und ich meine, Literale, nicht zufällige Stücke von Code) innerhalb von SQL mit Platzhaltern, entweder positionsbasierte ? oder mit dem Namen :username (nicht mischen, wählen Sie eine)
  • Bereiten Sie die Abfrage durch Aufruf der entsprechende Funktion, die SQL als Parameter
  • empfängt
  • Führen Sie die vorbereitete Abfrage durch die entsprechende Funktion aufrufen (n), die Werte wie paremeter

So erhalten, wenn Sie es richtig in mysqli, einen Schalter zu PDO tun wird keine Änderung in Ihrer Logik erfordern. Ihre Codebeispiele empfehlen jedoch Sie verwenden überhaupt keine vorbereiteten Anweisungen: Keine Platzhalter, keine Daten in einem separaten Kanal ... Ich kann variable interpolation in double quoted strings sehen, aber das ist eine PHP-Funktion, keine SQL-Funktion. Daher ist es völlig sinnlos, Code und Daten zu trennen und SQL-Injection zu verhindern.

Ich vermute, dass das Wurzel-Missverständnis nicht völlig sicher ist, wie PHP und SQL interagieren. Die Antwort ist, dass sie es nicht tun: Sie sind völlig verschiedene Computersprachen und werden von völlig verschiedenen Programmen ausgeführt. Die einzige Beziehung besteht darin, dass Sie die erstere verwenden, um die letztere zu generieren. Egal, was Sie tun, am Ende werden Sie nur eine Zeichenfolge (d. H. Nur-Text) an den Datenbankserver senden. Wie Sie diesen Text erzeugen, ist irrelevant, da Strings keinen Speicher haben.