Ik ben de laatste tijd bezig geweest met een session handler om sessies naar de database te schrijven. Nu gaat er alleen iets mis met het schrijven naar de database. De sessie wordt geschreven, alleen is het sessie_id regelmatig 0 en wordt de waarde nooit ingevuldt. De schrijf functie van de handler is:
<?
function write($ses_id,$ses_data)
{
//$ses_id is het id van de sessie, net zoals bij de read functie
//$ses_data is de data die geschreven moet worden
//we gaan de controle aanmaken, zodat de sessie ook alleen bij 1 ip geldig is:
$controle = md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);
//uiteraard willen we alles weer in de DB schrijven. Hiervoor weer een query opstellen:
$query = "INSERT INTO Sessies"; //we gaan de gegevens in de tabel Sessies opslaan
$query .= " (sessie_id,tijd_aangemaakt,waarde, controle)"; //de velden waar de gegevens moeten komen
$query .= " VALUES"; //uiteraard moeten er gegevens in komen
$query .= " ('".mysql_real_escape_string($ses_id)."', NOW(),
'".mysql_real_escape_string($ses_data)."', '".$controle."')"; //en dit zijn de gegevens die we in de DB zetten
//nu gaan we die query weer uitvoeren
$result = mysql_query($query);
//en kijken of dat gelukt is
if(!$result)
{
//niet gelukt
return false; //terugsturen dat het verkeerd ging
}
else
{
//het is gelukt waarschijnlijk gelukt. Nog 1 laatste check:
if(mysql_affected_rows() != 1)
{
//het aantal aangepaste rijen is niet 1. Dus blijkbaar ging er toch iets fout.
return false; //terugsturen dat er iets fout ging
}
else
{
//alles ging goed en de sessie is opgeslagen
return true; //terugsturen dat alles gelukt is
}
}
}?>
Schrijven gebeurt gewoon door $_SESSION['bla'] = "tekst";
Er ontstaan geen foutmeldingen. Dat is juist het hele probleem. Hij wil alleen gewoon de data niet juist in de DB zetten. Snap niet waarom dat niet gebeurt?
session_start(); staat overal boven. mysql_error() geeft ook niets.
Wat zou je moeten krijgen als je de query echo'd
session_start is niet nodig indien er een eigen session handler is. Je moet geloof ik zorgen dat de sessie pas wordt gesloten na de laatste </html> dmv.
Hoe registreer je de functie, en kloppen de andere callbacks wel? Zie ook [php]session_set_save_handler[/php].
Verder, weet je zeker dat sessie_id een nummer is? PHP Sessies zijn namelijk een md5-hash van iets, en ik merk niet dat je ergens een eigen sessie-id genereert. Een type CHAR(32) zou beter op z'n plaats zijn.
Overigens is de Varchar wel groot genoeg? Bij mijn weten heeft die een limiet van 255 karakters, en wanneer je grotere dingen in de sessie zet (de data van een sessie is het resultaat van [php]serialize[/php] uitgevoerd op de $_SESSION array) wordt je data maar deels opgeslagen. Met als gevolg dat bij de eerst volgende keer dat je de sessie probeert uit te lezen, unserialize (wat intern gebruikt wordt om de $_SESSION array vervolgens weer te vullen) zal zeuren over een niet geldige waarde, en niets zal teruggeven. Resultaat: geen sessie meer. Ik zou voor een TEXT of misschien wel BLOB veld gaan. BLOB omdat je de data niet als tekst hoeft te behandelen, al is het in weze gewoon een enorme string waar je niet veel mee kan. Het vertoont op zich vrij veel overeenkomsten met binaire data.
session_start is niet nodig indien er een eigen session handler is.
Is dat zo? Bij mijn weten behandel je in jouw php-code een sessie zoals je altijd een sessie behandeld, maar wordt de sessie intern alleen anders verwerkt. Niet meer in een bestandje maar in de database. session_start() heb je dan ook gewoon nodig.
Of ik sla de plank flink mis, wat nooit helemaal is uit te sluiten...
[quote='Jurgen schreef op 19.03.2008 17:45']session_start is niet nodig indien er een eigen session handler is.
Is dat zo? Bij mijn weten behandel je in jouw php-code een sessie zoals je altijd een sessie behandeld, maar wordt de sessie intern alleen anders verwerkt. Niet meer in een bestandje maar in de database. session_start() heb je dan ook gewoon nodig.
Of ik sla de plank flink mis, wat nooit helemaal is uit te sluiten...[/quote]
Zoals ik gelezen heb in PHP 5 voor gevorderden is dit niet nodig (ik dacht nl. ook eerst dat de schrijver het fout had). Zelf heb ik dit nog niet getest maar zo zou het moeten zijn. Wel benadrukte hij dat er na de laatste </html> een session_write_close() moet komen anders wordt de sessie niet geschreven naar de database. Omdat hij 2 functies aanroept bij het sluiten, nl. schrijven en sluiten.
wat ik heb gelezen moet session_start weldegelijk gebruikt worden en wordt de sessie intern anders behandeld. Zoals Frank al zegt.
@Jelmer: De waarde is in mijn geval niet zo heel groot, het slaat 2 sessie variabelen op en dat past prima in een varchar veld. Ik snap echter je punt, waardoor het inderdaad handiger wordt. Daarnaast ga ik nu eens testen of het id in een char veld werkt.
Edit: Inderdaad is een char veld hier de oplossing. Ik ging ervanuit dat het id uit een nummer zou bestaan, maar dat is niet het geval. Een char veld van 32 karakters biedt uitkomst, daar het id ook precies 32 karakters lang wordt.