Vorverarbeitungsanweisungen sind eine gängige und sichere Praxis, wenn die MySQLI -Erweiterung von PHP für Datenbankoperationen verwendet wird. Entwickler verwenden normalerweise MySQLI :: STMT_INIT (), um ein Anweisungsobjekt zu initialisieren und dann SQL -Anweisungen über die Methode Preped () vorzubereiten. Wenn Sie jedoch vergessen, Preped () nach dem Aufrufen von STMT_INIT () auszuführen, führt dies zu einigen impliziten Problemen. Dieser Artikel wird Beispiele analysieren und angeben.
Normalerweise ist unsere Codestruktur wie folgt:
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->stmt_init();
$stmt->prepare("SELECT * FROM users WHERE id = ?");
In:
stmt_init () initialisiert ein mySQLI_STMT -Objekt;
Prepe () erstellt eine SQL -Anweisung und bindet sie an das Objekt.
Wenn Sie nur STMT_INIT () und nicht vorbereiten () aufrufen, treten die folgenden Arten von Problemen auf, wenn das Programm das Anweisungsobjekt in der anschließenden Verwendung der folgenden Anweisung verwendet:
Aufrufen von Methoden wie Bind_param () , execute () direkt ohne Anruf prepect () führt zu Warnungen zu werfen oder sogar tödliche Fehler:
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->stmt_init();
// Ich habe vergessen anzurufen prepare()
$stmt->bind_param("i", $userId); // Hier wird ein Fehler gemeldet
$stmt->execute(); // Es wird auch hier scheitern
Die Fehlermeldung kann sein:
Fatal error: Uncaught Error: Call to a member function bind_param() on bool
oder:
Warning: mysqli_stmt::bind_param(): invalid object or not initialized
Wenn Sie das Anweisungsobjekt nur initialisieren, aber nicht vorbereitet () haben, werden SQL -Fehler, die in der Phase Preped () gefunden werden können, versteckt und führen möglicherweise bis zur Ausführung zu unklaren Fehlern. Dies erhöht die Debugg -Kosten.
Vergessen , Prepe () zu verwenden () bedeutet, dass Sie SQL -Anweisungen direkt spleißen können, die den Mechanismus der Parameterbindung umgehen und damit das Risiko einer SQL -Injektion erhöht. Zum Beispiel:
// Fehlerbeispiel(NEIN prepare)
$userId = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $userId";
$result = $mysqli->query($query);
Wenn Prepe () und Parameterbindung nicht verfügbar sind, wird die Benutzereingabe direkt in SQL eingebettet, und der Angreifer kann die folgende URL erstellen:
https://m66.net/get_user.php?id=1 OR 1=1
Wird Datenverletzungen verursachen.
Kombinieren Sie immer mit STMT_INIT () und vorbereiten () wie folgt:
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->stmt_init();
if ($stmt->prepare("SELECT * FROM users WHERE id = ?")) {
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['username'] . "<br>";
}
$stmt->close();
} else {
echo "SQL prepare Fehler: " . $mysqli->error;
}
Ich habe vergessen, Preped () anzurufen () zu folgenden Problemen:
Ein Fehler beim Aufrufen anderer Anweisungsmethoden aufgetreten;
SQL -Fehler können nicht im Voraus gefangen werden.
Erhöhen Sie Sicherheitsrisiken wie die SQL -Injektion.
Es wird empfohlen, Preped () sofort nach der Verwendung von STMT_Init () aufzurufen und seinen Rückgabewert zu beurteilen, um die Stabilität und Sicherheit des Programms zu gewährleisten.