hab nun aufgrund des Tutorialwunsches dieses Tutorial hier geschrieben, und los geht´s:
Das Einbinden der Klasse
Erstmal das einfachste von Allem, erstmal muss die Klasse eingebunden werden. Ich benutze hier aus folgendem Grund require_once():
include: fügt eine Datei beliebig häufg ein und lässt das Skript bei Fehlern weiterlaufen und gibt bloß eine Warnung aus. require: Tut das gleiche, jedoch bricht es bei einem Fehler das gesamte Skript ab und gibt ne Fehlermeldung aus. include_once: Gleiche wie include, nur wird hier die Datei nur einmal eingebunden. require_once: Gleicher Zusatzeffekt wie "include_once"
Hier sollte sofort ersichtlich werden, was für uns geeignet ist. Ohne der Datei geht nix, also benutzen wir require, außerdem braucht man die
Klasse nur einmal einzubinden, mehrmals ist nur schädlich für die Performance, also: "require_once()"
Außerdem gibt es noch heftige Performanceunterschiede bei der Angabe des Pfades zur Datei.
Kurz:
Relativer Pfad (Pfad von der Datei aus) wie zB: "/Ordner/datei.php" Ist am schlechtesten geeignet!, da PHP den Pfad erstmal neu berechnen muss, gibt es hier die größten Performanceverluste.
Semiabsoluter Pfad (Datei befindet sich im gleichen Verzeichnis) wie zB "./Ordner/datei.php"
Durch den Punkt wird gekennzeichnet, dass vom gleichen Verzeichnis wie die momentan ausgeführte Datei ausgegangen wird.
Diese Datei ist um einiges besser als die relative Pfadangabe, aber es geht noch besser
Absoluter Pfad (Der gesamte Pfad von der Root-Struktur aus) wie zB "C:\\User\UserName\Desktop\Ordner\datei.php" ist von allen Möglichkeiten am Performancebesten, da hierbei die komplette Zusatzarbeit von PHP abgenommen wird.
Absoluter Pfad in PHP bestimmen
Es gibt eine Konstante namens __FILE__, in dieser ist der momentane Name der Datei definiert.
Nun kombinieren wir das mit der Funktion dirname(), mit dieser Funktion bekommen wir den absoluten
Pfad zu der Datei, die wir als Übergabeparameter übergeben.
PHP
1:
2:
3:
4:
5:
6:
<?php
//RDIR als Abkürzung für: Root-Directory (Wurzelverzeichnis)
define ('RDIR', dirname(__FILE__));
require_once (RDIR . 'login.class.php')
?>
Die Verwendung der PHP-Klasse "Login"
Nachdem wir die Datei nun erfolgreich eingebunden haben, erzeugen wir erstmal ein Objekt, indem wir die Refenz dieser Klasse als Instanz auf in einer
Variable definieren.(Ich liebe es, so zu sprechen xD) Auf Deutsch: wir verwenden den New-Operator
PHP
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
<?php
//RDIR als Abkürzung für: Root-Directory (Wurzelverzeichnis)
define ('RDIR', dirname(__FILE__));
Wichtig für die Verwendung der Klasse sind nur 2 Dinge: die Methode (So nennt man die Funktionen in einer Klasse)
logged_in(), diese checkt, ob man eingeloggt ist oder nicht (Rückgabewert true oder false).
Und natürlich, wie man sich ein- und ausloggt. Dies geht über den Construktor (dazu später mehr) und
über die GET-Variable action. also bei ?action=logout wird man automatisch ausgeloggt und
bei ?action=login halt eingeloggt.
Ist doch ganz simpel, oder?
Diese Klasse hat auch noch den Vorteil, dass sone schwule Weiterleitung nicht mehr nötig ist
Die Klasse im Detail
Allgemein: Die Interzeptormethode (Schönes Wort ) __construct wird aufgerufen, wenn die
Referenz der Klasse gerade per dem New-Operator auf eine Variable übertragen wird.
Sie wird also per Zeile 10 (Siehe Codeschnipel hier drüber) aufgerufen.
Hier wird nun der Status (On oder Off) gesetzt und auf die GET-Variable "action" geprüft.
Die restlichen Methoden sollten per Kommentate gut genug erklärt sein:
<?php
/**
* Die Login-Klasse
*/
class Login
{
//Hat den Wert 0 oder 1, on oder off ;)
private $status;
//Den Namen der Session und des Cookies fest definieren
const SNAME = 'LOGGED_IN';
/**
* Der Konststruktur, er wird bei der Erzeugung
* des Objekts aufgerufen. Prüft auf Sessions und
* Cookies und prüft die GET-Variable "action"
*/
public function __construct ()
{
//Die Session starten
session_start();
//Ist eine Session oder ein Cookie gesetzt?
if(isset($_SESSION[self::SNAME]) or isset($_COOKIE[self::SNAME]))
$this->status = 1;
else
$this->status = 0;
//Erstmal ganz allgemein prüfen,
//ob sich die GET-Variable in der URL befindet
if(isset($_GET['action']))
{
//Wert in einer Variable ablegen
$action = $_GET['action'];
//Wenn der Wert "login" ist...
if($action == 'login')
{
//...prüfen, ob die POST-Variable "dauerhaft" dabei ist,
//um ggf. das Cookie zu setzen. Diese POST-Variable
//stammt von einer Check-Box ;)
if(isset($_POST['dauerhaft']))
$use_cookie = true;
else
$use_cookie = false;
//Die Methode login aufrufen und einloggen,
//evtl. auch das Cookie benutzen
$this->login($use_cookie);
}
//Oder der Wert ist "logout", dann...
else if($action == 'logout')
{
//... wird sich ausgeloggt, indem die
//entsprechende Methode aufgerufen wird
$this->logout();
}
}
} //Konstruktor ENDE
/**
* login()
* @param boolean $use_cookie
* Setzt die Session und ggf. auch das Cookie
*/
public function login ($use_cookie)
{
//Ist der User momentan nicht eingeloggt? Dann...
if(!$this->logged_in())
{
//Status auf 1 (On) setzen
$this->status = 1;
//Session setzen
//Zugriff auf die Konstante per self::SNAME
$_SESSION[self::SNAME] = true;
//Falls gegeben, Cookie setzen
if($use_cookie)
//Die Laufzeit beträgt eine Woche
//60s * 60 = 1 Stunde
//1 Stunde * 60 = 1 Tag
//1 Tag * 7 = 1 Woche
setcookie(self::SNAME, true, (time()+60*60*24*7));
}
}
/**
Prüft einfach bloß die Eigenschaft und
stellst dadurch off der on fest
*/
public function logged_in ()
{
if($this->status == 1)
return true;
else
return false;
}
/**
* Setzt den Status auf 1 (Off) und
löscht ggf. die Session oder das Cookie
*/
public function logout ()
{
if($this->logged_in())
{
$this->status = 0;
//Cookie löschen, indem die Aufenhaltszeit
//in die Vergangenheit gelegt wird
if(isset($_COOKIE[self::SNAME]))
setcookie(self::SNAME, false, (time()-60));
}
}
} //Login-Kasse ENDE
<?php
Viel Spaß damit!
Im Konstruktor muss diese Teil noch angepasst werden:
<?
//Wenn der Wert "login" ist...
if($action == 'login')
{
//...prüfen, ob die POST-Variable "dauerhaft" dabei ist,
//um ggf. das Cookie zu setzen. Diese POST-Variable
//stammt von einer Check-Box ;)
if(isset($_POST['dauerhaft']))
$use_cookie = true;
else
$use_cookie = false;
//Die Methode login aufrufen und einloggen,
//evtl. auch das Cookie benutzen
$this->login($use_cookie);
}
Und zwar müssen hier die Logindaten noch gecheckt werden, zB so:
So ich hoffe, das zeigt das Prinzip soweit ganz gut =)
Anmerkung:
Ich benutze immer Single Quotes (') anstatt Double Quotes ("), weil Single Quotes performaneter
sind, da PHP bei Double Quotes jedesmal den gesamten String nach Variablen durchsucht.
Beispiel:
PHP
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
<?
$var = 'Hallo';
//Ausgabe: Hallo Basti
echo "$var Basti";
echo '<br />';
//Ausgabe: $var Basti
echo '$var Basti';
Gruß Basti!
Post wurde schon 3x editiert, das letzte mal am 01.03.2011 um 11:34 von Andavos
Hehe is ja lustig =)
Hast du dich schon mit OOP richtig auseinandergesetzt?
Mein CMS besteht nur aus diesen Dingern und viel emhr Interzeptormethoden und mit einigen Design Pattern und blabla xD
Kommt auch bald noch hier rein
werd mich da aber durchkämpfen, ansonsten biste ja nciht aus der welt
PS.
Da ist auch bei dir der Fehler
Code
1:
2:
3:
4:
5:
6:
Cookie wurde gesetzt!
Warning: Cannot modify header information - headers already sent by (output started at /var/www/basti/Tutorials/Login/index.php:47) in /var/www/basti/Tutorials/Login/index.php on line 92
Du bist eingeloggt!
Ausloggen
und zwar wenn man auf dauerhaft login klickt
CONTEMPLATION
If today was perfect, there would be no need for tomorrow.
bei mir ist das nicht der Fall. Der Fehler kommt dadurch zu stande, dass du eine Ausgabe machst, bevor der Header fertig gesendet wurde.
Erst braucht PHP eine genaue Anweisung, wie er das Skript zu bearbeiten hat, und dies bestimmt der Header.
Und die Funktion session_start(); ist eine solche Headeranweisung. Ist ja auch Blödsinn, ihm den
Code zu geben und erst beim Abarbeiten zu sagen,
dass er plötzlich auf Sessions achten soll, evtl.
hat er das Lesen der Sessions separat und wird nur geladen, wenn der Header es ihm auch mitteilt.
Lösung:
Diese Codezeile:
PHP
1:
2:
<?
$User = new Login;
Muss vor jeder verdammten Ausgabe sein!
Da er im Konstruktor die Funktion session_start() aufruft
Äh jo, habs nun behoben, war genau das Problem, welches ich vorher erklärt hatte =)
Aber aufm Localhost kam der Fehler nicht...
War halt ein Fehler im chronischen Ablauf
Natürlich darf auch vor setcookie() keine Ausgabe erfolgen, da dies auch eine Header-Anweisung ist!
Das Beste daran finde ich die Tips zur Performance Die werde ich mir merken!
Ganz kleine Anmerkung:
In einem Kommentar steht, dass ein Tag 1h * 60 ist. Das stimmt natürlich nicht, es sind nur 24 Stunden . Da es im Code aber richtig steht, wirkt sich das nicht auf die Zeit aus.
Aber:
Ein Problem gibt es ja für cookies: man kann sie ändern.
mit dem ff 3.5 mag das addon gerade nicht gehen, aber mit dem opera kann man die cookies ganz einfach ändern, also solltest du dir da noch was überlegen mitdem loginstatus..
mit den Cookies sehe ich da eher weniger ein Problem. Sollte irgendwer die mit Absicht ändern,
passiert sowieso nix schlimmes, er ist dann halt nur ausgeloggt, da das Skript nur mit den richtigen Werten arbeiten kann.
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\xampp\htdocs\admin.php:12) in C:\xampp\htdocs\login.class.php on line 23
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\xampp\htdocs\admin.php:12) in C:\xampp\htdocs\login.class.php on line 23
Falsches PasswortSie müssen sich einloggen, um in den Administrationsbereich der Seite zu gelangen.
[hier ist das pw-Fenster]
Dauerhaft einloggen
Falsches Passwort
<-- ich bekomme diese Ausgabe an den Kopf geworfen.
30.05.2010, 11:19
Vielgeist
Mitglied
Exzellenter User
Dabei seit: 26.12.2008
Herkunft: Berlin
Posts: 1371