PHP Weitere PHP Anfänger-Fragen (inkl. COOKIES und nem Forum)

Don_SyStEmS

Cadet 3rd Year
Registriert
Juni 2009
Beiträge
53
Hi,

ich habe wieder ein paar Fragen zur einer Seite, die ich gerade programmiere.

Folgende "Probleme" gibt es:
  1. Login-Problem (Dokument erloschen)
  2. Cookies lassen sich nicht immer löschen
  3. Datenbankstruktur für ein Forum (selbstprogrammiert)
  4. Datenbankstruktur für Private Nachrichten (folgt noch)
  5. Tapatalk-Integration(für weite Ferne geplant)

Meine Lösungsansätze:
1. Klick, Aktuell über einen CSRF-Token gelöst, aktzeptable Lösung, leider nicht perfekt.
2. Aktuell speicher ich so Cookies:
PHP:
function create_cookie($uid,$expire_ = 0, $add_infos = array()){
  // $add_infos ist für später gedacht
  $user = user_load($uid);      // Lädt simpel alle User-Informationen
  
  $name = $user->uid;
  $value = md5($user->email); // Irgendetwas verschlüsseltes, was nur dem User zugeordnet werden kann?
  $expire = $expire_;
  $path = '/';
  $domain = str_replace('http://','.',url(FALSE));  // Liefert .example.com zurück
  $secure = FALSE;
  $httponly = TRUE;
  
  return setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
Ich bin mir nicht sicher, ob ich alles richtig gemacht habe, denn wenn ich beim Ausloggen folgendes Ausführe wird der Cookie nicht immer gelöscht bzw. variiert das Verhalten zwischen einem meinem Webserver und meinem Lokalen Server:
PHP:
if(IS_LOGGED_IN){
  setcookie($user->uid,'',time()+1);
}

Oder ganz einfach ausgedrückt. Ich schaffe es nicht, dass ein User eingeloggt bleibt, sofern er die Checkbox beim Einloggen abhackt.

3. Da ich kein Forum zum Intigrieren gefunden habe (bswp. ist phpBB einfach zu oversized) bin ich dazu gezwungen selber eins zu programmieren und habe mir folgende Datenbankstruktur ausgedacht.
Wenn jemand von euch ein simples aber durchdachtes Forum zum Intigrieren kennt (und es natürlich kostenlos/open source ist), dann immer her damit.

forumsse14.png
Was meint ihr, welche wirklich wichtigen Spalten Fehlen?
Ansonsten werde ich noch weitere Fragen ergänzen, falls mir welche einfallen bzw. falls ich noch weitere Fehler entdecke. :D
 
Zuletzt bearbeitet:
Die User- und Rechteverwaltung hatte ich bereits in anderen Tabellen umgesetzt.

Es wäre doch sinnvoller die Anzahl der Posts in der Datenbank zu speichern, anstatt bei jedem Seitenaufruf ein SELECT COUNT(*) zu machen, oder?
 
Zuletzt bearbeitet:
Zu deinen Cookies:
Was mir so auffällt:
Dein Cookiewert ist immer der selbe, aber von Nutzer zu Nutzer verschieden.
Dein Name ist immer der selbe, aber von Nutzer zu Nutzer verschieden.
Meine Idee:
name ist immer der selbe (z.B. login oder sessionid)
value ist ein sha1(microtime().id."salt") oder in die Richtung
Wie bekommst du dann den User aus deiner value?
Du speicherst in der Datenbank zu jedem Nutzer ab, welche sessionid dem zugeordnet ist.
Wenn sich jemand ausloggt, setzt du diese in der DB einfach auf "" und schon ist er immer abgemeldet. Selbst wenn der Cookie bestehen bleibt.
Zum Löschen: setzt eine Zeit in der Vergangenheit also setcookie('sessionid','',time()-3600); dabei ruhig ne größere Zeit, Uhren sind nicht immer genau gestellt.

Mal ne Frage zu deinen varchar in der DB, warum nimmst du nicht einfach Text als Datentyp?
Ist die Beziehung mit _head und _body nicht verkehrtherum (in der Beschriftung) von der Anlage stimmts ja.
Welche Felder fehlen: programmier mal dein Forum, dann wirst du es schnell feststellen.
 
Ist die Beziehung mit _head und _body nicht verkehrtherum (in der Beschriftung) von der Anlage stimmts ja.
So hatte ich mir das gedacht:
asdtqrsmh.png
Mal ne Frage zu deinen varchar in der DB, warum nimmst du nicht einfach Text als Datentyp?
So weit ich weiß reserviert MYSQL einem Text-Feld 64KB während ein Varchar-Feld maximal 255Byte reserviert bekommt, wobei ich das aufgrund deiner Frage inzwischen anzweifle. :)

Welche Felder fehlen: programmier mal dein Forum, dann wirst du es schnell feststellen.
Nun ja, ich wollte halt nicht mit totalem Mist anfangen, deswegen frage ich vorher. Erweitern muss man das sowieso.

Wie bekommst du dann den User aus deiner value?
Du speicherst in der Datenbank zu jedem Nutzer ab, welche sessionid dem zugeordnet ist.
Wenn sich jemand ausloggt, setzt du diese in der DB einfach auf "" und schon ist er immer abgemeldet. Selbst wenn der Cookie bestehen bleibt.
Ich gebe jetzt einfach mal das wieder was ich verstanden habe, damit du erkennst was ich nicht verstanden habe.

Loggt sich ein User ein wird die aktuelle Session_ID in der Datenbank gespeichert.
Es wird ein Cookie mit dem namen 'session_id' angelegt, dessen verschlüsselter Inhalt sowieso nicht von Bedeutung ist.
Loggt sich der Benutzer aus, dann wird der Datenbankeintrag und das Cookie gelöscht.(genullt)

Wenn ich jetzt aber möchte, dass der User einmal bei der Anmeldung eine kleine Checkbox abhackt um angemeldet zu bleiben, dann muss das ja irgendwie im Cookie gespeichert werden. Also irgend eine eindeutige Information zum User selbst. Und die wäre?

ODER ich habe es etwas falsch verstanden und das Cookie hat denselben Namen wie der Wert in der Datenbank!?

Übrigens, wäre es nicht sinnvoller das Forum nach einem Leitfaden (sofern es denn einen Gibt) von Tapatalk zu programmieren, da mir die Integration dessen schon wichtig war.
 
Zuletzt bearbeitet:
Damit der Nutzer angemeldet bleibt, musst du nur dafür sorgen, dass sein Cookie nicht beim Schließen des Browsers gelöscht wird. Dazu musst du bei expire ein Zeitpunkt angeben, wann der Cookie abläuft, also in der Art von setcookie('sessionid',$value,time()+86400*30);. Das wäre dann ein Monat (86400=24*60*60).

Ich halte es für nicht clever, wenn der Name eines Cookies einen Wert darstellt, weil du dann nicht einfach einen weiteren Cookie hinzufügen kannst, ohne dass es zu Uneindeutigkeiten kommt.

Die Information steckt in dem verschlüsselten Inhalt des Cookies, solange du davon ausgehen kannst, dass dieser eindeutig ist (also sha1 mit einer eindeutigen Information (z.B. der User-ID)), kannst du damit den Nutzer zuordnen, ohne dass ein Außenstehender das könnte.
Dadurch, dass der Wert in der Datenbank beim Ausloggen auch zurückgesetzt wird, stellst du sicher, dass niemand danach sich mit dem Cookie noch anmelden kann. Welcher Wert der Cookie dann hat ist irrelevant, da es einfach nicht gültig ist.

Also Anmeldung:
PHP:
$unique_hash=generate_uhash($_POST["name"],$_POST["password"]);
if($unique_hash){
mysql_query("update user set sessionid=$unique_hash where user=".$_POST["name"]);
setcookie("sessionid",$unique_hash,$_POST["permanent"]?time()+86400*30:0);
}else{echo "Name oder Passwort falsch";}
Abmeldung
PHP:
function get_userid(){
return mysql_fetch_row(mysql_query("select distinct ID from user where sessionid=".$_COOKIE["sessionid"]))[0];
}
$uid=get_userid();
mysql_query("update user set sessionid='' where ID=$uid");
setcookie("sessionid","",time()-3600);
 
Ich habe das jetzt wie folgt gelöst, abes es funktioniert immer noch nicht:
PHP:
function create_cookie($expire = 2592000, $add_infos = array()){
  
  $name = 'stay_logged_in';
  $value = md5('iwas_'.microtime(true));
  $path = '/';
  $domain = str_replace('http://','.',url(FALSE));
  $secure = FALSE;
  $httponly = TRUE;
  
  setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
  
  return $value;
}
// User-Validierung bestanden...
  if(isset($_POST['login_stay']) AND $_POST['login_stay'] == 1){
    $value = create_cookie();
    mysql_query("UPDATE user SET sessionid='$value' WHERE uid='$_infos->uid'");
  }
$_SESSION['user']['uid'] = $_infos->uid;
Das wird nur ausgeführt, wenn der User das Anmeldeformular absendet.
Wenn ich danach print_r($_COOKIE); ausführe bekomme ich folgendes:
PHP:
Array
(
    [phpbb3_gvr87_k] => 
    [phpbb3_gvr87_u] => 2
    [phpbb3_gvr87_sid] => 8af6c2d9f3af6d4f18bf890fc98eed00
    [style_cookie] => null
    [PHPSESSID] => dljc52jmdskjqfl28vqemc48i6
)
Es fehlt der Wert [stay_logged_in] => md5-hash.

Und ich weiß nicht wieso. :S
 
Was muss das Forum denn können und was macht es überladen?
 
Nun ja, im Endeffekt sollen User Thread erstellen und Antworten posten können. :D

Später möchte ich das Forum in Tapatalk intigrieren, damit man es auch mobil nutzen kann.

Was mir an einem fertigen Forum wie phpBB nicht gefällt ist, dass es ja im Endeffekt ein eigenes CMS ist (ein stupides Forum braucht doch keine 63 Tabellen in der Datenbank) und somit mein Programmierteil entfällt.
Inzwischen sehe ich es aber nicht mehr als wirklich schwer an ein eigenes Forum zu programmieren. (nun ja, ich bin optimistisch :D)
 
Zuletzt bearbeitet:
Also du verwendest eine Session und willst, dass du angemeldet bleibst.

Dann musst du deine Session so konfigurieren, dass diese länger gültig ist.

Was du da Programmierst, ist irgendwie.... du hast's nicht verstanden.
Also HTTP und PHP arbeitet i.d.R. zustandslos. Das bedeutet, du weißt nicht, was vorher passiert ist. Außer, eu verwendest ein Cookie, der dir diese Information speichert. Also wie ein verstecktes Feld in einem Formular, welches immer mitgesendet wird.

Beispiel PHPSESSID. Damit kann PHP die Sessionvariablen, die auf dem Server gespichert sind, wiederfimden und ein Zustand speichern. Wenn du jetzt eimgellogt bleiben willst, dann muss deine Session länger Leben. Google hilft.
 
Das bedeutet, du weißt nicht, was vorher passiert ist. Außer, eu verwendest ein Cookie, der dir diese Information speichert.
Ist es nicht das was ich hier versuche zu programmieren?

Ich speicher eine bestimmte Information in der Datenbank und zeitgleich als Cookie.
Woran ich gerade scheitere ist einfach nur die Informationen aus dem auszulesenden Cookie zu erhalten um dann den User wieder einzuloggen.

Aus meiner Sicht muss ich die Laufzeit der Session nicht verlängern, da das Cookie ja eine bestimmte Laufzeit hat und bei jedem Seitenaufruf ja neu geladen wird und der User somit neu angemeldet wird.

Es ist natürlich toll, dass du mir sagst, dass Google mir hilft aber ich habe so ziemlich alles durch Google gefunden und gelernt und wende mich an euch weil ich eben nicht weiterkomme und nicht, weil ich mir denke ja die machen mir das schon.

Du siehst meinen (anscheinend) fehlerhaften Code bzw. erkennst meinen (anscheinend gravierenden) Denkfehler und anstatt mir zu erläutern was ich falsch gemacht habe verweist du mich auf Google.

Edit: Fehler bei der Zeitausgabe gefunden.
 
Zuletzt bearbeitet:
Welchen Rückgabewert liefert denn setcookie() in deiner Funktion create_cookie()?

PHP-Dokumentation schrieb:
Rückgabewerte

Erfolgt eine Ausgabe vor dem Aufruf dieser Funktion, wird setcookie() fehlschlagen und FALSE zurückgeben. Wenn setcookie() erfolgreich durchgeführt wird, wird TRUE zurückgegeben. Dies sagt jedoch nichts darüber aus, ob der Benutzer das Cookie auch akzeptiert hat.
 
Die Zeile
PHP:
mysql_query("UPDATE user SET sessionid='$value' WHERE uid='$_infos->uid'");

wird so nicht funktionieren, die Abfrage wird deswegen wohl auch nicht ausgeführt, oder prüfst du deine Tabelle darauf?

PHP:
mysql_query("UPDATE user SET sessionid = '$value' WHERE uid = {$_infos->uid}");
// oder
mysql_query("UPDATE user SET sessionid = '$value' WHERE uid = " . $_infos->uid);
 
Diesen "ich schreib alles in Anführungsstrichel" - Stil sollte man sich eh ganz schnell abgewöhnen. Der verwirrt jegliche Form von Syntax Highlighting und lässt alles irgendwie unlesbar werden.
Armes PHP... mit dir kann mans ja machen.
 
In all meinem Querys kommen die Variablen in einfache Anführungszeichen und es funktioniert jedesmal. ;)

Von Daher kann man das als Fehlerquelle ausschließen.
 
Nur weil PHP so etwas zu lässt heißt das nicht, dass man es machen soll. PHP lädt wirklich zu schlechtem Code ein und bringt sich damit selbst in Verruf.
Tu dir selbst einen Gefallen, pack so etwas immer schon in Konkatenationen oder in sprintf(). Ist um einiges besser, was Wartung und Erweiterung angeht... von IDEs mal abgesehen.
 
Was wäre denn sinnvoller?

PHP:
mysql_query("SET sessionid=".$session_id);

oder

PHP:
mysql_query("SET sessionid='%s'", $session_id);

BTW, ich bräuchte einen (möglichst günstigen) Grafiker für meine Seite, kennt jemand eine Gute Seite wo ich jemanden Finde der das machen würde, also die komplette Seite designen?
 
Die erste Variante taugt schon, du solltest nur sicherstellen, dass
a) $session_id nicht leer ist oder du vor und hinter der Variable ein ' hast.
b) $session_id sauber escaped ist, genau wie alles andere, dass nicht 100% sicher ist. Lieber ein mysql_real_escape_string zu viel als zu wenig.
 
So ich habe jetzt noch ein bisschen was getestet und habe festgestellt, dass trotz (anscheinend) fehlerfreiem Code kein Cookie angelegt wird.

Ich weiß echt nicht woran es liegen kann...
 
Zurück
Oben