PDA

View Full Version : [php] Logout utente a sessioni terminate


Simone19
24-02-2008, 18:18
Salve utenti.

Sono nuovo di qui, scrivo questo post perche sono alla creazione di un sito-community da me programmato da zero, ora sono quasi alla sua pubbligazione on-line, manga solo uno script e finalmente dopo tante ricerche ho trovato come farlo, il logout utente quando l' utente non si trova più all' interno del mio sito, per fare ciò pero ho bisongo di fare queste tre cose:
1) settare il tempo attuale nel db associandolo all'utente
2) controllare chi è loggato
3) Se il tempo attuale, il tempo di sessione per ogni utente è maggiore ad esenoui di 3 minuti , mi include ed esegue la pagina logout.php

marko.fatto
24-02-2008, 19:11
modifica il titolo e aggiungi [PHP] all'inizio ;)

nuovoUtente86
24-02-2008, 19:32
Non si capisce bene cosa tu voglia fare: vuoi che passato un tot di tempo scada la sessione e l' utente debba riloggarsi?

Simone19
24-02-2008, 20:04
No, io vorrei che la sessione terminasse: o quando l' utente effettua il logout ( script gia fatto nel sito ) o quando l' utente non si trova più nel sito.

Io vorrei che se un utente non si trova più nel mio sito automaticamente si eseguono delle operazioni (quelle per il logout e non solo)...come fare?

nuovoUtente86
24-02-2008, 20:09
Cioè intendi un utente che per un tot prestabilito pur essendo loggato non genera attivtà

Simone19
24-02-2008, 20:17
io veramente intendevo un utente che proprio non si trova più nel sito, ma se quella e l' unica soluzione allora si, intendevo quello

nuovoUtente86
24-02-2008, 20:20
Un utente non si trova piu nel sito quando non è piu loggato.Non conosco il php,ma al pari di altri linguaggi dovrebbe consentirti di raggiungere in tuo intento attraverso la sessione

Simone19
24-02-2008, 20:25
ok, allora per quello che voglio fare io, voi dite che mi serve uno script che mi sloga un utente che rimane per un pò di tempo inattivo sul sito?

nuovoUtente86
24-02-2008, 20:42
La sessione funziona in questo modo:è valida per un tot di tempo prefissato entro il quali l' utente invia 2 richieste al server,in quanto il protocollo Http è senza stato.Se l' utente non rispetta il timeout ovvero invia 2 richieste in un tempo superiore al timeout la sua sessione scade e in caso di sito protetto dovrà ripetere il login

Simone19
24-02-2008, 20:47
ok, ma come si fa ad impostare il timeaut delle sessioni?

nuovoUtente86
24-02-2008, 20:51
session_set_cookie_params();

la funzione dovrebbe essere questa e dovrebbe accettare il tempo in secondi,ma ti ripeto non utilizzo il php per cui non so cn precisione

Simone19
24-02-2008, 20:56
session_set_cookie_params();
Questa funzione dovrebbe esistere in php...oltre alla tue risposte aspetto risposte di altri utenti che usano il php e se sapranno rispondermi a questa domanda:
che per caso questa funzione termina le sessioni alla chiusura del browser quando il tempo in segondi non viene specificato in essa?

nuovoUtente86
24-02-2008, 21:26
Quella è una funzione di php,se non la utilizzi il server prenderà come valore di default per la sessione quello impostato nel file php.ini.
Non ho ben capito la tua domanda ma cerco di interpretarla:
La sessione non è nulla di fisico ma un collegamento "astratto" che sopperisce alla mancanza dello stato nel protocollo Http.In sostanza è un numero univoco che identifica il browser:se mi presento ad un sito con una sessione o meglio un Idsession scaduto sarà aperta una nuova sessione,cosi come ne sarà aperta un' altra se non ho nel browser o sull' URL un IDsession.
Alla chiusura del browser la sessione non è piu valida per cui di fatto si entra in stato di log-out

cionci
25-02-2008, 00:37
No, la funzione per settare il timeout della sessione è session_cache_expire...questa fa scadere la sessione dopo tot minuti indipendentemente dalla durata del cookie di sessione e dalla modalità di propagazione dell'id di sessione.

cionci
25-02-2008, 00:40
Alla chiusura del browser la sessione non è piu valida per cui di fatto si entra in stato di log-out
Non è più valida perché viene eliminato il cockie di sessione, ma se io passo manualmente il session id, la sessione sul server esiste anche dopo la chiusura del browser. La scadenza della sessione è settata appunto in php.ini ed avviene dopo tot minuti di inattività (15 di default).
In php non c'è un modo "diretto" per eseguire un qualche codice alla scadenza di una sessione (purtroppo aggiungo)...

Simone19
25-02-2008, 16:33
E quindi come potro fare per far eseguire un codice quando la sessione è scaduta?...non so, magari un comando anche quando nessuno esegue lo script!

nuovoUtente86
25-02-2008, 22:50
Non è più valida perché viene eliminato il cockie di sessione, ma se io passo manualmente il session id, la sessione sul server esiste anche dopo la chiusura del browser. La scadenza della sessione è settata appunto in php.ini ed avviene dopo tot minuti di inattività (15 di default).
In php non c'è un modo "diretto" per eseguire un qualche codice alla scadenza di una sessione (purtroppo aggiungo)...

Ottima precisazione,in effetti mi ero espresso male.
Un domanda: cosi di sfuggita ho letto i valori di default per le sessioni in PHP e ho trovato spesso il valore 20 minuti e in un tutorial 24,ora tu mi dai un terzo valore 15.Varia per caso in base alla versione?

cionci
26-02-2008, 07:36
Ci sta anche che mi sbagli :D
Basta scaricare e vedere il php.ini di default ;)

Simone19: spiegami cosa vuoi fare quando la sessione è scaduta. Devi lavorare in ogni caso loggando l'ultima operazione fatta dall'utente sul database.

Simone19
26-02-2008, 15:42
Allore, nella mia tabella utente o un cambo chiamato Stato(che rapresenta lo stato dell' utente: 1 = online ; 0 = offline) di tipo decimal che ammete solo due valori 0,1 e che a come predefinito il valore 0 questo valore mi deve cambiare da 1 (quando l' utente e loggato) a 0 (quando l' utente non è più logato...tutto questo oltre a far scadere le sessione me lo deve fare quando la sessione dell' utente scade o quando viene direttamente chiuso il browser

cionci
26-02-2008, 15:59
Non è possibile fare quello che cerchi di fare, l'unico modo è tenere nel database il timestamp dell'ultima operazione fatta dall'utente ed a quel punto determini quali utenti sono online e quali non lo sono facendo una query in base alla differenza fra il timestamp attuale e quello memorizzato nell'ultima azione, che ovviamente deve essere minore o uguale del timeout della sessione di php (in realtà ci metterei qualche secondo in più per sicurezza).
E' la stessa cosa che viene fatta su questo forum per determinare la lista degli utenti online.

Simone19
26-02-2008, 17:23
Mi potresti scrivere un esempio di script che utiliza questo medoto, non è che ho capito proprio bene.

aspe, allora stai dicendo che la lista degli utenti on-line io la dovro tederminare con quel medodo no mediante il valore del campo stato ?

cionci
26-02-2008, 19:25
Te devi aggiungere un campo "Timestamp" alla tabella degli utenti e lo aggiorni con NOW() ad ogni azione fatta dall'utente.
Se vuoi determinare la lista degli utenti attualmente online devi fare la differenza fra NOW() e "Timestamp" e questa differenza deve essere inferiore al tempo di scadenza della sessione ;)

In realtà ci sarebbero altri modi, magari usando i trigger in abbinamento sempre al timestamp, però me lo dovrei studiare per bene...quello sopra è sicuramente il più semplice.

Simone19
26-02-2008, 19:39
1. L' azione con NOW deve essere presente in una pagina che si aggiorna ogni volta o ogni quanti minuti?
2. Ho gia impostato il campo Stato (mi dice se e online o no) lo aggiorno con quel campo o lo elimino proprio?
3. Hai detto che per essere non connesso l' utente devo fare la diferenza fra il NOW() e il timespam e che questo deve essere inferiore alla scadenza delle sessione, ma quanto è la scadenza delle sessioni?
4. Non ho proprio idea di come creare la query che seleziona li utenti on-line e quella
5. che cosa sono i trigger?

cionci
26-02-2008, 20:10
1. L' azione con NOW deve essere presente in una pagina che si aggiorna ogni volta o ogni quanti minuti?
2. Ho gia impostato il campo Stato (mi dice se e online o no) lo aggiorno con quel campo o lo elimino proprio?
3. Hai detto che per essere non connesso l' utente devo fare la diferenza fra il NOW() e il timespam e che questo deve essere inferiore alla scadenza delle sessione, ma quanto è la scadenza delle sessioni?
4. Non ho proprio idea di come creare la query che seleziona li utenti on-line e quella
5. che cosa sono i trigger?
1 - si aggiorna ogni volta che un utente fa un'azione, cioè ogni volta che un utente richiama una pagina php
2 - il campo stato non ti serve più, un utente è online quando la differenza fra now e l'ultima azione è minore del tempo di scadenza della sessione
3 - la scadenza è un po' complessa, dovrebbe essere il minimo fra il lifetime ottenuto da session_get_cookie_params e il valore session.cache_expires impostato in php.ini, imho ti conviene dimensionare il controllo sul valore di lifetime ritornato da session_get_cookie_params
4 - SELECT * FROM utenti WHERE timestamp < DATE_SUB(NOW(), INTERVAL XX MINUTE);
5 - http://dev.mysql.com/doc/refman/5.1/en/triggers.html

Simone19
26-02-2008, 20:32
4 - SELECT * FROM utenti WHERE timestamp < DATE_SUB(NOW(), INTERVAL XX MINUTE);

Intervallo che dichiare qui a quante minute deve essere uguale? hai minuti di scadenza della sessione o ad altro?

cionci
27-02-2008, 08:51
Ai minuti di scadenza della sessione -1 sarebbe la cosa migliore.

Simone19
27-02-2008, 10:28
1 - si aggiorna ogni volta che un utente fa un'azione, cioè ogni volta che un utente richiama una pagina php
scusa ma se un utente per esempi sta scrivendo e on-line e non sta compiento nessuna azione ( non aggiorna la pagina ) e se un untente vedi la lista on-line non quell' altro utente gli risulta off-line o no?

cionci
27-02-2008, 10:36
Se l'utente sta più di XX minuti a scrivere in quella pagina, senza fare azioni, risulta offline. Ma è normale dopo XX+1 minuti scade anche il cookie e la sessione deve essere fatta nuovamente.
Anche su questo forum, se fai in modo di non memorizzare il login, stai 15 minuti a scrivere un messaggio dopo non sei più autenticato.

Simone19
27-02-2008, 12:20
Senti, ho provato ad aggiungere il SELECT che voi mi avete dato alla pagina dove io ho la lista utenti (sia on-line che off-line) nella pagina e presente anche un sistema di navigazione e mi da errere nella query che ho appena inserito, posto qui il codice della pagina:

<table align="center" width="99%" cellpadding="1" cellspacing="1">
<tr>
<td style="border-bottom:groove #000022 1px"><sup><strong>Lista utenti</strong></sup></td>
</tr>
<tr>
<td>Qui potrete trovare una lista completa di tutti l' utenti registrati nella nostra community com la loro home page, la loro e-mail, il link per l' invio di messagi privati all' utente(PM) e il loro stato attuale ( Online ; Offline ) <br />
<table align='center' width='680' cellpadding='0' cellspacing='0'>
<tr align='center' style='background:url(img/stab.png)'>
<td width='82' style='border:solid #003366 1px'><strong>Username</strong></td>
<td width='146' style='border:solid #003366 1px'><strong>Home - page</strong></td>
<td width='132' style='border:solid #003366 1px'><strong>E - Mail</strong></td>
<td width='155' style='border:solid #003366 1px'><strong>PM</strong></td>
<td width='163' style='border:solid #003366 1px'><strong>Stato</strong></td>
</tr>
<?
$count=mysql_query("SELECT COUNT(id) FROM utente");
$res_count = mysql_fetch_row($count);
// numero totale di records
$tot_records = $res_count[0];
// risultati per pagina(secondo parametro di LIMIT)
$per_page = 10;
// numero totale di pagine
$tot_pages = ceil($tot_records / $per_page);
// pagina corrente
$current_page = (!$_GET['page']) ? 1 : (int)$_GET['page'];
// primo parametro di LIMIT
$primo = ($current_page - 1) * $per_page;

// esecuzione seconda query con LIMIT
$query_limit = mysql_query("SELECT * FROM utente LIMIT $primo, $per_page");
while($rs = mysql_fetch_array($query_limit)) {
// Controlla stato utente ( on-line ; off-line )
$controllo = mysql_query("SELECT * FROM utenti WHERE timestamp < DATE_SUB(NOW(), INTERVAL -1 MINUTE)");
if (mysql_num_rows($controllo) = 0) {
$stato = "<font corol=red>Off-line</font>" ;
}else
$stato = "<font corol=green>On-line</font>" ;
}
echo " <tr align='center'>
<td width='82' style='border:solid #003366 1px; border-top:none'>$rs[Username]</td>
<td width='146' style='border:solid #003366 1px; border-top:none'><a href='$rs[Home]' target='_blank' title='Visualiza home - page di $rs[Username]'>Visualiza home</a></td>
<td width='132' style='border:solid #003366 1px; border-top:none'><a href='mailto:$rs[Email]' title='Invia E - Mail a $rs[Username]'>Invia mail</a></td>
<td width='155' style='border:solid #003366 1px; border-top:none'><a href='index.php?Dir=msg_nuovo&destinmp=".$rs[Username]."' title='invia messagio privato a $rs[Username]'>Invia pm</a></td>
<td width='163' style='border:solid #003366 1px; border-top:none'>".$stato."</td>
</tr>" ;
}
?>
</table>
<?
$pag_tot = $tot_pages ;
if($current_page == 1) { // se siamo nella prima pagina
$precedente = "&laquo; precedente";
} else { // altrimenti
$previous_page = ($current_page - 1);
$precedente = "<a href=\"index.php?Dir=search_utente&page=$previous_page\" title=\"Pagina precedente\">&laquo; precedente</a>";
}
if($current_page == $tot_pages) { // se siamo nell'ultima pagina
$successiva = "successiva &raquo;";
} else { // altrimenti
$next_page = ($current_page + 1);
$successiva = "<a href=\"index.php?Dir=search_utente&page=$next_page\" title=\"Pagina successiva\">successiva &raquo;</a>";
}
$paginazione = "$precedente · $successiva";
?>
<br />
<table align="right" cellpadding="0" cellspacing="0" style="border:solid #003366 1px">
<tr>
<td style="border-left:solid #003366 1px; background:url(img/stab.png)">&nbsp;Pagina <?=$current_page ?> di <?=$pag_tot ?>&nbsp;</td>
<td style="border-left:solid #003366 1px">&nbsp;<?=$paginazione ?></td>
</tr>
</table>
</td>
</tr>
</table>

Quando eseguo lo script mi da questo errore:

Fatal error: Can't use function return value in write context in C:\AppServ\www\Fasterwolf\lista_utenti.php on line 34

qual' è il probblema?

cionci
27-02-2008, 12:25
Scusa, ma devi anche provarla prima la query direttamente su MySQL non è detto che funzioni così al primo colpo. Hai fatto poi le modifiche alla tabella ? Hai immesso il timestamp ?
Inoltre l'errore non è relativo a MySQL.

Simone19
27-02-2008, 12:42
Infatti solo ora lo provata, mi da errore proprio alla funzione DATE_SUB()

cionci
27-02-2008, 13:37
A me funziona, prova a cambiare il nome del campo, timestamp è riservato.
Questa mi funziona perfettamente:
SELECT * FROM prova WHERE last_action > DATE_SUB(NOW(), INTERVAL 2 MINUTE);

Simone19
27-02-2008, 16:17
A me da sempre lo stesso errore

cionci
27-02-2008, 16:36
A me da sempre lo stesso errore
Fammi vedere come imposti la tabella e come immetti i dati...

Simone19
27-02-2008, 16:43
la tabella utente a il campo last_action impostato cosi:

Campo : last_action
Tipo : timestamp
Attributo : ON UPDATE CURRENT_TIMESTAMP
Null : No
Predefinito : CURRENT_TIMESTAMP


per quando riguarda i dati, di quali dadi parli, io non ho impostato nessun dado

cionci
27-02-2008, 16:57
Attributo : ON UPDATE CURRENT_TIMESTAMP

Questo lo devresti togliere...

Quando un utente fa un'azione dovrai aggiornare la data con:

UPDATE tabella SET last_action = NOW() WHERE id_utente = XYZ;

Prova a farlo su una tabella vuota.

PS: ma su quale versione di MySQL lavori ?

Simone19
27-02-2008, 17:07
L'UPDATE che mi avete dado va, ma la SELECT per creare la lista on-line no?

cionci
27-02-2008, 17:10
Che versione di MySQL hai ?

Simone19
27-02-2008, 17:26
La versione : 5.0.45

cionci
27-02-2008, 17:37
E allora ti deve andare ad ogni costo...

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.0.45-Debian_1ubuntu3.1-log Debian etch distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use prova
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe prova;
+-------------+-----------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------+------+-----+-------------------+----------------+
| prova_id | int(11) | NO | PRI | NULL | auto_increment |
| last_action | timestamp | NO | | CURRENT_TIMESTAMP | |
+-------------+-----------+------+-----+-------------------+----------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO prova VALUES (1, NOW());
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO prova VALUES (2, NOW());
Query OK, 1 row affected (0.00 sec)

mysql> SELECT prova_id FROM prova WHERE last_action > DATE_SUB(NOW(), INTERVAL 10 MINUTE);
+----------+
| prova_id |
+----------+
| 1 |
| 2 |
+----------+
2 rows in set (0.00 sec)

mysql> SELECT prova_id FROM prova WHERE last_action > DATE_SUB(NOW(), INTERVAL 1 MINUTE);
+----------+
| prova_id |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)

mysql> select prova_id from prova where last_action > DATE_SUB(NOW(), INTERVAL 1 MINUTE);
Empty set (0.00 sec)

mysql> select prova_id from prova where last_action > DATE_SUB(NOW(), INTERVAL 10 MINUTE);
+----------+
| prova_id |
+----------+
| 1 |
| 2 |
+----------+
2 rows in set (0.00 sec)

mysql> SELECT prova_id FROM prova WHERE last_action > DATE_SUB(NOW(), INTERVAL 1 MINUTE);
Empty set (0.00 sec)

mysql>

Simone19
27-02-2008, 20:16
Come mai allora non va?

cionci
28-02-2008, 00:50
Come mai allora non va?
Più che postarti il log delle operazioni che ho fatto io non posso fare, come vedi a me funziona. L'errore nella pagina php non riguarda la query sql.

Simone19
02-03-2008, 17:59
Infatti, non è la query sql...segondo le prove che ho fatto è proprio la funzione date_sub()...ho provato a fare delle prove ma nessuna di quelle va

cionci
02-03-2008, 18:07
Ti ho dimostrato che date_sub va, come vedi dal log della sessione di mysql. Prova a fare come me, connettiti con il client testuale e prova la query.

Simone19
02-03-2008, 18:11
Non ho mai visto fino ad ora un log di mysql, quindi non so come legelo?

cionci
02-03-2008, 18:16
Se hai il server in locale:

mysql -u root -p

Inserisci:

use nomedatabase

e poi fai la query ed incolli l'output dell'errore qui..

Simone19
02-03-2008, 19:17
Non ho capito bene le prime cose che devo fare?

cionci
02-03-2008, 19:22
Hai il server mysql in locale ?
Cerca mysql.exe se sei su Windows, individua il percorso in cui si trova...
start -> esegui -> cmd -> invio

CD percorsodimysql.exe

mysql -u root -p

use nomedatabase

Simone19
02-03-2008, 19:48
Ho fatto come voi mi avete detto, fino ad ora mi a stampato a video questo:
http://fasterwolf.netsons.org/Immagine.png
Poi, che dovrei fare?

cionci
03-03-2008, 00:25
Te l'ho scritto:

use nomedatabase;

ovviamente con nomedatabase devi mettere il nome del database che contiene la tabella su cui devi fare la select.

describe nometabella;

Questo giusto per vedere com'è fatta...e poi la select con il DATE_SUB

Simone19
03-03-2008, 19:45
Quando scrivo use nomedatabase mi esche scritto
database changed
mysql>
dopo mysql scrivo describe nometabella e mi da questo
>
che devo mettere dopo?