Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Problematik bei If abhängiger MYSQL Abfrage - und Ausgabewert

Frage Entwicklung PHP

Mitglied: DanteGabriel

DanteGabriel (Level 1) - Jetzt verbinden

20.01.2012, aktualisiert 13:10 Uhr, 4312 Aufrufe, 9 Kommentare

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:
01.
  
02.
function login($username, $password, $db, $salt) { 
03.
	$password = hash('sha256', $password.$salt); 
04.
	 
05.
	$sql = ' 
06.
		SELECT 
07.
			COUNT(*) 
08.
		FROM 
09.
			user 
10.
		WHERE 
11.
			Username = ? 
12.
		AND 
13.
			Password = ? 
14.
                AND 
15.
                        Freischaltung != 0                 
16.
			';	//Count (also zählen ob vorhanden geht schneller als expliziet den Wert auszulesen und zu prüfen.) 
17.
	$stmt = $db->prepare($sql); 
18.
	$stmt->bind_param('ss', $username, $password); 
19.
	$stmt->execute(); //ausführen 
20.
	$stmt->bind_result($result); //Ergebnis in einer Varriablen result speichern. 
21.
	$stmt->fetch(); //fetchen (speichern in "result"
22.
	$stmt->close(); 
23.
         
24.
    	if($result == 1) { 
25.
            $_SESSION['logged_in'] = true; 
26.
            $_SESSION['username'] = $username;  
27.
            return true; //Die Session muss noch an den Server geschickt werden 
28.
	} else
29.
	    $sql = ' 
30.
		SELECT 
31.
			COUNT(*) 
32.
		FROM 
33.
			user 
34.
		WHERE 
35.
			Username = ? 
36.
		AND 
37.
			Password = ?           
38.
			';	//Count (also zählen ob vorhanden geht schneller als expliziet den Wert auszulesen und zu prüfen.) 
39.
            $stmt = $db->prepare($sql); 
40.
            $stmt->bind_param('ss', $username, $password); 
41.
            $stmt->execute(); //ausführen 
42.
            $stmt->bind_result($result); //Ergebnis in einer Varriablen result speichern. 
43.
            $stmt->fetch(); //fetchen (speichern in "result"
44.
            $stmt->close(); 
45.
            if($result == 1) { 
46.
                $Fehlercode = 1; 
47.
            } else
48.
                $Fehlercode = 2; 
49.
50.
51.
}
Der dynamische Bezug:
01.
if(login($_POST['username'], $_POST['password'], $db, $salt)) { 
02.
	header('Location: /Script/login.php');	 
03.
} else
04.
    if($Fehlercode == 1) { 
05.
        $error_msg = "Sie wurden noch nicht freigeschaltet. Bitte haben Sie noch etwas Gedult. ";          
06.
    } else
07.
        $error_msg = "Der Benutzername oder das Passwort ist falsch. "
08.
09.
}

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.

Mit freundlichen Grüßen: DanteGabriel

EDIT:
Der SQL Befehl
01.
 $sql = ' 
02.
		SELECT 
03.
			Freischaltung 
04.
		FROM 
05.
			user 
06.
		WHERE 
07.
			Username = ?    
08.
			';
Mit entsprechender Anpassung des Skriptverlaufes führt zum gleichen Ergebnis bzw. Problem.
Mitglied: 32067
20.01.2012 um 13:49 Uhr
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.
Bitte warten ..
Mitglied: DanteGabriel
20.01.2012 um 14:02 Uhr
Guter Einwand, hast Recht Danke, der Auto Wert ist Null, hab d.h. mal das Freischaltung != 0 auf Freischaltung != NULL geändert, aber es verändert sich leider nichts am Problem, habs gerade mal ausprobiert.

Mit freundlichen Grüßen: DanteGabriel

edit: Aber ich glaube nicht das es an der NULL liegt, da wie du sagst sonst die erste Abfrage stehts scheitert oder stehts richtig ist. (Das heißt ob man freigeschaltet ist oder nicht spielte keine Rolle) aber so ist es ja nicht. Wenn ich den Nutzer nicht freigeschaltet habe (Testnutzer) kann er sich auch nicht anmelden, schalte ich ihn frei, kann er sich anmelden. (Nur im ersten Fall kommt die falsche Rückmeldung)
Bitte warten ..
Mitglied: nxclass
20.01.2012 um 17:50 Uhr
Freischaltung != NULL
Freischaltung IS NOT NULL

//Count (also zählen ob vorhanden geht schneller als expliziet den Wert auszulesen und zu prüfen.)
in welcher Dimension ist denn das so ?
Bitte warten ..
Mitglied: dog
20.01.2012 um 19:06 Uhr
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.
Bitte warten ..
Mitglied: DanteGabriel
20.01.2012 um 23:27 Uhr
@nxclass:
Achso den != gibt es in SQL nicht? Dachte den würde es auch geben, da es ja =, <>, usw. auch gibt. Aber das erklärt es natürlich Danke

Zu dem Count, warum das genau schneller geht weiß ich nicht so genau, hatte das beiläufig mal am Rande gelesen. Soweit ich das verstanden habe ist das angeblich deswegen so, weil nicht alle Angaben einzeln geprüft und der Wert ausgegeben werden muss, sondern nur die Anzahl der vorkommenden Datensätze (auf die diese Beschreibung passt) erfasst wird. Inwiefern sich das letztlich wirklich auf die Geschwindigkeit auswirkt kann ich nicht beurteilen soweit reicht mein wissen noch nicht. (Hatte mir das als Randnotiz im Script hinterlegt)

@dog:
Also das mit der error_msg verstehe ich jetzt nicht? Die Error_msg wird immer ausgegeben, wenn entweder die Nutzerdaten nicht mit den Logineingaben übereinstimmen oder aber der User noch nicht freigeschaltet ist, es bleibt aber die selbe Variable die dann jedoch nur einen anderen Wert bzw. String hat.

Zu dem Link, wenn ich das richtig verstehe willst du mir damit sagen, das die Variable nur lokal in der Funktion vorhanden ist, da diese nicht global definiert wurde. Das würde in diesem Fall auch erklären warum der else Zweig genommen wird. Es überrascht mich jedoch, da ich beide sowohl die Funktion (die seperat in einer php liegt) als auch die Logik dynamisch via require reingeladen habe. (Dachte damit würde die globale Definition hinfällig.)

Das die Art der Abfrage nicht besonders elegant ist, hatte ich bereits befürchtet. Da ich mich jedoch erst seit kurzem damit beschäftige ist es mir ein Anliegen, das es erst mal so funktioniert wie ich es mir zuerst überlegt hatte, ist dies der Fall kann ich es immer noch effektiver bzw. schöner gestalten. Außerdem finde ich ist der Lerneffekt dann wesentlich größer.

Ich Danke euch beiden jedenfalls, werde bei nächster Gelegenheit das ganze mal austesten.

Mit freundlichen Grüßen: DanteGabriel
Bitte warten ..
Mitglied: nxclass
22.01.2012 um 00:08 Uhr
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
Bitte warten ..
Mitglied: DanteGabriel
25.01.2012 um 11:11 Uhr
Juhu es läuft, Danke für die Hilfe an alle

Der Fehler lag wie Dog schon richtig sagte darin, das die Ergebnisse der Varriablen nicht global definiert waren.

Die Sache mit dem SQL Null od. 0 verwirrt mich jedoch weiterhin, da beide Werte zum gewünschten Ergebnis führen. Ich habe das eben noch mal expliziet getestet, obwohl als Standartwert in der DB "Null" eingetragen ist, funktioniert die Abfrage sowohl mit IS NOT null, als auch mit != 0.

Mit freundlichen Grüßen: DanteGabriel
Bitte warten ..
Mitglied: dog
25.01.2012 um 15:09 Uhr
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.
01.
mysql> SELECT 1 != NULL; 
02.
+-----------+ 
03.
| 1 != NULL | 
04.
+-----------+ 
05.
|      NULL | 
06.
+-----------+ 
07.
 
08.
 
09.
mysql> SELECT 1 IS NOT NULL; 
10.
+---------------+ 
11.
| 1 IS NOT NULL | 
12.
+---------------+ 
13.
|             1 | 
14.
+---------------+
Bitte warten ..
Mitglied: DanteGabriel
25.01.2012 um 18:23 Uhr
Naja alleine drauf gekommen ... ich erinnere mich da an so einen Link... :D

Achso okay, dann hatte mich der Beitrag vorher verwirrt, das Null ein Zustand ist und das gleiche Ergebnis wie die Zahl 0 liefert. Aber so ist es natürlich klar. Danke

Mit freundlichen Grüßen: DanteGabriel
Bitte warten ..
Neuester Wissensbeitrag
Humor (lol)

Linkliste für Adventskalender

(3)

Information von nikoatit zum Thema Humor (lol) ...

Ähnliche Inhalte
PHP
MySQL-Abfrage mit php: Wert + true bzw. false (2)

Frage von tomolpi zum Thema PHP ...

Datenbanken
gelöst MYSQL Abfrage (20)

Frage von datadexx zum Thema Datenbanken ...

Datenbanken
gelöst Row Number bei einer Abfrage sinnvoll einsetzen (1)

Frage von Aximand zum Thema Datenbanken ...

Batch & Shell
gelöst Batch Abfrage Vergleiche mit Variable goto (4)

Frage von Zunaras zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Server
DHCP Server switchen (25)

Frage von M.Marz zum Thema Windows Server ...

SAN, NAS, DAS
gelöst HP-Proliant Microserver Betriebssystem (14)

Frage von Yannosch zum Thema SAN, NAS, DAS ...

Grafikkarten & Monitore
Win 10 Grafikkarte Crash von Software? (13)

Frage von Marabunta zum Thema Grafikkarten & Monitore ...

Erkennung und -Abwehr
Spam mit eigener Domain (12)

Frage von NoobOne zum Thema Erkennung und -Abwehr ...