Aktueller Standort: Startseite> Neueste Artikel> MySQLI_STMT :: $ ERROR Der Grund und die Lösung für den Syntaxfehler können nicht erfasst werden

MySQLI_STMT :: $ ERROR Der Grund und die Lösung für den Syntaxfehler können nicht erfasst werden

gitbox 2025-05-28

Bei Verwendung von PHP -Erweiterung von PHP für Datenbankvorgänge verwenden wir häufig vorbereitete Anweisungen, um Sicherheit und Leistung zu verbessern. Gleichzeitig möchten Entwickler häufig mögliche Fehler wie SQL -Syntaxfehler während der Ausführung genau erfassen. Sie können jedoch auf ein so verwirrendes Problem stoßen:

Was ist denn los? Dieser Artikel wird eine eingehende Analyse dieses Problems durchführen und praktische Lösungen bieten.

1. Problem taucht wieder auf

Siehe den folgenden Beispielcode:

 $mysqli = new mysqli("localhost", "user", "password", "testdb");

// Syntaxfehler:Einer fehlt FROM
$sql = "SELECT id name users WHERE id = ?";

$stmt = $mysqli->prepare($sql);

if (!$stmt) {
    echo "Prepare failed: " . $mysqli->error;  // Die richtige Art, es zu tun
} else {
    $stmt->bind_param("i", $id);
    $id = 1;
    $stmt->execute();

    if ($stmt->error) {
        echo "Execute error: " . $stmt->error; // 不会捕捉到Syntaxfehler
    }

    $stmt->close();
}
$mysqli->close();

Ausgangsergebnis:

 Prepare failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version...

Wie Sie sehen können, geben SQL-Syntaxfehler überhaupt nicht $ stmt-> Fehler ein , sondern werden in der Stufe PREAP () von $ mySQLi-> Fehler aufgenommen.

2. Analyse Ursache

Wir müssen die Arbeitsteilung zwischen MySQLI und MySQLI_STMT in PHP verstehen:

  • Mysqli :: prepe () ist eine Methode, die vom Datenbankverbindungsobjekt aufgerufen wird. Wenn SQL Syntaxfehler aufweist, wird das STMT -Objekt überhaupt nicht generiert , sodass $ STMT falsch ist.

  • MySQLI_STMT :: $ ERROR hat nur einen Wert, nachdem die Anweisung erfolgreich erstellt wurde und ein Laufzeitfehler auftritt (z. B. der Bindungsvariablentyp übereinstimmt nicht während der Ausführung, fehlende Schlüsselbeschränkungen für Fremdkörper usw.).

  • SQL-Syntaxfehler werden und können nicht mit $ stmt-> fehler nicht erfasst werden, da es nicht einmal ein STMT-Objekt erstellt .

Mit anderen Worten:

SQL-Syntaxfehler treten in der Phase prepe () auf und müssen nach dem Rückgabewert von $ mysqli-> fehler oder mysqli :: prepe () beurteilt werden, anstatt auf $ stmt-> execute () zu warten.

3.. Richtige Fehlerbehandlungsmethode

Schreiben Sie den obigen Code neu und verwenden Sie eine sicherere Fehlerbehandlungslogik:

 $mysqli = new mysqli("localhost", "user", "password", "testdb");

$sql = "SELECT id, name FROM users WHERE id = ?";  // Richtige Syntax

$stmt = $mysqli->prepare($sql);

if (!$stmt) {
    // 检查Syntaxfehler
    die("SQL prepare failed: " . $mysqli->error);
}

$stmt->bind_param("i", $id);
$id = 1;

if (!$stmt->execute()) {
    // Überprüfen Sie die Laufzeitfehler
    die("Execute failed: " . $stmt->error);
}

$result = $stmt->get_result();
$data = $result->fetch_assoc();

echo "User: " . $data['name'];

$stmt->close();
$mysqli->close();

4.. Ein Sicherheitsrisiko, das leicht übersehen wird

Wenn Sie die AJAX -Schnittstelle verwenden, um SQL -Parameter einzureichen, z. B. auf eine solche Adresse zugreifen:

 https://gitbox.net/api/get_user.php?id=1

Dann spleißen Sie die Benutzereingabe in SQL (gefährlich!):

 $id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $id";  // Potenzial SQL Injektionsrisiko

Diese Schreibmethode ist beim Spleißen leicht zu schreiben, und vorbereiten () wird nicht verwendet, und Fehler sind schwieriger zu finden. Daher wird die folgende Schreibmethode empfohlen:

 $sql = "SELECT * FROM users WHERE id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i", $_GET['id']);

Dies vermeidet nicht nur die SQL -Injektion, sondern macht auch die Fehlerprüfung klar und zentralisiert.

5. Zusammenfassung

  • SQL-Syntaxfehler können nur in der Stufe Prepe () gefunden werden und können nicht über $ STMT-> Fehler erhalten werden.

  • Überprüfen Sie unbedingt den Rückgabewert von Prepe () und verwenden Sie $ MySQLI-> Fehler, um die Fehlermeldung auszugeben.

  • Es wird empfohlen, Vorverarbeitungsanweisungen zu verwenden, um die Injektion zu verhindern, und es ist einfacher, Fehler zu debuggen und zu fangen.

Nur durch das Verständnis der Aufteilung der Verantwortlichkeiten zwischen MySQLI und MySQLI_STMT können wir robusteren und sichereren Datenbank -Interaktionscode schreiben.