werken met tijd
Ik heb een database(online) waarin de tijd van het inloggen wordt opgenomen.
Als de user uitlogd wordt dit record verwijderd , maar sommige users loggen niet uit , ze verlaten gewoon zonder uitloggen, dus het record blijft bestaan.
Nu wil ik zelf het record verwijderen door te gaan kijken naar de inlogtijd en deze vergelijken met de huidge tijd - 2uur.
Als de inlogtijd kleiner is dan de huidige tijd -2 uur mag het record verwijderd worden.
Ik slaag er niet in deze tijden te kunnen vergelijken , eook niet om de tabel af te lopen.
Wie kan mij hiermee helpen AUB
Een query die je kan gebruiken is als volgt:
Je insert altijd een record met de huidige tijd en als iemand uitlogt, vul je ook de kolom "uitgelogd" met dat tijdstip.
Dat record laat je staan.
Dan kun je nog steeds dezelfde info opvragen die je nu wilt hebben, maar dan met de query
SELECT *
FROM onliners
WHERE inlogtijd > now() - interval 2 hour AND uitgelogd is null
Voordeel:
Je kunt ook terug kijken wanneer iemand voor het laatst online was
--
INSERT INTO onliners (userid, inlogtijd) VALUES (1234, NOW());
uitloggen
UPDATE onliners SET uitgelogd = NOW()
WHERE userid = 1234
ORDER BY inlogtijd DESC
LIMIT 1;
Maar niet iedereen logt altijd uit. Soms wissen zelf hun cookies, of komen ze terug als de koekjes alweer over hun houdbaarheid zijn.
Wat is precies het probleem van ingelogd blijven (of het automatisch doorstarten ervan)?
Het probleem is misschien wel juist het meten van inactiviteit. Dit zou je bijvoorbeeld op kunnen lossen door een houdbaarheidsdatum en -tijd in te stellen. Elke keer als een ingelogd persoon de site ververst, schuif je de "verloopdatum" vooruit, uitgaande van de huidige tijd plus een timeout (die je zelf zou kunnen tweaken). In deze routine zou je ook kunnen controleren of er logins verlopen zijn, en deze on-the-fly verwijderen, of je neemt dit op in een aparte routine (cron) die dit periodiek opschoont.
De vraag is ook: waarvoor gebruik je dit: is dit om ingelogde/actieve gebruikers te managen, of is dit, zoals hierboven aangehaald, een middel om een soort van overzichtje te genereren van de (op dat moment) "actieve" gebruikers?
Ik weet ook niet in welke setting dit alles gebruikt wordt. Misschien moeten de gebruikers ook opgevoed worden om uit te loggen als ze klaar zijn met het systeem?
Het wordt mogelijk nog interessanter als je een "onthoud mij" functionaliteit hebt (voor niet-publieke machines), waarbij gebruikers in principe onbeperkt ingelogd zijn, zo lang dit technisch/praktisch mogelijk blijft.
Het oorspronkelijke probleem heeft waarschijnlijk ook zijn oorsprong in het feit dat er geen "houdbaarheidsdatum" op de records zit, en er vervolgens ook geen mechaniek is om deze op te schonen. Het beste lijkt mij om dit ontwerp om te gooien naar een aanpak waar dingen kunnen verlopen, en wellicht ook automatisch kunnen worden doorgestart indien dat gewenst is.
Er is niks dat werkt, het is wel in de programmatie van phprunner.
ziet er zo uit.
Quote:
date_default_timezone_set('Europe/Brussels');
$data = array();
$data["tijd"] < (NOW() - INTERVAL 2 HOUR) ;
DB::Delete("online", $data );
$data = array();
$data["tijd"] < (NOW() - INTERVAL 2 HOUR) ;
DB::Delete("online", $data );
hierop krijg ik steeds de fout : syntax error, unexpected '2' (T_LNUMBER) in line 4
alvast bedankt voor de vlugge reactie.
Ik neem van harte aan dat je datum wel hebt opgeslagen als een DATETIME type in je database
Gewijzigd op 11/06/2020 17:39:18 door - Ariën -
Ik weet niet precies wat DB::Delete() doet, maar ik neem aan dat de eerste parameter de tabelnaam bevat, en de tweede parameter waarschijnlijk een lijst van condities?
Dan zou ik zoiets op regel 4 verwachten, aangenomen dat de kolom in kwestie "tijd" heet:
Of wellicht simpelweg:
Maar de vraag is hoe DB::Delete() intern werkt, en hoe daarmee de uiteindelijke query eruit komt te zien.
Ik heb het nu in een query geplaatst , en inderdaad nu werkt het.
De manier in de phprunner begrijp ik ook niet goed.
Alvast velen dank voor dit alles.
PHPrunner ken ik overigens niet.
Nogmaals bedankt.
Een van de beste programma's om php te genereren, zelf kan je daar ook wijzigingen aan brengen en toeltjes bij schrijven, het is van xlinsoft in America.
De prijs is wel duur maar je krijgt er wel wat voor 499$ 1 jaar updates inbegrepen na dat jaar telkens 199$ per jaar voor updates.
Maar ben er heel tevreden van, heb momenteel een data site van meer dan 200.000 records . waarin ook een grafische kaart aan te pas komt.(enkel interessant voor geocachers )www.dcjt.be/geo_database
Heb er zelf de google authenticator in verwerkt.
Je kan er overigens niet uit afleiden of de gebruiker écht iets aan het doen is, of dat hij de pagina heeft geopend en vervolgens de hond uit is gaan laten. Alleen wanneer daadwerkelijk een pagina wordt geladen is dat een redelijk goede aanwijzing dat de gebruiker actief is. Maar met een keep-alive-signaal kun je in ieder geval zien dat de pagina nog zichtbaar is op het scherm.
Hiertoe zou je op elke pagina van je site een iframe kunnen opnemen dat een bestandje keepalive.php (of hoe je het dan ook wilt noemen) opent. Dat iframe kun je met CSS (display:none) verbergen.
In keepalive.php bepaal je aan de hand van de sessiegegevens wat het userid is en update je het record waarin wordt bijgehouden dat de gebruiker online is. Vervolgens genereer je een (optisch lege) HTML-pagina met daarin een stukje javascript. Iets als:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
# Bepaal het userid en voer vervolgens een SQL-query uit om aan te geven dat de gebruiker nog actief is:
# UPDATE heartbeats SET last_active = NOW() WHERE userid = ?
?><html><title></title><head>
<script>
function keepalive()
{
if (document.visibilityState != 'hidden') {
location.reload();
}
}
setInterval(keepalive,120000);
</script>
</head><body></body></html>
# Bepaal het userid en voer vervolgens een SQL-query uit om aan te geven dat de gebruiker nog actief is:
# UPDATE heartbeats SET last_active = NOW() WHERE userid = ?
?><html><title></title><head>
<script>
function keepalive()
{
if (document.visibilityState != 'hidden') {
location.reload();
}
}
setInterval(keepalive,120000);
</script>
</head><body></body></html>
Door de setInterval() wordt de functie keepalive() elke 2 minuten aangeroepen. Als de visibilityState van de pagina niet 'hidden' is, wordt de pagina herladen. Is de gebruiker ondertussen naar een andere tab gegaan, of heeft hij zijn browser geminimaliseerd, dan is de state wel 'hidden' en kijkt het script twee minuten later nog eens of de gebruiker weer is teruggekomen.
Als je niet wilt dat een gebruiker die is weggezapt automatisch weer online komt, zou je de setInterval() kunnen veranderen in een setTimeout(); de keepalive-functie wordt dan slechts eenmaal aangeroepen. Is de webpagina zichtbaar/actief dan wordt keepalive.php in het iframe herladen, waardoor de setTimeout opnieuw wordt ingesteld. Het enige verschil tussen setTimeout en setInterval is dus dat in het laatste geval de gebruiker weer automatisch online komt als hij teruggaat naar de browser-tab met jouw website.
In de code voor je website kun je vervolgens bepalen welke gebruikers online zijn door te kijken naar alle gebruikers waarvan de last_active-timestamp niet ouder is dan 2 minuten. Voor de zekerheid moet je misschien een minuutje extra erbij nemen.
Code (php)
1
2
3
2
3
SELECT userid, timestampdiff(minute, last_active, now()) as alive
from heartbeats
where last_active > now() - interval 10 minute
from heartbeats
where last_active > now() - interval 10 minute
Op je website kun je nu alle gebruikers met alive < 3 de status 'online' geven en iedereen met alive >= 3 de status 'recent online' of iets dergelijks.
<disclaimer>
Ik heb dit net even uit de losse pols zitten tikken dus het kan zijn dat het niet, of niet in alle situaties, perfect werkt.
</disclaimer>
Gewijzigd op 18/06/2020 23:21:51 door Willem vp