Folgende Klasse benutze ich für die Session-Verwaltung:
Wenn ich '$transSID = false;' in '$transSID = true;' abändere, bleibt mein Skript in einer Endlosschleife hängen bzw. bricht mit der Meldung "Redirection limit reached for this page" ab. Wenn ich 'false' stehen lasse, kannn ich keine Cookies zum Speichern der Session-ID verwenden.
Liegt das an der Konfiguration des IIS? Ich verwende PHP 4.3.2 - also die neueste, stabile Version. Ich glaube unter Linux mit Apache 2.0 funktioniert das - nur leider bin ich auf der Arbeit an Windows und IIS gebunden. Sieht da jemand, wo der Fehler liegt?
PHP-Code:
class session {
var $version = 106; // V1.06
var $usesCookies = false; // Client nimmt Cookies an
var $transSID = false; // Wurde mit --enable-trans-sid
// kompiliert
//---------------------------------------------------------
/**
* Konstruktor - nimmt, wenn gewünscht einen neuen
* Session-Namen entgegen
*/
function session($sessionName="SESSID") {
// Cookies deaktivieren:
ini_set("session.use_cookies", "1");
// automatisches Anhaengen der Session-ID an URLs im Dokument
ini_set("session.use_trans_sid", "1");
// festlegen, wie das Rewriting per TransSID erfolgen soll:
ini_set("url_rewriter.tags", "a=href,area=href,frame=src,form=action");
$this->sendNoCacheHeader();
// Session-Namen setzen, Session initialisieren
session_name(isset($sessionName)
? $sessionName
: session_name());
session_start();
// Prüfen ob die Session-ID die Standardlänge
// von 32 Zeichen hat,
// ansonsten Session-ID neu setzen
if (strlen(session_id()) != 32)
{
mt_srand ((double)microtime()*1000000);
session_id(md5(uniqid(mt_rand())));
}
// Prüfen, ob eine Session-ID übergeben wurde
// (über Cookie, POST oder GET)
$IDpassed = false;
if ( isset($_COOKIE [session_name()]) &&
strlen($_COOKIE [session_name()]) == 32
) $IDpassed = true;
if ( isset($_POST [session_name()]) &&
strlen($_POST [session_name()]) == 32
) $IDpassed = true;
if ( isset($_GET [session_name()]) &&
strlen($_GET [session_name()]) == 32
) $IDpassed = true;
if(!$IDpassed) {
// alte Session-Dateien loeschen:
// Es wurde keine (gültige) Session-ID übergeben.
// Script-Parameter der URL zufügen
$query = (isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] != "") ? "?".$_SERVER["QUERY_STRING"] : "";
header("Status: 302 Found");
// Script terminiert
$this->redirectTo($_SERVER["PHP_SELF"].$query);
}
// Wenn die Session-ID übergeben wurde, muß sie
// nicht unbedingt gültig sein!
// Für weiteren Gebrauch merken
$this->usesCookies =
(isset($_COOKIE[session_name()]) &&
@strlen($_COOKIE[session_name()])
== 32);
}
### -------------------------------------------------------
/**
* Cacheing unterbinden
*
* Ergänze/Override "session.cache_limiter = nocache"
*
* @param void
* @return void
*/
function sendNoCacheHeader() {
header("Expires: Sat, 05 Aug 2000 22:27:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
header("Cache-Control: post-check=0, pre-check=0");
}
### -------------------------------------------------------
/**
* HTTP-Redirect ausführen (header("Location: ...")
*
* Diese Methode berücksichtigt auch nicht-standard Ports
* und SSL. Ein GET-Parameter beim wird bei Bedarf
* (Session-ID-Fallback) an die URI drangehängt. Nach
* dem Aufruf dieser Methode wird das aktive Script
* beendet und die Kontrolle wird an das Ziel-Script
* übergeben.
*
* @param string Ziel-Datei (z.B. "index.php")
* @return void
*/
function redirectTo($pathInfo) {
// Relativer Pfad?
if ($pathInfo[0] != "/")
{ $pathInfo = substr(getenv("SCRIPT_NAME"),
0,
strrpos(getenv("SCRIPT_NAME"),"/")+1
)
.$pathInfo;
}
// Läuft dieses Script auf einem non-standard Port?
$port = !preg_match( "/^(80|800|443)$/",
getenv("SERVER_PORT"),
$portMatch)
? ":".getenv("SERVER_PORT")
: "";
// Redirect
header("Location: ".(($portMatch[1] == 443) ? "https://" : "http://").getenv("SERVER_NAME").":".$portMatch[1].$this->url($pathInfo));
exit;
}
### -------------------------------------------------------
/**
* Entfernt mögliche abschließende "&" und "?"
*
* @param string String
* @return string String ohne abschließende "&" und "?"
*/
function removeTrail($pathInfo) {
$dummy = preg_match("/(.*)(?<!&|\?)/",$pathInfo,$match);
return $match[0];
}
### -------------------------------------------------------
/**
* Fallback via GET - wenn Cookies ausgeschaltet sind
*
* @param string Ziel-Datei
* @return string Ziel-Datei mit - bei Bedarf - angehängter Session-ID
*/
function url($pathInfo) {
if ($this->usesCookies || $this->transSID) return $pathInfo;
// Anchor-Fragment extrahieren
$dummyArray = split("#",$pathInfo);
$pathInfo = $dummyArray[0];
// evtl. (kaputte) Session-ID(s) aus dem Querystring entfernen
$pathInfo = preg_replace( "/[?|&]".session_name()."=[^&]*/",
"",
$pathInfo);
// evtl. Query-Delimiter korrigieren
if (preg_match("/&/",$pathInfo) && !preg_match("/\?/",$pathInfo))
{
// 4ter Parameter für "preg_replace()" erst ab 4.0.1pl2
$pathInfo = preg_replace("/&/","?",$pathInfo,1);
}
// Restmüll entsorgen
$pathInfo = $this->removeTrail($pathInfo);
// Session-Name und Session-ID frisch hinzufügen
$pathInfo .= preg_match("/\?/",$pathInfo) ? "&" : "?";
$pathInfo .= session_name()."=".session_id();
// Anchor-Fragment wieder anfügen
$pathInfo .= isset($dummyArray[1]) ? "#".$dummyArray[1] : "";
return $pathInfo;
}
### -------------------------------------------------------
/**
* Fallback via HIDDEN FIELD - wenn Cookies ausgeschaltet sind
*
* Ohne Cookies erfolgt Fallback via HTML-Hidden-Field
* (für Formulare)
*
* @param void
* @return string HTML-Hidden-Input-Tag mit der Session-ID
*/
function hidden() {
if ($this->usesCookies || $this->transSID) return "";
return "<INPUT type=\"hidden\"
name=\"".session_name()."\"
value=\"".session_id()."\">";
}
} // of class
Liegt das an der Konfiguration des IIS? Ich verwende PHP 4.3.2 - also die neueste, stabile Version. Ich glaube unter Linux mit Apache 2.0 funktioniert das - nur leider bin ich auf der Arbeit an Windows und IIS gebunden. Sieht da jemand, wo der Fehler liegt?
EDIT:
code.tags -> php.tags by Abraxax