[PHP] Datenbankzugriffe

Squart

Pomme Etrangle
Registriert
29.01.04
Beiträge
910
Hallo,

wie immer - wenn ich mit PHP ein Problem zu lösen versuche - bin ich am verzweifeln. Ich habe eine MySQL-Datenbank, in welcher Benutzernamen und Passwörter drinnen stehen. Diese sollen mittels Cookies im einzelnen Browser gespeichert werden. Damit ich nicht auf jeder Seite dies manuell überprüfen muss habe ich mir folgende Methode geschrieben:
Code:
function registered_user() {
	if (isset($_COOKIE[user_cookie()]) && isset($_COOKIE[pass_cookie()])) {
		$db = mysql_connect(host(), user(), password());
		mysql_select_db(database());
		
		$ergebnis = mysql_query("SELECT status FROM ". user_table() ." WHERE username = '" .  $_COOKIE[user_cookie()] . "' AND password = '" . $_COOKIE[pass_cookie()]."'");
		$status = mysql_fetch_row($ergebnis);
		
		mysql_close($db);
		return $status[0];
	} else {
		return 0;
	}
}
Das Problem ist nun folgendes: Eine andere PHP-Datei will diese Function aufrufen. Natürlich hat diese auch einen Datenbankzugriff gleichzeitig laufen, es gibt mehrere relevante Tabellen. Nachdem die Funktion registered_user() aufgerufen wurde geht jede weitere MySQL-Anfrage in die Hose. Es kommen dann ungefähr solche Fehlermeldungen:
Code:
mysql_fetch_row(): supplied argument is not a valid MySQL result resource in /Applications/MAMP/htdocs/projekt/index.php on line 50
Falls ich in der Funktion registered_user() keine eigene Datenbankverbindung herstelle bekomme ich natürlich den gleichen Fehler (mit anderer Datei und andere Zeile).
Wie bekomme ich es nun hin, dass meine Datenbankzugriffe sowohl aus der Funktion als auch aus dem PHP-Code der die Funktion aufruft hinhaut?

Viele Grüße
Squart
 

Squart

Pomme Etrangle
Registriert
29.01.04
Beiträge
910
So, da ich nicht viel Zeit habe werde ich dies nun so angehen, dass eine PHP-Datei erst eine Verbindung zur Datenbank aufbaut, sobald die Funktion registered_user() aufgerufen wurde. Ich hasse PHP.

Viele Grüße
Squart
 

kauan

Stina Lohmann
Registriert
31.12.05
Beiträge
1.043
Prinzipiell ist die Funktion mysql_error() in solchen Faellen sehr sehr nuetzlich. Also bei allen mysql_* Commands in etwa folgendes versuchen:
Code:
mysql_connect('foo', 'bar', 'baz') or print(mysql_error());
Somit kennst du den Fehler, den MySQL zurueckgibt. Und der bringt dich sehr oft weiter.
Dasselbe kannst du natuerlich mit den Funktionen mysql_select_db, mysql_query etc. tun.

Gruss
Jonathan
 

Squart

Pomme Etrangle
Registriert
29.01.04
Beiträge
910
Klar, der Fehler war ja schon bekannt: Er konnte keine Datenbank mehr anwählen, die Verbindung war also nicht mehr da. mysql_error() bestätigt dies (No database selected, oder ähnlich). Aber irgendwie schon enttäuschend, dass eine Funktion keine eigene Verbindung zur Datenbank so einfach herstellen kann. Es wäre alles so schön einfach. Wenn dies ein großes Softwareprojekt wäre, dann würde ich wohl daran scheitern...

Naja, danke auf jeden Fall.
 

kauan

Stina Lohmann
Registriert
31.12.05
Beiträge
1.043
Aeh, also irgendwie versteh ich das ganze nun doch nicht so richtig. Was tun diese host(), user() und password() Funktionen? (Keine sehr tolle Namensgebung uebrigens, aber das ist ein Detail).
Du speicherst in einem Cookie (warum eigentlich keine Session? ;)) Host, Benutzernamen und Passwort fuer die Datenbank, und anhand dieser Daten verbindest du dann zur Datenbank?
Prinzipiell muss (und sollte) man die DB-Verbindung nur einmal oeffnen (am besten in einer Datei, die mittels require_once() eingefuegt wird). Und die Verbindung bleibt dann bestehen.
Ich glaube ich sehe dein Problem nicht so ganz ;)

Gruss
Jonathan
 

Bananenbieger

Golden Noble
Registriert
14.08.05
Beiträge
25.515
Nicht böse gemeint, aber Du solltest vielleicht mal ein Tutorial für gutes Web-Applikationsdesign und vor allem SICHERHEIT(!!!) durcharbeiten.

z.B. solltest Du statt Username und Passwort einen Session-Key verwenden. Ich gehe mal davon aus, dass Du nicht nur die eine Tabelle aus der Datenbank verwenden willst, oder? Dann wäre es doch besser, wenn Du die SQL-Verbindung nicht in der registered_user()-Funktion auf-/abbaust, sondern am Anfang/Ende des Gesamtprogramms.
host(), user(), password()??? Statische Variablen aus Funktionen holen ist nicht sehr elegant.
 

Squart

Pomme Etrangle
Registriert
29.01.04
Beiträge
910
Bananenbieger schrieb:
Nicht böse gemeint, aber Du solltest vielleicht mal ein Tutorial für gutes Web-Applikationsdesign und vor allem SICHERHEIT(!!!) durcharbeiten.

z.B. solltest Du statt Username und Passwort einen Session-Key verwenden. Ich gehe mal davon aus, dass Du nicht nur die eine Tabelle aus der Datenbank verwenden willst, oder? Dann wäre es doch besser, wenn Du die SQL-Verbindung nicht in der registered_user()-Funktion auf-/abbaust, sondern am Anfang/Ende des Gesamtprogramms.
host(), user(), password()??? Statische Variablen aus Funktionen holen ist nicht sehr elegant.
Stimmt, elegant ist es mit Sicherheit nicht. Da ich aber schon in den nächsten Tagen (evtl. noch heute) fertig werden sollte bleibt mir keine Zeit mich in das Thema tiefer einzuarbeiten. Daher verstehe ich auch einen großteil der letzten beiden Postings nicht. Wie sollte man es beispielsweise anfangen, dass er es nur am Anfang bzw. Ende des Gesamtprogramms aufbaut? Meiner Desktop-App-lastigen Denkweise würde ich für jede Seite von neuem nachschauen, ob der User registriert ist. Das Programm wird eine Art Portal, wo man nicht vom Anfang bis zum Ende eine gewisse Reihenfolge an Seiten öffnet.
Gut, evtl. lese ich mir doch ein Tutorial über Sessions durch, evtl. wird dann das gesamte einfacher zu programmieren.
Danke schön, ich werde jetzt mal nach euren Hinweisen googlen.

Squart
 

kauan

Stina Lohmann
Registriert
31.12.05
Beiträge
1.043
Ja, von dieser Denkweise musst du in der Webentwicklung wohl weg kommen ;)
Bei einer Webseite ist es ja so, dass die Seite geladen wird, was also bedeutet, dass zu dieser Zeit der PHP Code ausgefuehrt wird. Hier ein Beispiel einer Seite:
- Oeffnen der Datenbank-Verbindung
- Dein eigentliches Script, den Code den du gepostet hast
- Schliessen der Datenbankverbindung (geht auch ohne, ist aber sauberer)
Bei anderen Applikationen (nicht im Web) ist es ja wohl so, dass man auf einen Button klickt oder aehnliches, und dann passiert irgendwas. Bei einer Webapplikation wird aber dein Code komplett ausgefuehrt, daraus HTML Code generiert, und der dann an den Client (Browser) gesendet. Wenn dann der User irgendetwas tut (auf Link klicken, Formulareingaben...) wird die Seite in der Regel neu geladen, wodurch dein ganzer Code erneut durchlaeuft.
Hier sieht man den Unterschied der Webapplikationen - dein Programmcode wird nicht dann ausgefuehrt, wenn der Benutzer deine Seite sieht, sondern zuvor.

Gruss
Jonathan

PS: Nimm dir lieber etwas mehr Zeit (wenn es denn moeglich ist), und mach es dafuer gut. Das hat sich bei mir schon oooft bewaehrt ;)
 

Squart

Pomme Etrangle
Registriert
29.01.04
Beiträge
910
So, habe jetzt ein Tutorial durchgemacht: http://www.php-resource.de/tutorials/read/38/1/

Werde so jetzt meine Anmeldung realisieren. Denke mal, dass dies keine Cookies beherrscht, aber das kann ich dann ja noch gegebenenfalls implementieren.

Also: Noch einmal vielen Dank für eure Hilfe.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
Squart schrieb:
Meiner Desktop-App-lastigen Denkweise würde ich für jede Seite von neuem nachschauen, ob der User registriert ist.
Diese Arbeit brummt man dem Webserver auf und kümmerst sich gar nicht darum! (Es gibt verschiedene AUTH_Module für apache bei uns ist das immer der LDAP Server, ein RDBMS tut's aber auch.) So ist garantiert, daß nicht registrierte Nutzer gar keine oder nur solche Seiten herunterladen können, die für sie bestimmt sind.

In den entsprechenden PHP Variablen liegt dann der Nutzername, des authentifizierten Nutzers. Die Verbindung zum DBMS macht man mit einem speziellem Webserver Account auf, der gilt für alle Nutzer. Aus den PHP Variablen (die übergibt der Webserver an PHP) kann man dann die nutzertypischen Infos filtern.

Eine Session braucht man immer dann, wenn man Daten zu einem Nutzer ablegen muß, die der Nutzer nicht sehen darf, weil er so Kenntnisse über das System erhalten würde, die er nicht besitzen darf. Das hier ist eine Sicherheitsanforderung!

Man kann eine Session anlegen, wenn die Daten zu umfangreich sind, der Nutzer sie aber im Prinzip sehen dürfte. Damit wird die Webapplikation komfortabler.

Nutzereingaben, egal welche, müssen immer mißtraut werden, so daß keine Codeinjections möglich sind!
 

kauan

Stina Lohmann
Registriert
31.12.05
Beiträge
1.043
tjp schrieb:
Diese Arbeit brummt man dem Webserver auf und kümmerst sich gar nicht darum! (Es gibt verschiedene AUTH_Module für apache bei uns ist das immer der LDAP Server, ein RDBMS tut's aber auch.) So ist garantiert, daß nicht registrierte Nutzer gar keine oder nur solche Seiten herunterladen können, die für sie bestimmt sind.
Ich habe dies mal in einer Webapplikation noch etwas weiter getrieben. Die Authentifikation geschah per Session (HTML-Login-Formular, Speichern der User-ID in der Session (ob das so toll ist, sei dahingestellt)). Dann gab es da verschiedene Dateien, die im Verzeichnis /upload lagen. Dort sollten nur bestimmte Benutzer Zugriff haben. Nun schrieb ich ein Script, das dem der Pfad der entsprechenden Datei per Apache RewriteRule uebergeben wurde. Das Script pruefte dann in der Session, ob der Zugriff existierte, und zeigte andernfalls eine Fehlermeldung an.
Es wurde also ein Zugriff auf eine Datei gemacht, z.B. /upload/foo/bar.jpg. Nun wurde mittels RewriteRule der Request auf diese Datei abgefangen:
Code:
RewriteRule ^/upload/(.*)$ /auth.php?file=$1[/quote]
auth.php ueberpruefte dann wie gesagt den Zugriff, und im erfolgreichen Fall wurde mit read_file die Datei ausgegeben.

Okay, das war Off Topic. Aber passt doch ein bisschen hierhin, finde ich. Denn sowas wird oft nicht bedenkt: Beispielsweise hat man auf einer Community-Seite keinen Zugriff auf bestimmte Bilder, wenn man die entsprechende Seite ansehen will. Kennt man aber den genauen Pfad derjenigen Bilder, kann man problemlos darauf zugreifen.

Gruss
Jonathan