Problematik bei If abhängiger MYSQL Abfrage - und Ausgabewert
Hallo zusammen, ich habe ein Problem mit der dynamischen Ausgabe zweier Strings, wobei jeweils nur einer in Abhängigkeit von einer Varriablen angezeigt werden soll. Diese Varriable wird nach einer MYSQL DB Abfrage, in Abhängigkeit vom Ergebnis gesetzt. Naja ich hoffe ihr könnt mir da helfen, denn ich verstehe einfach den Fehler nicht. Doch nun erstmal der Reihe nach.
Hintergrund:
Ich arbeite an einem Loginsystem mit Zugriff auf 2 Datenbanken (1x Loginsystem selber auf Mysql Basis und nach erfolgreichem Login eine Suchfunktion die Daten in einer externen Postgresql Datenbank sucht und dann in einem Iframe anzeigt.) Das Loginsystem sowie das suchen nach den Daten in der ext. Datenbank funktioniert soweit tadellos. Da ich im nächsten Schritt aus Sicherheitsgründen eine manuelle aktivierung Seitens der Administration einbauen möchte, habe ich mich dazu entschieden dazu ein neues Feld in der Mysql Datenbank anzulegen. Dieses Feld befindet sich in der gleiben Tabelle wie auch alle anderen Userdaten (Name, PW usw.)) Nachdem ich nun bei meiner SQL Abfrage einen Zusatz hinzugefügt habe, der Abfragt ob der Wert im Feld Freischaltung (der Standartmäßig 0 ist) 1 ist oder nicht, kann sich ein Benutzer nur noch einloggen, wenn ein Administrator in der Datenbank zuvor den Wert von 0 auf 1 geändert hat.
Das Schwierige im letzten Teilschritt ist nun, das der User beim Anmeldeversuch nicht nur angegeben bekommt, das sein Name oder Passwort falsch eingegeben ist (sofern es falsch eingegeben ist) sondern auch, das der Account noch nicht freigeschaltet wurde.
Skripte:
nach dem sowohl der Username als auch das PW eingegeben wurde, werden die Daten via PHP in Varriablen gespeichert und dann weiterverarbeitet. Da der Seitenaufbau dynamisch gestaltet ist, habe ich dazu eine Funktion angelegt. Ich werde im nächsten Abschnitt weiter auf das Skript eingehen (und warum ich da was gemacht habe), hier soll erstmal nur das Skript zu sehen sein.
Die Funktion:
Der dynamische Bezug:
Skript Beschreibung:
Es ist zugegeben vielleicht nicht die schönste Methode nach der SQL Abfrage eine weitere SQL Abfrage zu stellen, nur mit einem Parameter weniger (um die Art des fehler zu differenzieren), es ist jedoch der einzige Weg der mir eingefallen ist. Im ersten Schritt speichere ich den SQL Befehl in einer Varriablen, bereite dann die Datenbank auf das statement vor, übergebe nutzerspezifische Angaben mit bind_param, lasse dann die Abfrage durchführen und speichere das Ergebnis in einer Variablen. Unabhängig vom weiteren Verlauf des Skriptes und den Abfragen funktioniert das bis hierhin definitv.
Wenn das Ergebnis der Abfrage positiv ist, also alle abgefragten Inhalte einmal vorhanden sind (und es geht nur einmal da Benutzername unique ist) soll der Loginvorgang ganz normal von Statten gehen (Das Funktioniert). Wenn der Rückgabewert 0 ist, also mindestens eine der Abfragen nicht gefunden wurde, oder falsch ist soll weiter geprüft werden.
Das weiter Prüfen sieht so aus, das eine identische SQL Abfrage an den Server gesendet wird, jedoch ohne das auf die manuelle Freischaltung eingegangen wird. Ist dann bei dieser Abfrage etwas nicht in Ordnung, so ist das Passwort oder der Benutzername falsch bzw. nicht vorhanden. Trifft beides jedoch zu und es wird eine 1 zurückgegeben (Also die Angaben stimmen mit denen in der DB überein.) bleibt nur noch, das der Nutzer noch nicht freigeschaltet wurde. (Im Skript ist das mit Fehlercode 1 und Fehlercode 2 angegeben, wobei die entsprechende Fehlermeldung im dynamischen bezug steht. (Bzw. genauer in der Logik die alle Seiten verbindet.)
Problem:
Unabhängig davon was man falsch im Login eingibt, es erscheint immer nur der String $error_msg = "Der Benutzername oder das Passwort ist falsch. ". Aber ich verstehe nicht so ganz warum... (Wenn die Nutzerdaten stimmen funktioniert der Login und man kommt auf die nächste Seite bzw. diese wird dynamisch nachgeladen.)
Hardware:
Das Testsystem, auf dem ich die Skripte Teste besteht aus 2 virtuellen Apache Webservern (mit fester IP), auf dem einen ist eine Postgesql DB, auf dem anderen eine Mysql DB installiert. Auf der mysql DB liegen die Daten der Webseite. Genutzt werden alle erforderlichen Resourcen in der aktuellsten Version. (Also php, mysql server, postgresql server usw.) Falls ihr diesbezüglich noch weitere angaben benötigt, stelleich euch diese gerne zur Verfügung.
Schlosswort:
Ich hoffe ich konnte meine Problematik einigermaßen verständlich darlegen und vielleicht hat jemand eine Idee, was ich übersehen habe. Jedenfalls würde ich mich über eine Rückmeldung sehr freuen.
mfg: DanteGabriel
EDIT:
Der SQL Befehl
Mit entsprechender Anpassung des Skriptverlaufes führt zum gleichen Ergebnis bzw. Problem.
Hintergrund:
Ich arbeite an einem Loginsystem mit Zugriff auf 2 Datenbanken (1x Loginsystem selber auf Mysql Basis und nach erfolgreichem Login eine Suchfunktion die Daten in einer externen Postgresql Datenbank sucht und dann in einem Iframe anzeigt.) Das Loginsystem sowie das suchen nach den Daten in der ext. Datenbank funktioniert soweit tadellos. Da ich im nächsten Schritt aus Sicherheitsgründen eine manuelle aktivierung Seitens der Administration einbauen möchte, habe ich mich dazu entschieden dazu ein neues Feld in der Mysql Datenbank anzulegen. Dieses Feld befindet sich in der gleiben Tabelle wie auch alle anderen Userdaten (Name, PW usw.)) Nachdem ich nun bei meiner SQL Abfrage einen Zusatz hinzugefügt habe, der Abfragt ob der Wert im Feld Freischaltung (der Standartmäßig 0 ist) 1 ist oder nicht, kann sich ein Benutzer nur noch einloggen, wenn ein Administrator in der Datenbank zuvor den Wert von 0 auf 1 geändert hat.
Das Schwierige im letzten Teilschritt ist nun, das der User beim Anmeldeversuch nicht nur angegeben bekommt, das sein Name oder Passwort falsch eingegeben ist (sofern es falsch eingegeben ist) sondern auch, das der Account noch nicht freigeschaltet wurde.
Skripte:
nach dem sowohl der Username als auch das PW eingegeben wurde, werden die Daten via PHP in Varriablen gespeichert und dann weiterverarbeitet. Da der Seitenaufbau dynamisch gestaltet ist, habe ich dazu eine Funktion angelegt. Ich werde im nächsten Abschnitt weiter auf das Skript eingehen (und warum ich da was gemacht habe), hier soll erstmal nur das Skript zu sehen sein.
Die Funktion:
function login($username, $password, $db, $salt) {
$password = hash('sha256', $password.$salt);
$sql = '
SELECT
COUNT(*)
FROM
user
WHERE
Username = ?
AND
Password = ?
AND
Freischaltung != 0
'; //Count (also zählen ob vorhanden geht schneller als expliziet den Wert auszulesen und zu prüfen.)
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $username, $password);
$stmt->execute(); //ausführen
$stmt->bind_result($result); //Ergebnis in einer Varriablen result speichern.
$stmt->fetch(); //fetchen (speichern in "result")
$stmt->close();
if($result == 1) {
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $username;
return true; //Die Session muss noch an den Server geschickt werden
} else {
$sql = '
SELECT
COUNT(*)
FROM
user
WHERE
Username = ?
AND
Password = ?
'; //Count (also zählen ob vorhanden geht schneller als expliziet den Wert auszulesen und zu prüfen.)
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $username, $password);
$stmt->execute(); //ausführen
$stmt->bind_result($result); //Ergebnis in einer Varriablen result speichern.
$stmt->fetch(); //fetchen (speichern in "result")
$stmt->close();
if($result == 1) {
$Fehlercode = 1;
} else {
$Fehlercode = 2;
}
}
}
Der dynamische Bezug:
if(login($_POST['username'], $_POST['password'], $db, $salt)) {
header('Location: /Script/login.php');
} else {
if($Fehlercode == 1) {
$error_msg = "Sie wurden noch nicht freigeschaltet. Bitte haben Sie noch etwas Gedult. ";
} else {
$error_msg = "Der Benutzername oder das Passwort ist falsch. ";
}
}
Skript Beschreibung:
Es ist zugegeben vielleicht nicht die schönste Methode nach der SQL Abfrage eine weitere SQL Abfrage zu stellen, nur mit einem Parameter weniger (um die Art des fehler zu differenzieren), es ist jedoch der einzige Weg der mir eingefallen ist. Im ersten Schritt speichere ich den SQL Befehl in einer Varriablen, bereite dann die Datenbank auf das statement vor, übergebe nutzerspezifische Angaben mit bind_param, lasse dann die Abfrage durchführen und speichere das Ergebnis in einer Variablen. Unabhängig vom weiteren Verlauf des Skriptes und den Abfragen funktioniert das bis hierhin definitv.
Wenn das Ergebnis der Abfrage positiv ist, also alle abgefragten Inhalte einmal vorhanden sind (und es geht nur einmal da Benutzername unique ist) soll der Loginvorgang ganz normal von Statten gehen (Das Funktioniert). Wenn der Rückgabewert 0 ist, also mindestens eine der Abfragen nicht gefunden wurde, oder falsch ist soll weiter geprüft werden.
Das weiter Prüfen sieht so aus, das eine identische SQL Abfrage an den Server gesendet wird, jedoch ohne das auf die manuelle Freischaltung eingegangen wird. Ist dann bei dieser Abfrage etwas nicht in Ordnung, so ist das Passwort oder der Benutzername falsch bzw. nicht vorhanden. Trifft beides jedoch zu und es wird eine 1 zurückgegeben (Also die Angaben stimmen mit denen in der DB überein.) bleibt nur noch, das der Nutzer noch nicht freigeschaltet wurde. (Im Skript ist das mit Fehlercode 1 und Fehlercode 2 angegeben, wobei die entsprechende Fehlermeldung im dynamischen bezug steht. (Bzw. genauer in der Logik die alle Seiten verbindet.)
Problem:
Unabhängig davon was man falsch im Login eingibt, es erscheint immer nur der String $error_msg = "Der Benutzername oder das Passwort ist falsch. ". Aber ich verstehe nicht so ganz warum... (Wenn die Nutzerdaten stimmen funktioniert der Login und man kommt auf die nächste Seite bzw. diese wird dynamisch nachgeladen.)
Hardware:
Das Testsystem, auf dem ich die Skripte Teste besteht aus 2 virtuellen Apache Webservern (mit fester IP), auf dem einen ist eine Postgesql DB, auf dem anderen eine Mysql DB installiert. Auf der mysql DB liegen die Daten der Webseite. Genutzt werden alle erforderlichen Resourcen in der aktuellsten Version. (Also php, mysql server, postgresql server usw.) Falls ihr diesbezüglich noch weitere angaben benötigt, stelleich euch diese gerne zur Verfügung.
Schlosswort:
Ich hoffe ich konnte meine Problematik einigermaßen verständlich darlegen und vielleicht hat jemand eine Idee, was ich übersehen habe. Jedenfalls würde ich mich über eine Rückmeldung sehr freuen.
mfg: DanteGabriel
EDIT:
Der SQL Befehl
$sql = '
SELECT
Freischaltung
FROM
user
WHERE
Username = ?
';
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 179237
Url: https://administrator.de/contentid/179237
Ausgedruckt am: 22.11.2024 um 18:11 Uhr
9 Kommentare
Neuester Kommentar
Hallo,
schnelle Idee ohne jetzt alles bis ins letzte Durchdacht zu haben : Hast du beim Hinzufügen der neuen Spalte "Freischaltung" einen Default-Wert angegeben oder stehen da jetzt aktuell eventuell NULLs in dieser Spalte drin?
Dann würde das erste IF immer in den ELSE-Teil laufen weil da eine 0 als Wert bei SQL rauskommt wenn ich das richtig sehe, d.h. Passwort-Prüfung, die dann in die Hose geht.
schnelle Idee ohne jetzt alles bis ins letzte Durchdacht zu haben : Hast du beim Hinzufügen der neuen Spalte "Freischaltung" einen Default-Wert angegeben oder stehen da jetzt aktuell eventuell NULLs in dieser Spalte drin?
Dann würde das erste IF immer in den ELSE-Teil laufen weil da eine 0 als Wert bei SQL rauskommt wenn ich das richtig sehe, d.h. Passwort-Prüfung, die dann in die Hose geht.
Unabhängig davon was man falsch im Login eingibt, es erscheint immer nur der String $error_msg = "Der Benutzername oder das Passwort ist falsch.
Stimmt, ist ja auch völlig logisch.
Die
$error_msg
ist deine else-Bedingung, sie tritt also in jedem Fall ein wo $Fehlercode
nicht 1 ist.Und jetzt liest du dir das mal durch:
http://php.net/manual/de/language.variables.scope.php
Übrigens: COUNT(*) ist nur in genau einem Fall wesentlich schneller als ein normales SELECT:
SELECT COUNT(*) FROM table
. In allen anderen Fällen liegt die Hauptlast bei der WHERE-Bedingung.Also spar dir das COUNT, lies die Daten direkt aus und und wirst dieses hässliche if-Konstrukt inkl. zweiter Abfrage auch noch los.
Achso den != gibt es in SQL nicht?
natürlich gibt es den - ABER: NULL ist kein Wert - nur ein Zustand, und kann nicht mit != geprüft werden.siehe dazu; http://dev.mysql.com/doc/refman/5.1/de/comparison-operators.html
Der Fehler lag wie Dog schon richtig sagte darin, das die Ergebnisse der Varriablen nicht global definiert waren.
Schön, dass du von selbst drauf gekommen bist
funktioniert die Abfrage sowohl mit IS NOT null, als auch mit != 0.
Stimmt, beides ist ja uch ungleich NULL.
Was aber nicht geht ist
!= NULL
weil NULL kein gültiger Teil einer Vergleichsoperation ist.mysql> SELECT 1 != NULL;
+-----------+
| 1 != NULL |
+-----------+
| NULL |
+-----------+
mysql> SELECT 1 IS NOT NULL;
+---------------+
| 1 IS NOT NULL |
+---------------+
| 1 |
+---------------+