1. OCAU Merchandise is available! Check out our 20th Anniversary Mugs, Classic Logo Shirts and much more! Discussion in this thread.
    Dismiss Notice

PHP help.

Discussion in 'Programming & Software Development' started by Tanus, Aug 13, 2002.

(追記) (追記ここまで)
  1. Tanus Member

    Joined:
    Jun 27, 2001
    Messages:
    923
    Location:
    Melbourne
    I'm having trouble getting my head around a "Who's Online" type of thing. Currently, whenever someone hits a page, I have a function that updates a table in a DB for that session ID (or installs a new record if it is a new user). What I don't know how to do is remove someone's information from this table when they leave the site.
  2. Wizardx8 Member

    Joined:
    Jan 2, 2002
    Messages:
    2,742
    Location:
    Singapore
    Hmmmmm, never done one of these but see if this works...

    Set a session when the user visits the site, and have a query check all active session, every 10 minutes or so...

    Then set it so the session expires as soon as the user exits the site, seems simple enough, though probably isn't...

    A thought though?
  3. OP
    OP
    Tanus

    Tanus Member

    Joined:
    Jun 27, 2001
    Messages:
    923
    Location:
    Melbourne
    Well, the way I was planning to do it was have the time the session was last touched (updated) stored. Each time the function is run, it checks through all the stored session infos and any that have the last touched time too long ago deleted. However, it seems to be a bit of a waste of cycles.
  4. Bangers Member

    Joined:
    Dec 25, 2001
    Messages:
    7,254
    Location:
    Silicon Valley
    If I was implementing this, I would have it have a timelimit of about 300 seconds per session ID.

    When they first come in, adds them and their timestamp. Everytime the page loads, it resets the timestamp to current time and also does a SQL update to the people with timestamp over 300s.

    I'm interested to see how vBulletin implements this. eva2000?
  5. OP
    OP
    Tanus

    Tanus Member

    Joined:
    Jun 27, 2001
    Messages:
    923
    Location:
    Melbourne
    Yeah, I guess that's the way I'll do it... there's an article HERE that uses that method too.
  6. hogwash Member

    Joined:
    Jun 27, 2001
    Messages:
    120
    Location:
    Melbourne, Australia
    Why don't you have a something simple like a text file which stores a single timestamp. Every time you query the table containing session information, check whether this timestamp has been exceeded and if it has do a remove of all redundant records. This way you won't have to scan through all records and remove them everytime. If the timestamp has been exceeded and you do an update, the simply update the timestamp in the text file to 10 minutes ahead (for example).
  7. nudge Member

    Joined:
    Sep 5, 2001
    Messages:
    860
    Location:
    Amsterdam NL
    Use PHP's inbuilt session handling system and write your own session handler for it. That way you dont need to call functions to check for stale records...php does it for you.

    I wrote a mysql handler, and a whos online page for my web page (ank site, in sig ), the whos online section is only viewable by admins though.

    If ya need help, just ask!
  8. OP
    OP
    Tanus

    Tanus Member

    Joined:
    Jun 27, 2001
    Messages:
    923
    Location:
    Melbourne
    I'm not too familiar with sessions, other than how to start it, register stuff, and get to the registered info. What exactly do you mean by a session handler that makes php automatically clear the stale records?

    EDIT : Okay, so I'm guessing that you can overide the way php handles the sessions, and that the functions to override are sess_open, sess_close, sess_read, sess_write, sess_destroy and sess_gc ?
    Last edited: Aug 14, 2002
  9. SpeedFreak Member

    Joined:
    Jun 27, 2001
    Messages:
    1,385
    Location:
    London, UK | OCAU's Euro corrispondant!
    the easiest way is just tomake the session timeout after say 5 mins, if they are still on the site the script will send another one when he goes to another page anywayz

    cheers
  10. nudge Member

    Joined:
    Sep 5, 2001
    Messages:
    860
    Location:
    Amsterdam NL
    Sorry, i didnt really explain, i was in a bit of a rush =)

    I'll attempt to explain how PHP sessions work.
    Firstly, when a new user browses to the php webpage that contains session_start(), PHP will send the browser a session cookie, which consists of a random hex string. This string is known as the session ID, and is associated with that particular user. PHP will also store the session ID on the server itself, along with any variables you have registered (with session_register()). Now everytime the user browses to a web page, that session cookie will also be sent along to the server. PHP will look up its table to see if the session ID exists, and if it does, will restore the session information stored about the user. These sessions expire when the user closes thier browser, or if the user hasnt come back in session.cookie_lifetime minutes, or if session_destroy() is called.
    ie, to set the timeout to 10 minutes:
    ini_set("session.cookie_lifetime","10");
    Any stale records will be cleaned up by PHP automatically.

    Yep, thats how you do it. Once you have written your custom functions, call session_set_save_handler() to tell PHP to use your functions. More info here: http://www.php.net/manual/en/function.session-set-save-handler.php
    The example given on the page works with flat files, but using a db table is much better =)

    Theres an introduction to session handling here:
    http://www.devshed.com/Server_Side/PHP/Sessions/page1.html
    But its pretty basic and you probably already know this.


    Heres a copy of the session handler i use:
    PHP:
    <?
    //global $MYSQL_HOSTNAME, $MYSQL_DATABASE, $MYSQL_USERNAME, $MYSQL_PASSWORD;

    $SESS_DBHOST = _MYSQL_HOSTNAME; /* database server hostname */
    $SESS_DBNAME = _MYSQL_DATABASE; /* database name */
    $SESS_DBUSER = _MYSQL_USERNAME; /* database user */
    $SESS_DBPASS = _MYSQL_PASSWORD; /* database password */

    $SESS_DBH = "";
    $SESS_LIFE = get_cfg_var("session.gc_maxlifetime");

    function
    sess_open($save_path, $session_name) {
    global
    $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;

    if (!
    $SESS_DBH = @mysql_connect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {
    trigger_error("Unable to connect to mySQL server.<br>MySQL Error: (" . mysql_errno() . ") " . mysql_error() . " <br>\n", E_USER_ERROR);
    return
    false;
    die;
    }

    if (! @
    mysql_select_db($SESS_DBNAME, $SESS_DBH)) {
    trigger_error("Unable to select database [ $SESS_DBNAME ]<br>\n", E_USER_ERROR);
    return
    false;
    die;
    }

    return
    true;
    }

    function
    sess_close() {
    return
    true;
    }

    function
    sess_read($key) {
    global
    $SESS_DBH, $SESS_LIFE;


    $qry = "DELETE FROM "._TBL_SESSIONS." WHERE expiry < " . time();
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error( "sess_read($key) [DELETE FROM]: " . mysql_error(), E_USER_ERROR);
    die();
    }


    $qry = "SELECT value FROM "._TBL_SESSIONS." WHERE sesskey = '$key' AND expiry > " . time();
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error("sess_read($key) [SELECT]: " . mysql_error(), E_USER_ERROR);
    die();
    }


    if (list(
    $value) = mysql_fetch_row($qid)) {
    //echo("<!--sess_read($key) OK -->\n");
    return $value;
    } else {
    //echo("<!--sess_read($key) FAILED -->\n");
    return false;
    }
    }

    function
    sess_write($key, $val) {
    global
    $SESS_DBH, $SESS_LIFE;


    $qry = "DELETE FROM "._TBL_SESSIONS." WHERE expiry < " . time();
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    //trigger_error( "sess_write($key, $value) [DELETE FROM]: " . mysql_error(), E_USER_ERROR);
    die();
    }



    $expiry = time() + $SESS_LIFE;
    $value = addslashes($val);
    $ipaddress = getUserIP();

    $qry = "INSERT INTO "._TBL_SESSIONS." VALUES ('$key', $expiry, '$value', '$ipaddress')";
    $qid = @mysql_query($qry, $SESS_DBH);
    //if (mysql_error()) {
    // trigger_error( "sess_write($key, $val) [INSERT INTO]: " . mysql_error(), E_USER_ERROR);
    // die();
    //}

    if (! $qid) {
    $qry = "UPDATE "._TBL_SESSIONS." SET expiry = $expiry, value = '$value', ipaddress = '$ipaddress' WHERE sesskey = '$key' AND expiry > " . time();
    $qid = mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error( "sess_write($key, $value) [UPDATE]: " . mysql_error(), E_USER_ERROR);
    die();
    }
    }

    return
    $qid;
    }

    function
    sess_destroy($key) {
    global
    $SESS_DBH;

    $qry = "DELETE FROM "._TBL_SESSIONS." WHERE expiry < " . time();
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error( "sess_destroy($key) [DELETE FROM]: " . mysql_error(), E_USER_ERROR);
    die();
    }

    $qry = "DELETE FROM "._TBL_SESSIONS." WHERE sesskey = '$key'";
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error( "sess_destroy($key) [DELETE FROM]: " . mysql_error(), E_USER_ERROR);
    die();
    }

    return
    $qid;
    }

    function
    sess_gc($maxlifetime) {
    global
    $SESS_DBH;

    $qry = "DELETE FROM "._TBL_SESSIONS." WHERE expiry < " . time();
    $qid = @mysql_query($qry, $SESS_DBH);
    if (
    mysql_error()) {
    trigger_error( "sess_gc($maxlifetime) [DELETE FROM]: " . mysql_error(), E_USER_ERROR);
    die();
    }

    return
    mysql_affected_rows($SESS_DBH);

    return
    false;
    }



    session_set_save_handler(
    "sess_open",
    "sess_close",
    "sess_read",
    "sess_write",
    "sess_destroy",
    "sess_gc");

    session_start();


    ?>
    Some of it might not make much sense cos i wrote it a while ago and slowly added stuff to it (thus is a bit messy), so yeah...but it'll give hya a good starting point.
    I include() this page into every other page that requires session handling.

    Also, debugging session handlers can be quite annoying.

Share This Page

Advertisement:
(追記) (追記ここまで)

AltStyle によって変換されたページ (->オリジナル) /